isp(4): Fix a typo in a message.
[dragonfly.git] / sys / dev / disk / isp / isp.c
CommitLineData
191d7ec1
SW
1/*-
2 * Copyright (c) 1997-2009 by Matthew Jacob
3 * All rights reserved.
984263bc 4 *
191d7ec1
SW
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
984263bc 8 *
191d7ec1
SW
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
984263bc 14 *
191d7ec1
SW
15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: src/sys/dev/isp/isp.c,v 1.168 2011/11/16 02:52:24 mjacob Exp $
28 */
29
30/*
31 * Machine and OS Independent (well, as best as possible)
32 * code for the Qlogic ISP SCSI and FC-SCSI adapters.
984263bc
MD
33 */
34
35/*
36 * Inspiration and ideas about this driver are from Erik Moe's Linux driver
37 * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
38 * ideas dredged from the Solaris driver.
39 */
40
41/*
42 * Include header file appropriate for platform we're building on.
43 */
191d7ec1 44#include <dev/disk/isp/isp_freebsd.h>
984263bc
MD
45
46/*
47 * General defines
48 */
984263bc 49#define MBOX_DELAY_COUNT 1000000 / 100
191d7ec1
SW
50#define ISP_MARK_PORTDB(a, b, c) \
51 isp_prt(isp, ISP_LOGSANCFG, \
52 "Chan %d ISP_MARK_PORTDB@LINE %d", b, __LINE__); \
53 isp_mark_portdb(a, b, c)
984263bc
MD
54
55/*
56 * Local static data
57 */
191d7ec1
SW
58static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
59static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
60static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
984263bc 61static const char sc4[] = "NVRAM";
191d7ec1
SW
62static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
63static const char lipd[] = "Chan %d LIP destroyed %d active commands";
64static const char sacq[] = "unable to acquire scratch area";
65
66static const uint8_t alpa_map[] = {
67 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
68 0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
69 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
70 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
71 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
72 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
73 0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
74 0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
75 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
76 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
77 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
78 0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
79 0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
80 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
81 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
82 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
83};
984263bc
MD
84
85/*
86 * Local function prototypes.
87 */
191d7ec1
SW
88static int isp_parse_async(ispsoftc_t *, uint16_t);
89static int isp_parse_async_fc(ispsoftc_t *, uint16_t);
90static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
91static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void
92isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
93static void isp_fastpost_complete(ispsoftc_t *, uint32_t);
94static int isp_mbox_continue(ispsoftc_t *);
95static void isp_scsi_init(ispsoftc_t *);
96static void isp_scsi_channel_init(ispsoftc_t *, int);
97static void isp_fibre_init(ispsoftc_t *);
98static void isp_fibre_init_2400(ispsoftc_t *);
99static void isp_mark_portdb(ispsoftc_t *, int, int);
100static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
101static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
102static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
103static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
104static void isp_dump_chip_portdb(ispsoftc_t *, int, int);
105static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
106static int isp_fclink_test(ispsoftc_t *, int, int);
107static int isp_pdb_sync(ispsoftc_t *, int);
108static int isp_scan_loop(ispsoftc_t *, int);
109static int isp_gid_ft_sns(ispsoftc_t *, int);
110static int isp_gid_ft_ct_passthru(ispsoftc_t *, int);
111static int isp_scan_fabric(ispsoftc_t *, int);
112static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
113static int isp_register_fc4_type(ispsoftc_t *, int);
114static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
115static uint16_t isp_nxt_handle(ispsoftc_t *, int, uint16_t);
116static void isp_fw_state(ispsoftc_t *, int);
117static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
118static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
119
120static void isp_spi_update(ispsoftc_t *, int);
121static void isp_setdfltsdparm(ispsoftc_t *);
122static void isp_setdfltfcparm(ispsoftc_t *, int);
123static int isp_read_nvram(ispsoftc_t *, int);
124static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *);
125static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
126static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
127static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
128static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
129static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
130static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
131static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
984263bc
MD
132
133/*
134 * Reset Hardware.
135 *
136 * Hit the chip over the head, download new f/w if available and set it running.
137 *
138 * Locking done elsewhere.
139 */
140
141void
191d7ec1 142isp_reset(ispsoftc_t *isp, int do_load_defaults)
984263bc
MD
143{
144 mbreg_t mbs;
191d7ec1 145 uint32_t code_org, val;
984263bc 146 int loops, i, dodnld = 1;
191d7ec1
SW
147 const char *btype = "????";
148 static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
984263bc
MD
149
150 isp->isp_state = ISP_NILSTATE;
191d7ec1
SW
151 if (isp->isp_dead) {
152 isp_shutdown(isp);
153 ISP_DISABLE_INTS(isp);
154 return;
155 }
984263bc
MD
156
157 /*
158 * Basic types (SCSI, FibreChannel and PCI or SBus)
159 * have been set in the MD code. We figure out more
160 * here. Possibly more refined types based upon PCI
161 * identification. Chip revision has been gathered.
162 *
163 * After we've fired this chip up, zero out the conf1 register
164 * for SCSI adapters and do other settings for the 2100.
165 */
166
191d7ec1
SW
167 ISP_DISABLE_INTS(isp);
168
984263bc 169 /*
191d7ec1
SW
170 * Pick an initial maxcmds value which will be used
171 * to allocate xflist pointer space. It may be changed
172 * later by the firmware.
984263bc 173 */
191d7ec1
SW
174 if (IS_24XX(isp)) {
175 isp->isp_maxcmds = 4096;
176 } else if (IS_2322(isp)) {
177 isp->isp_maxcmds = 2048;
178 } else if (IS_23XX(isp) || IS_2200(isp)) {
179 isp->isp_maxcmds = 1024;
180 } else {
181 isp->isp_maxcmds = 512;
984263bc
MD
182 }
183
191d7ec1
SW
184 /*
185 * Set up DMA for the request and response queues.
186 *
187 * We do this now so we can use the request queue
188 * for dma to load firmware from.
189 */
190 if (ISP_MBOXDMASETUP(isp) != 0) {
191 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
192 return;
193 }
984263bc
MD
194
195 /*
196 * Set up default request/response queue in-pointer/out-pointer
197 * register indices.
198 */
191d7ec1
SW
199 if (IS_24XX(isp)) {
200 isp->isp_rqstinrp = BIU2400_REQINP;
201 isp->isp_rqstoutrp = BIU2400_REQOUTP;
202 isp->isp_respinrp = BIU2400_RSPINP;
203 isp->isp_respoutrp = BIU2400_RSPOUTP;
204 } else if (IS_23XX(isp)) {
984263bc
MD
205 isp->isp_rqstinrp = BIU_REQINP;
206 isp->isp_rqstoutrp = BIU_REQOUTP;
207 isp->isp_respinrp = BIU_RSPINP;
208 isp->isp_respoutrp = BIU_RSPOUTP;
209 } else {
210 isp->isp_rqstinrp = INMAILBOX4;
211 isp->isp_rqstoutrp = OUTMAILBOX4;
212 isp->isp_respinrp = OUTMAILBOX5;
213 isp->isp_respoutrp = INMAILBOX5;
214 }
215
216 /*
217 * Put the board into PAUSE mode (so we can read the SXP registers
218 * or write FPM/FBM registers).
219 */
191d7ec1
SW
220 if (IS_24XX(isp)) {
221 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
222 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
223 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
224 } else {
225 ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
226 }
984263bc
MD
227
228 if (IS_FC(isp)) {
229 switch (isp->isp_type) {
230 case ISP_HA_FC_2100:
231 btype = "2100";
232 break;
233 case ISP_HA_FC_2200:
234 btype = "2200";
235 break;
236 case ISP_HA_FC_2300:
237 btype = "2300";
238 break;
239 case ISP_HA_FC_2312:
240 btype = "2312";
241 break;
191d7ec1
SW
242 case ISP_HA_FC_2322:
243 btype = "2322";
244 break;
245 case ISP_HA_FC_2400:
246 btype = "2422";
247 break;
248 case ISP_HA_FC_2500:
249 btype = "2532";
250 break;
984263bc
MD
251 default:
252 break;
253 }
191d7ec1
SW
254
255 if (!IS_24XX(isp)) {
256 /*
257 * While we're paused, reset the FPM module and FBM
258 * fifos.
259 */
260 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
261 ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
262 ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
263 ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
264 ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
265 }
984263bc 266 } else if (IS_1240(isp)) {
191d7ec1
SW
267 sdparam *sdp;
268
984263bc
MD
269 btype = "1240";
270 isp->isp_clock = 60;
191d7ec1 271 sdp = SDPARAM(isp, 0);
984263bc 272 sdp->isp_ultramode = 1;
191d7ec1 273 sdp = SDPARAM(isp, 1);
984263bc
MD
274 sdp->isp_ultramode = 1;
275 /*
276 * XXX: Should probably do some bus sensing.
277 */
191d7ec1
SW
278 } else if (IS_ULTRA3(isp)) {
279 sdparam *sdp = isp->isp_param;
280
281 isp->isp_clock = 100;
282
283 if (IS_10160(isp))
284 btype = "10160";
285 else if (IS_12160(isp))
286 btype = "12160";
287 else
288 btype = "<UNKLVD>";
289 sdp->isp_lvdmode = 1;
290
291 if (IS_DUALBUS(isp)) {
292 sdp++;
293 sdp->isp_lvdmode = 1;
294 }
984263bc
MD
295 } else if (IS_ULTRA2(isp)) {
296 static const char m[] = "bus %d is in %s Mode";
191d7ec1
SW
297 uint16_t l;
298 sdparam *sdp = SDPARAM(isp, 0);
984263bc
MD
299
300 isp->isp_clock = 100;
301
302 if (IS_1280(isp))
303 btype = "1280";
304 else if (IS_1080(isp))
305 btype = "1080";
984263bc
MD
306 else
307 btype = "<UNKLVD>";
308
309 l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
310 switch (l) {
311 case ISP1080_LVD_MODE:
312 sdp->isp_lvdmode = 1;
313 isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
314 break;
315 case ISP1080_HVD_MODE:
316 sdp->isp_diffmode = 1;
317 isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
318 break;
319 case ISP1080_SE_MODE:
320 sdp->isp_ultramode = 1;
321 isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
322 break;
323 default:
324 isp_prt(isp, ISP_LOGERR,
325 "unknown mode on bus %d (0x%x)", 0, l);
326 break;
327 }
328
329 if (IS_DUALBUS(isp)) {
191d7ec1 330 sdp = SDPARAM(isp, 1);
984263bc
MD
331 l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
332 l &= ISP1080_MODE_MASK;
191d7ec1 333 switch (l) {
984263bc
MD
334 case ISP1080_LVD_MODE:
335 sdp->isp_lvdmode = 1;
336 isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
337 break;
338 case ISP1080_HVD_MODE:
339 sdp->isp_diffmode = 1;
340 isp_prt(isp, ISP_LOGCONFIG,
341 m, 1, "Differential");
342 break;
343 case ISP1080_SE_MODE:
344 sdp->isp_ultramode = 1;
345 isp_prt(isp, ISP_LOGCONFIG,
346 m, 1, "Single-Ended");
347 break;
348 default:
349 isp_prt(isp, ISP_LOGERR,
350 "unknown mode on bus %d (0x%x)", 1, l);
351 break;
352 }
353 }
354 } else {
191d7ec1 355 sdparam *sdp = SDPARAM(isp, 0);
984263bc
MD
356 i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
357 switch (i) {
358 default:
359 isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
360 /* FALLTHROUGH */
361 case 1:
362 btype = "1020";
363 isp->isp_type = ISP_HA_SCSI_1020;
364 isp->isp_clock = 40;
365 break;
366 case 2:
367 /*
368 * Some 1020A chips are Ultra Capable, but don't
369 * run the clock rate up for that unless told to
370 * do so by the Ultra Capable bits being set.
371 */
372 btype = "1020A";
373 isp->isp_type = ISP_HA_SCSI_1020A;
374 isp->isp_clock = 40;
375 break;
376 case 3:
377 btype = "1040";
378 isp->isp_type = ISP_HA_SCSI_1040;
379 isp->isp_clock = 60;
380 break;
381 case 4:
382 btype = "1040A";
383 isp->isp_type = ISP_HA_SCSI_1040A;
384 isp->isp_clock = 60;
385 break;
386 case 5:
387 btype = "1040B";
388 isp->isp_type = ISP_HA_SCSI_1040B;
389 isp->isp_clock = 60;
390 break;
391 case 6:
392 btype = "1040C";
393 isp->isp_type = ISP_HA_SCSI_1040C;
394 isp->isp_clock = 60;
395 break;
396 }
397 /*
398 * Now, while we're at it, gather info about ultra
399 * and/or differential mode.
400 */
401 if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
402 isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
403 sdp->isp_diffmode = 1;
404 } else {
405 sdp->isp_diffmode = 0;
406 }
407 i = ISP_READ(isp, RISC_PSR);
408 if (isp->isp_bustype == ISP_BT_SBUS) {
409 i &= RISC_PSR_SBUS_ULTRA;
410 } else {
411 i &= RISC_PSR_PCI_ULTRA;
412 }
413 if (i != 0) {
414 isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
415 sdp->isp_ultramode = 1;
416 /*
191d7ec1 417 * If we're in Ultra Mode, we have to be 60MHz clock-
984263bc
MD
418 * even for the SBus version.
419 */
420 isp->isp_clock = 60;
421 } else {
422 sdp->isp_ultramode = 0;
423 /*
424 * Clock is known. Gronk.
425 */
426 }
427
428 /*
429 * Machine dependent clock (if set) overrides
430 * our generic determinations.
431 */
432 if (isp->isp_mdvec->dv_clock) {
433 if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
434 isp->isp_clock = isp->isp_mdvec->dv_clock;
435 }
436 }
437
438 }
439
440 /*
441 * Clear instrumentation
442 */
443 isp->isp_intcnt = isp->isp_intbogus = 0;
444
445 /*
446 * Do MD specific pre initialization
447 */
448 ISP_RESET0(isp);
449
984263bc
MD
450 /*
451 * Hit the chip over the head with hammer,
191d7ec1 452 * and give it a chance to recover.
984263bc
MD
453 */
454
455 if (IS_SCSI(isp)) {
456 ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
457 /*
458 * A slight delay...
459 */
191d7ec1 460 ISP_DELAY(100);
984263bc
MD
461
462 /*
463 * Clear data && control DMA engines.
464 */
191d7ec1
SW
465 ISP_WRITE(isp, CDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
466 ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
984263bc
MD
467
468
191d7ec1
SW
469 } else if (IS_24XX(isp)) {
470 /*
471 * Stop DMA and wait for it to stop.
472 */
473 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
474 for (val = loops = 0; loops < 30000; loops++) {
475 ISP_DELAY(10);
476 val = ISP_READ(isp, BIU2400_CSR);
477 if ((val & BIU2400_DMA_ACTIVE) == 0) {
478 break;
479 }
480 }
481 if (val & BIU2400_DMA_ACTIVE) {
482 ISP_RESET0(isp);
483 isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
484 return;
485 }
486 /*
487 * Hold it in SOFT_RESET and STOP state for 100us.
488 */
489 ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
490 ISP_DELAY(100);
491 for (loops = 0; loops < 10000; loops++) {
492 ISP_DELAY(5);
493 val = ISP_READ(isp, OUTMAILBOX0);
494 }
495 for (val = loops = 0; loops < 500000; loops ++) {
496 val = ISP_READ(isp, BIU2400_CSR);
497 if ((val & BIU2400_SOFT_RESET) == 0) {
498 break;
499 }
500 }
501 if (val & BIU2400_SOFT_RESET) {
502 ISP_RESET0(isp);
503 isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
504 return;
505 }
984263bc
MD
506 } else {
507 ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
508 /*
509 * A slight delay...
510 */
191d7ec1 511 ISP_DELAY(100);
984263bc
MD
512
513 /*
514 * Clear data && control DMA engines.
515 */
191d7ec1
SW
516 ISP_WRITE(isp, CDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
517 ISP_WRITE(isp, TDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
518 ISP_WRITE(isp, RDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
984263bc
MD
519 }
520
521 /*
522 * Wait for ISP to be ready to go...
523 */
524 loops = MBOX_DELAY_COUNT;
525 for (;;) {
526 if (IS_SCSI(isp)) {
191d7ec1 527 if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
984263bc 528 break;
191d7ec1
SW
529 }
530 } else if (IS_24XX(isp)) {
531 if (ISP_READ(isp, OUTMAILBOX0) == 0) {
532 break;
533 }
984263bc
MD
534 } else {
535 if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
536 break;
537 }
191d7ec1 538 ISP_DELAY(100);
984263bc
MD
539 if (--loops < 0) {
540 ISP_DUMPREGS(isp, "chip reset timed out");
191d7ec1 541 ISP_RESET0(isp);
984263bc
MD
542 return;
543 }
544 }
545
546 /*
547 * After we've fired this chip up, zero out the conf1 register
548 * for SCSI adapters and other settings for the 2100.
549 */
550
551 if (IS_SCSI(isp)) {
552 ISP_WRITE(isp, BIU_CONF1, 0);
191d7ec1 553 } else if (!IS_24XX(isp)) {
984263bc
MD
554 ISP_WRITE(isp, BIU2100_CSR, 0);
555 }
556
557 /*
558 * Reset RISC Processor
559 */
191d7ec1
SW
560 if (IS_24XX(isp)) {
561 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
562 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
563 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
564 } else {
565 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
566 ISP_DELAY(100);
567 ISP_WRITE(isp, BIU_SEMA, 0);
568 }
984263bc
MD
569
570 /*
191d7ec1 571 * Post-RISC Reset stuff.
984263bc 572 */
191d7ec1
SW
573 if (IS_24XX(isp)) {
574 for (val = loops = 0; loops < 5000000; loops++) {
575 ISP_DELAY(5);
576 val = ISP_READ(isp, OUTMAILBOX0);
577 if (val == 0) {
578 break;
579 }
580 }
581 if (val != 0) {
582 ISP_RESET0(isp);
583 isp_prt(isp, ISP_LOGERR, "reset didn't clear");
584 return;
585 }
586 } else if (IS_SCSI(isp)) {
587 uint16_t tmp = isp->isp_mdvec->dv_conf1;
984263bc
MD
588 /*
589 * Busted FIFO. Turn off all but burst enables.
590 */
591 if (isp->isp_type == ISP_HA_SCSI_1040A) {
592 tmp &= BIU_BURST_ENABLE;
593 }
594 ISP_SETBITS(isp, BIU_CONF1, tmp);
595 if (tmp & BIU_BURST_ENABLE) {
596 ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
597 ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
598 }
191d7ec1
SW
599 if (SDPARAM(isp, 0)->isp_ptisp) {
600 if (SDPARAM(isp, 0)->isp_ultramode) {
601 while (ISP_READ(isp, RISC_MTR) != 0x1313) {
602 ISP_WRITE(isp, RISC_MTR, 0x1313);
603 ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
604 }
605 } else {
606 ISP_WRITE(isp, RISC_MTR, 0x1212);
984263bc 607 }
191d7ec1
SW
608 /*
609 * PTI specific register
610 */
611 ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
984263bc
MD
612 } else {
613 ISP_WRITE(isp, RISC_MTR, 0x1212);
614 }
191d7ec1 615 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
984263bc
MD
616 } else {
617 ISP_WRITE(isp, RISC_MTR2100, 0x1212);
618 if (IS_2200(isp) || IS_23XX(isp)) {
619 ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
620 }
191d7ec1 621 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
984263bc
MD
622 }
623
191d7ec1
SW
624 ISP_WRITE(isp, isp->isp_rqstinrp, 0);
625 ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
626 ISP_WRITE(isp, isp->isp_respinrp, 0);
627 ISP_WRITE(isp, isp->isp_respoutrp, 0);
628 if (IS_24XX(isp)) {
629 ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
630 ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
631 ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
632 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
633 }
984263bc
MD
634
635 /*
636 * Do MD specific post initialization
637 */
638 ISP_RESET1(isp);
639
640 /*
641 * Wait for everything to finish firing up.
642 *
191d7ec1 643 * Avoid doing this on early 2312s because you can generate a PCI
984263bc
MD
644 * parity error (chip breakage).
645 */
191d7ec1
SW
646 if (IS_2312(isp) && isp->isp_revision < 2) {
647 ISP_DELAY(100);
984263bc
MD
648 } else {
649 loops = MBOX_DELAY_COUNT;
650 while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
191d7ec1 651 ISP_DELAY(100);
984263bc 652 if (--loops < 0) {
191d7ec1 653 ISP_RESET0(isp);
984263bc
MD
654 isp_prt(isp, ISP_LOGERR,
655 "MBOX_BUSY never cleared on reset");
656 return;
657 }
658 }
659 }
660
661 /*
662 * Up until this point we've done everything by just reading or
663 * setting registers. From this point on we rely on at least *some*
664 * kind of firmware running in the card.
665 */
666
667 /*
191d7ec1
SW
668 * Do some sanity checking by running a NOP command.
669 * If it succeeds, the ROM firmware is now running.
984263bc 670 */
191d7ec1 671 ISP_MEMZERO(&mbs, sizeof (mbs));
984263bc 672 mbs.param[0] = MBOX_NO_OP;
191d7ec1
SW
673 mbs.logval = MBLOGALL;
674 isp_mboxcmd(isp, &mbs);
984263bc 675 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
191d7ec1
SW
676 isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
677 ISP_RESET0(isp);
984263bc
MD
678 return;
679 }
680
191d7ec1
SW
681 /*
682 * Do some operational tests
683 */
684
685 if (IS_SCSI(isp) || IS_24XX(isp)) {
686 ISP_MEMZERO(&mbs, sizeof (mbs));
984263bc
MD
687 mbs.param[0] = MBOX_MAILBOX_REG_TEST;
688 mbs.param[1] = 0xdead;
689 mbs.param[2] = 0xbeef;
690 mbs.param[3] = 0xffff;
691 mbs.param[4] = 0x1111;
692 mbs.param[5] = 0xa5a5;
191d7ec1
SW
693 mbs.param[6] = 0x0000;
694 mbs.param[7] = 0x0000;
695 mbs.logval = MBLOGALL;
696 isp_mboxcmd(isp, &mbs);
984263bc 697 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
191d7ec1 698 ISP_RESET0(isp);
984263bc
MD
699 return;
700 }
701 if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
702 mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
703 mbs.param[5] != 0xa5a5) {
191d7ec1
SW
704 ISP_RESET0(isp);
705 isp_prt(isp, ISP_LOGERR, "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", mbs.param[1], mbs.param[2], mbs.param[3], mbs.param[4], mbs.param[5]);
984263bc
MD
706 return;
707 }
708
709 }
710
711 /*
712 * Download new Firmware, unless requested not to do so.
713 * This is made slightly trickier in some cases where the
714 * firmware of the ROM revision is newer than the revision
715 * compiled into the driver. So, where we used to compare
716 * versions of our f/w and the ROM f/w, now we just see
717 * whether we have f/w at all and whether a config flag
718 * has disabled our download.
719 */
191d7ec1 720 if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
984263bc
MD
721 dodnld = 0;
722 }
723
191d7ec1
SW
724 if (IS_24XX(isp)) {
725 code_org = ISP_CODE_ORG_2400;
726 } else if (IS_23XX(isp)) {
984263bc 727 code_org = ISP_CODE_ORG_2300;
191d7ec1 728 } else {
984263bc 729 code_org = ISP_CODE_ORG;
191d7ec1
SW
730 }
731
732 if (dodnld && IS_24XX(isp)) {
733 const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
734 int wordload;
984263bc 735
984263bc 736 /*
191d7ec1 737 * Keep loading until we run out of f/w.
984263bc 738 */
191d7ec1
SW
739 code_org = ptr[2]; /* 1st load address is our start addr */
740 wordload = 0;
741
742 for (;;) {
743 uint32_t la, wi, wl;
744
745 isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]);
746
747 wi = 0;
748 la = ptr[2];
749 wl = ptr[3];
750
751 while (wi < ptr[3]) {
752 uint32_t *cp;
753 uint32_t nw;
754
755 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2;
756 if (nw > wl) {
757 nw = wl;
758 }
759 cp = isp->isp_rquest;
760 for (i = 0; i < nw; i++) {
761 ISP_IOXPUT_32(isp, ptr[wi++], &cp[i]);
762 wl--;
763 }
764 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
765 again:
766 ISP_MEMZERO(&mbs, sizeof (mbs));
767 if (la < 0x10000 && nw < 0x10000) {
768 mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
769 mbs.param[1] = la;
770 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
771 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
772 mbs.param[4] = nw;
773 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
774 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
775 isp_prt(isp, ISP_LOGDEBUG0, "LOAD RISC RAM 2100 %u words at load address 0x%x", nw, la);
776 } else if (wordload) {
777 union {
778 const uint32_t *cp;
779 uint32_t *np;
780 } ucd;
781 ucd.cp = (const uint32_t *)cp;
782 mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED;
783 mbs.param[1] = la;
784 mbs.param[2] = (*ucd.np);
785 mbs.param[3] = (*ucd.np) >> 16;
786 mbs.param[8] = la >> 16;
787 isp->isp_mbxwrk0 = nw - 1;
788 isp->isp_mbxworkp = ucd.np+1;
789 isp->isp_mbxwrk1 = (la + 1);
790 isp->isp_mbxwrk8 = (la + 1) >> 16;
791 isp_prt(isp, ISP_LOGDEBUG0, "WRITE RAM WORD EXTENDED %u words at load address 0x%x", nw, la);
792 } else {
793 mbs.param[0] = MBOX_LOAD_RISC_RAM;
794 mbs.param[1] = la;
795 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
796 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
797 mbs.param[4] = nw >> 16;
798 mbs.param[5] = nw;
799 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
800 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
801 mbs.param[8] = la >> 16;
802 isp_prt(isp, ISP_LOGDEBUG0, "LOAD RISC RAM %u words at load address 0x%x", nw, la);
803 }
804 mbs.logval = MBLOGALL;
805 isp_mboxcmd(isp, &mbs);
806 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
807 if (mbs.param[0] == MBOX_HOST_INTERFACE_ERROR) {
808 isp_prt(isp, ISP_LOGERR, "switching to word load");
809 wordload = 1;
810 goto again;
811 }
812 isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
813 ISP_RESET0(isp);
814 return;
815 }
816 la += nw;
817 }
818
819 if (ptr[1] == 0) {
820 break;
821 }
822 ptr += ptr[3];
823 }
824 isp->isp_loaded_fw = 1;
825 } else if (dodnld && IS_23XX(isp)) {
826 const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
827 uint16_t wi, wl, segno;
828 uint32_t la;
829
830 la = code_org;
831 segno = 0;
832
833 for (;;) {
834 uint32_t nxtaddr;
835
836 isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], la);
837
838 wi = 0;
839 wl = ptr[3];
840
841 while (wi < ptr[3]) {
842 uint16_t *cp;
843 uint16_t nw;
844
845 nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
846 if (nw > wl) {
847 nw = wl;
848 }
849 if (nw > (1 << 15)) {
850 nw = 1 << 15;
851 }
852 cp = isp->isp_rquest;
853 for (i = 0; i < nw; i++) {
854 ISP_IOXPUT_16(isp, ptr[wi++], &cp[i]);
855 wl--;
856 }
857 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
858 ISP_MEMZERO(&mbs, sizeof (mbs));
859 if (la < 0x10000) {
860 mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
861 mbs.param[1] = la;
862 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
863 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
864 mbs.param[4] = nw;
865 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
866 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
867 isp_prt(isp, ISP_LOGDEBUG1, "LOAD RISC RAM 2100 %u words at load address 0x%x\n", nw, la);
868 } else {
869 mbs.param[0] = MBOX_LOAD_RISC_RAM;
870 mbs.param[1] = la;
871 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
872 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
873 mbs.param[4] = nw;
874 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
875 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
876 mbs.param[8] = la >> 16;
877 isp_prt(isp, ISP_LOGDEBUG1, "LOAD RISC RAM %u words at load address 0x%x\n", nw, la);
878 }
879 mbs.logval = MBLOGALL;
880 isp_mboxcmd(isp, &mbs);
881 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
882 isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
883 ISP_RESET0(isp);
884 return;
885 }
886 la += nw;
887 }
888
889 if (!IS_2322(isp)) {
890 break;
891 }
892
893 if (++segno == 3) {
894 break;
895 }
896
897 /*
898 * If we're a 2322, the firmware actually comes in
899 * three chunks. We loaded the first at the code_org
900 * address. The other two chunks, which follow right
901 * after each other in memory here, get loaded at
902 * addresses specfied at offset 0x9..0xB.
903 */
904
905 nxtaddr = ptr[3];
906 ptr = &ptr[nxtaddr];
907 la = ptr[5] | ((ptr[4] & 0x3f) << 16);
908 }
909 isp->isp_loaded_fw = 1;
910 } else if (dodnld) {
911 union {
912 const uint16_t *cp;
913 uint16_t *np;
914 } ucd;
915 ucd.cp = isp->isp_mdvec->dv_ispfw;
916 isp->isp_mbxworkp = &ucd.np[1];
917 isp->isp_mbxwrk0 = ucd.np[3] - 1;
918 isp->isp_mbxwrk1 = code_org + 1;
919 ISP_MEMZERO(&mbs, sizeof (mbs));
920 mbs.param[0] = MBOX_WRITE_RAM_WORD;
984263bc 921 mbs.param[1] = code_org;
191d7ec1
SW
922 mbs.param[2] = ucd.np[0];
923 mbs.logval = MBLOGNONE;
924 isp_prt(isp, ISP_LOGDEBUG1, "WRITE RAM %u words at load address 0x%x\n", ucd.np[3], code_org);
925 isp_mboxcmd(isp, &mbs);
984263bc 926 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
191d7ec1
SW
927 isp_prt(isp, ISP_LOGERR, "F/W download failed at word %d", isp->isp_mbxwrk1 - code_org);
928 ISP_RESET0(isp);
984263bc
MD
929 return;
930 }
984263bc
MD
931 } else {
932 isp->isp_loaded_fw = 0;
933 isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
934 }
935
191d7ec1
SW
936 /*
937 * If we loaded firmware, verify its checksum
938 */
939 if (isp->isp_loaded_fw) {
940 ISP_MEMZERO(&mbs, sizeof (mbs));
941 mbs.param[0] = MBOX_VERIFY_CHECKSUM;
942 if (IS_24XX(isp)) {
943 mbs.param[1] = code_org >> 16;
944 mbs.param[2] = code_org;
945 } else {
946 mbs.param[1] = code_org;
947 }
948 isp_mboxcmd(isp, &mbs);
949 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
950 isp_prt(isp, ISP_LOGERR, dcrc);
951 ISP_RESET0(isp);
952 return;
953 }
954 }
955
984263bc
MD
956 /*
957 * Now start it rolling.
958 *
959 * If we didn't actually download f/w,
960 * we still need to (re)start it.
961 */
962
963
191d7ec1
SW
964 MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 1000000);
965 if (IS_24XX(isp)) {
966 mbs.param[1] = code_org >> 16;
967 mbs.param[2] = code_org;
968 if (isp->isp_loaded_fw) {
969 mbs.param[3] = 0;
970 } else {
971 mbs.param[3] = 1;
972 }
973 if (IS_25XX(isp)) {
974 mbs.ibits |= 0x10;
975 }
976 } else if (IS_2322(isp)) {
977 mbs.param[1] = code_org;
978 if (isp->isp_loaded_fw) {
979 mbs.param[2] = 0;
980 } else {
981 mbs.param[2] = 1;
982 }
983 } else {
984 mbs.param[1] = code_org;
985 }
986 isp_mboxcmd(isp, &mbs);
987 if (IS_2322(isp) || IS_24XX(isp)) {
988 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
989 ISP_RESET0(isp);
990 return;
991 }
992 }
993
984263bc 994 /*
191d7ec1
SW
995 * Give it a chance to finish starting up.
996 * Give the 24XX more time.
984263bc 997 */
191d7ec1
SW
998 if (IS_24XX(isp)) {
999 ISP_DELAY(500000);
984263bc 1000 /*
191d7ec1 1001 * Check to see if the 24XX firmware really started.
984263bc 1002 */
191d7ec1
SW
1003 if (mbs.param[1] == 0xdead) {
1004 isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
1005 ISP_RESET0(isp);
1006 return;
1007 }
1008 } else {
1009 ISP_DELAY(250000);
1010 if (IS_SCSI(isp)) {
1011 /*
1012 * Set CLOCK RATE, but only if asked to.
1013 */
1014 if (isp->isp_clock) {
1015 mbs.param[0] = MBOX_SET_CLOCK_RATE;
1016 mbs.param[1] = isp->isp_clock;
1017 mbs.logval = MBLOGNONE;
1018 isp_mboxcmd(isp, &mbs);
1019 /* we will try not to care if this fails */
1020 }
984263bc
MD
1021 }
1022 }
1023
191d7ec1
SW
1024 /*
1025 * Ask the chip for the current firmware version.
1026 * This should prove that the new firmware is working.
1027 */
1028 MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 0);
1029 isp_mboxcmd(isp, &mbs);
984263bc 1030 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
191d7ec1 1031 ISP_RESET0(isp);
984263bc
MD
1032 return;
1033 }
1034
1035 /*
1036 * The SBus firmware that we are using apparently does not return
1037 * major, minor, micro revisions in the mailbox registers, which
1038 * is really, really, annoying.
1039 */
1040 if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
1041 if (dodnld) {
1042#ifdef ISP_TARGET_MODE
1043 isp->isp_fwrev[0] = 7;
1044 isp->isp_fwrev[1] = 55;
1045#else
1046 isp->isp_fwrev[0] = 1;
1047 isp->isp_fwrev[1] = 37;
1048#endif
1049 isp->isp_fwrev[2] = 0;
191d7ec1 1050 }
984263bc
MD
1051 } else {
1052 isp->isp_fwrev[0] = mbs.param[1];
1053 isp->isp_fwrev[1] = mbs.param[2];
1054 isp->isp_fwrev[2] = mbs.param[3];
1055 }
191d7ec1
SW
1056
1057 isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
1058 btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
984263bc
MD
1059
1060 if (IS_FC(isp)) {
1061 /*
1062 * We do not believe firmware attributes for 2100 code less
1063 * than 1.17.0, unless it's the firmware we specifically
1064 * are loading.
1065 *
191d7ec1 1066 * Note that all 22XX and later f/w is greater than 1.X.0.
984263bc 1067 */
191d7ec1 1068 if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
984263bc 1069#ifdef USE_SMALLER_2100_FIRMWARE
191d7ec1 1070 isp->isp_fwattr = ISP_FW_ATTR_SCCLUN;
984263bc 1071#else
191d7ec1 1072 isp->isp_fwattr = 0;
984263bc
MD
1073#endif
1074 } else {
191d7ec1
SW
1075 isp->isp_fwattr = mbs.param[6];
1076 isp_prt(isp, ISP_LOGDEBUG0, "Firmware Attributes = 0x%x", mbs.param[6]);
984263bc 1077 }
191d7ec1
SW
1078 } else {
1079#ifndef ISP_TARGET_MODE
1080 isp->isp_fwattr = ISP_FW_ATTR_TMODE;
1081#else
1082 isp->isp_fwattr = 0;
1083#endif
984263bc
MD
1084 }
1085
191d7ec1
SW
1086 if (!IS_24XX(isp)) {
1087 MBSINIT(&mbs, MBOX_GET_FIRMWARE_STATUS, MBLOGALL, 0);
1088 isp_mboxcmd(isp, &mbs);
1089 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1090 ISP_RESET0(isp);
1091 return;
1092 }
1093 if (isp->isp_maxcmds >= mbs.param[2]) {
1094 isp->isp_maxcmds = mbs.param[2];
1095 }
984263bc 1096 }
191d7ec1 1097 isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
984263bc
MD
1098
1099 /*
191d7ec1
SW
1100 * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
1101 * Only make this check for non-SCSI cards (I'm not sure firmware attributes
1102 * work for them).
984263bc 1103 */
191d7ec1
SW
1104 if (IS_FC(isp) && ISP_CAP_MULTI_ID(isp) == 0 && isp->isp_nchan > 1) {
1105 isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, only can enable 1 of %d channels", isp->isp_nchan);
1106 isp->isp_nchan = 1;
1107 }
1108
1109 for (i = 0; i < isp->isp_nchan; i++) {
1110 isp_fw_state(isp, i);
1111 }
1112 if (isp->isp_dead) {
1113 isp_shutdown(isp);
1114 ISP_DISABLE_INTS(isp);
984263bc
MD
1115 return;
1116 }
191d7ec1 1117
984263bc
MD
1118 isp->isp_state = ISP_RESETSTATE;
1119
1120 /*
1121 * Okay- now that we have new firmware running, we now (re)set our
1122 * notion of how many luns we support. This is somewhat tricky because
1123 * if we haven't loaded firmware, we sometimes do not have an easy way
1124 * of knowing how many luns we support.
1125 *
1126 * Expanded lun firmware gives you 32 luns for SCSI cards and
1127 * 16384 luns for Fibre Channel cards.
1128 *
1129 * It turns out that even for QLogic 2100s with ROM 1.10 and above
1130 * we do get a firmware attributes word returned in mailbox register 6.
1131 *
191d7ec1 1132 * Because the lun is in a different position in the Request Queue
984263bc
MD
1133 * Entry structure for Fibre Channel with expanded lun firmware, we
1134 * can only support one lun (lun zero) when we don't know what kind
1135 * of firmware we're running.
984263bc
MD
1136 */
1137 if (IS_SCSI(isp)) {
1138 if (dodnld) {
1139 if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
1140 isp->isp_maxluns = 32;
1141 } else {
1142 isp->isp_maxluns = 8;
1143 }
1144 } else {
1145 isp->isp_maxluns = 8;
1146 }
1147 } else {
191d7ec1 1148 if (ISP_CAP_SCCFW(isp)) {
984263bc
MD
1149 isp->isp_maxluns = 16384;
1150 } else {
1151 isp->isp_maxluns = 16;
1152 }
1153 }
191d7ec1
SW
1154
1155 /*
1156 * We get some default values established. As a side
1157 * effect, NVRAM is read here (unless overriden by
1158 * a configuration flag).
1159 */
1160 if (do_load_defaults) {
1161 if (IS_SCSI(isp)) {
1162 isp_setdfltsdparm(isp);
1163 } else {
1164 for (i = 0; i < isp->isp_nchan; i++) {
1165 isp_setdfltfcparm(isp, i);
1166 }
1167 }
1168 }
984263bc
MD
1169}
1170
1171/*
1172 * Initialize Parameters of Hardware to a known state.
1173 *
1174 * Locks are held before coming here.
1175 */
1176
1177void
191d7ec1 1178isp_init(ispsoftc_t *isp)
984263bc 1179{
984263bc 1180 if (IS_FC(isp)) {
191d7ec1
SW
1181 if (IS_24XX(isp)) {
1182 isp_fibre_init_2400(isp);
1183 } else {
1184 isp_fibre_init(isp);
1185 }
984263bc
MD
1186 } else {
1187 isp_scsi_init(isp);
1188 }
191d7ec1 1189 GET_NANOTIME(&isp->isp_init_time);
984263bc
MD
1190}
1191
1192static void
191d7ec1 1193isp_scsi_init(ispsoftc_t *isp)
984263bc
MD
1194{
1195 sdparam *sdp_chan0, *sdp_chan1;
1196 mbreg_t mbs;
1197
191d7ec1 1198 sdp_chan0 = SDPARAM(isp, 0);
984263bc
MD
1199 sdp_chan1 = sdp_chan0;
1200 if (IS_DUALBUS(isp)) {
191d7ec1 1201 sdp_chan1 = SDPARAM(isp, 1);
984263bc
MD
1202 }
1203
1204 /* First do overall per-card settings. */
1205
1206 /*
1207 * If we have fast memory timing enabled, turn it on.
1208 */
1209 if (sdp_chan0->isp_fast_mttr) {
1210 ISP_WRITE(isp, RISC_MTR, 0x1313);
1211 }
1212
1213 /*
1214 * Set Retry Delay and Count.
1215 * You set both channels at the same time.
1216 */
191d7ec1 1217 MBSINIT(&mbs, MBOX_SET_RETRY_COUNT, MBLOGALL, 0);
984263bc
MD
1218 mbs.param[1] = sdp_chan0->isp_retry_count;
1219 mbs.param[2] = sdp_chan0->isp_retry_delay;
1220 mbs.param[6] = sdp_chan1->isp_retry_count;
1221 mbs.param[7] = sdp_chan1->isp_retry_delay;
191d7ec1 1222 isp_mboxcmd(isp, &mbs);
984263bc
MD
1223 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1224 return;
1225 }
1226
1227 /*
1228 * Set ASYNC DATA SETUP time. This is very important.
1229 */
191d7ec1 1230 MBSINIT(&mbs, MBOX_SET_ASYNC_DATA_SETUP_TIME, MBLOGALL, 0);
984263bc
MD
1231 mbs.param[1] = sdp_chan0->isp_async_data_setup;
1232 mbs.param[2] = sdp_chan1->isp_async_data_setup;
191d7ec1 1233 isp_mboxcmd(isp, &mbs);
984263bc
MD
1234 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1235 return;
1236 }
1237
1238 /*
1239 * Set ACTIVE Negation State.
1240 */
191d7ec1 1241 MBSINIT(&mbs, MBOX_SET_ACT_NEG_STATE, MBLOGNONE, 0);
984263bc
MD
1242 mbs.param[1] =
1243 (sdp_chan0->isp_req_ack_active_neg << 4) |
1244 (sdp_chan0->isp_data_line_active_neg << 5);
1245 mbs.param[2] =
1246 (sdp_chan1->isp_req_ack_active_neg << 4) |
1247 (sdp_chan1->isp_data_line_active_neg << 5);
191d7ec1 1248 isp_mboxcmd(isp, &mbs);
984263bc
MD
1249 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1250 isp_prt(isp, ISP_LOGERR,
1251 "failed to set active negation state (%d,%d), (%d,%d)",
1252 sdp_chan0->isp_req_ack_active_neg,
1253 sdp_chan0->isp_data_line_active_neg,
1254 sdp_chan1->isp_req_ack_active_neg,
1255 sdp_chan1->isp_data_line_active_neg);
1256 /*
1257 * But don't return.
1258 */
1259 }
1260
1261 /*
1262 * Set the Tag Aging limit
1263 */
191d7ec1 1264 MBSINIT(&mbs, MBOX_SET_TAG_AGE_LIMIT, MBLOGALL, 0);
984263bc
MD
1265 mbs.param[1] = sdp_chan0->isp_tag_aging;
1266 mbs.param[2] = sdp_chan1->isp_tag_aging;
191d7ec1 1267 isp_mboxcmd(isp, &mbs);
984263bc
MD
1268 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1269 isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
1270 sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
1271 return;
1272 }
1273
1274 /*
1275 * Set selection timeout.
1276 */
191d7ec1 1277 MBSINIT(&mbs, MBOX_SET_SELECT_TIMEOUT, MBLOGALL, 0);
984263bc
MD
1278 mbs.param[1] = sdp_chan0->isp_selection_timeout;
1279 mbs.param[2] = sdp_chan1->isp_selection_timeout;
191d7ec1 1280 isp_mboxcmd(isp, &mbs);
984263bc
MD
1281 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1282 return;
1283 }
1284
1285 /* now do per-channel settings */
1286 isp_scsi_channel_init(isp, 0);
1287 if (IS_DUALBUS(isp))
1288 isp_scsi_channel_init(isp, 1);
1289
1290 /*
1291 * Now enable request/response queues
1292 */
1293
1294 if (IS_ULTRA2(isp) || IS_1240(isp)) {
191d7ec1 1295 MBSINIT(&mbs, MBOX_INIT_RES_QUEUE_A64, MBLOGALL, 0);
984263bc
MD
1296 mbs.param[1] = RESULT_QUEUE_LEN(isp);
1297 mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1298 mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1299 mbs.param[4] = 0;
1300 mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1301 mbs.param[7] = DMA_WD2(isp->isp_result_dma);
191d7ec1 1302 isp_mboxcmd(isp, &mbs);
984263bc
MD
1303 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1304 return;
1305 }
1306 isp->isp_residx = mbs.param[5];
1307
191d7ec1 1308 MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE_A64, MBLOGALL, 0);
984263bc
MD
1309 mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1310 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1311 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1312 mbs.param[5] = 0;
1313 mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1314 mbs.param[7] = DMA_WD2(isp->isp_result_dma);
191d7ec1 1315 isp_mboxcmd(isp, &mbs);
984263bc
MD
1316 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1317 return;
1318 }
1319 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1320 } else {
191d7ec1 1321 MBSINIT(&mbs, MBOX_INIT_RES_QUEUE, MBLOGALL, 0);
984263bc
MD
1322 mbs.param[1] = RESULT_QUEUE_LEN(isp);
1323 mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1324 mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1325 mbs.param[4] = 0;
191d7ec1 1326 isp_mboxcmd(isp, &mbs);
984263bc
MD
1327 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1328 return;
1329 }
1330 isp->isp_residx = mbs.param[5];
1331
191d7ec1 1332 MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE, MBLOGALL, 0);
984263bc
MD
1333 mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1334 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1335 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1336 mbs.param[5] = 0;
191d7ec1 1337 isp_mboxcmd(isp, &mbs);
984263bc
MD
1338 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1339 return;
1340 }
1341 isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1342 }
1343
1344 /*
191d7ec1 1345 * Turn on LVD transitions for ULTRA2 or better and other features
984263bc 1346 *
191d7ec1
SW
1347 * Now that we have 32 bit handles, don't do any fast posting
1348 * any more. For Ultra2/Ultra3 cards, we can turn on 32 bit RIO
1349 * operation or use fast posting. To be conservative, we'll only
1350 * do this for Ultra3 cards now because the other cards are so
1351 * rare for this author to find and test with.
984263bc
MD
1352 */
1353
191d7ec1 1354 MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0);
984263bc
MD
1355 if (IS_ULTRA2(isp))
1356 mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
191d7ec1
SW
1357#ifdef ISP_NO_RIO
1358 if (IS_ULTRA3(isp))
984263bc 1359 mbs.param[1] |= FW_FEATURE_FAST_POST;
191d7ec1
SW
1360#else
1361 if (IS_ULTRA3(isp))
1362 mbs.param[1] |= FW_FEATURE_RIO_32BIT;
984263bc
MD
1363#endif
1364 if (mbs.param[1] != 0) {
191d7ec1
SW
1365 uint16_t sfeat = mbs.param[1];
1366 isp_mboxcmd(isp, &mbs);
984263bc
MD
1367 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1368 isp_prt(isp, ISP_LOGINFO,
1369 "Enabled FW features (0x%x)", sfeat);
1370 }
1371 }
1372
984263bc
MD
1373 isp->isp_state = ISP_INITSTATE;
1374}
1375
1376static void
191d7ec1 1377isp_scsi_channel_init(ispsoftc_t *isp, int chan)
984263bc
MD
1378{
1379 sdparam *sdp;
1380 mbreg_t mbs;
1381 int tgt;
1382
191d7ec1 1383 sdp = SDPARAM(isp, chan);
984263bc
MD
1384
1385 /*
1386 * Set (possibly new) Initiator ID.
1387 */
191d7ec1
SW
1388 MBSINIT(&mbs, MBOX_SET_INIT_SCSI_ID, MBLOGALL, 0);
1389 mbs.param[1] = (chan << 7) | sdp->isp_initiator_id;
1390 isp_mboxcmd(isp, &mbs);
984263bc
MD
1391 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1392 return;
1393 }
191d7ec1
SW
1394 isp_prt(isp, ISP_LOGINFO, "Chan %d Initiator ID is %d",
1395 chan, sdp->isp_initiator_id);
984263bc
MD
1396
1397
1398 /*
1399 * Set current per-target parameters to an initial safe minimum.
1400 */
1401 for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1402 int lun;
191d7ec1 1403 uint16_t sdf;
984263bc
MD
1404
1405 if (sdp->isp_devparam[tgt].dev_enable == 0) {
1406 continue;
1407 }
1408#ifndef ISP_TARGET_MODE
1409 sdf = sdp->isp_devparam[tgt].goal_flags;
1410 sdf &= DPARM_SAFE_DFLT;
1411 /*
1412 * It is not quite clear when this changed over so that
1413 * we could force narrow and async for 1000/1020 cards,
1414 * but assume that this is only the case for loaded
1415 * firmware.
1416 */
1417 if (isp->isp_loaded_fw) {
1418 sdf |= DPARM_NARROW | DPARM_ASYNC;
1419 }
1420#else
1421 /*
1422 * The !$*!)$!$)* f/w uses the same index into some
1423 * internal table to decide how to respond to negotiations,
1424 * so if we've said "let's be safe" for ID X, and ID X
1425 * selects *us*, the negotiations will back to 'safe'
1426 * (as in narrow/async). What the f/w *should* do is
1427 * use the initiator id settings to decide how to respond.
1428 */
1429 sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
1430#endif
191d7ec1
SW
1431 MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGNONE, 0);
1432 mbs.param[1] = (chan << 15) | (tgt << 8);
984263bc
MD
1433 mbs.param[2] = sdf;
1434 if ((sdf & DPARM_SYNC) == 0) {
1435 mbs.param[3] = 0;
1436 } else {
1437 mbs.param[3] =
1438 (sdp->isp_devparam[tgt].goal_offset << 8) |
1439 (sdp->isp_devparam[tgt].goal_period);
1440 }
191d7ec1
SW
1441 isp_prt(isp, ISP_LOGDEBUG0, "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
1442 chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
1443 isp_mboxcmd(isp, &mbs);
984263bc
MD
1444 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1445 sdf = DPARM_SAFE_DFLT;
191d7ec1
SW
1446 MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGALL, 0);
1447 mbs.param[1] = (tgt << 8) | (chan << 15);
984263bc
MD
1448 mbs.param[2] = sdf;
1449 mbs.param[3] = 0;
191d7ec1 1450 isp_mboxcmd(isp, &mbs);
984263bc
MD
1451 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1452 continue;
1453 }
1454 }
1455
1456 /*
1457 * We don't update any information directly from the f/w
1458 * because we need to run at least one command to cause a
1459 * new state to be latched up. So, we just assume that we
1460 * converge to the values we just had set.
1461 *
1462 * Ensure that we don't believe tagged queuing is enabled yet.
1463 * It turns out that sometimes the ISP just ignores our
1464 * attempts to set parameters for devices that it hasn't
1465 * seen yet.
1466 */
1467 sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
1468 for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
191d7ec1
SW
1469 MBSINIT(&mbs, MBOX_SET_DEV_QUEUE_PARAMS, MBLOGALL, 0);
1470 mbs.param[1] = (chan << 15) | (tgt << 8) | lun;
984263bc
MD
1471 mbs.param[2] = sdp->isp_max_queue_depth;
1472 mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
191d7ec1 1473 isp_mboxcmd(isp, &mbs);
984263bc
MD
1474 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1475 break;
1476 }
1477 }
1478 }
1479 for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1480 if (sdp->isp_devparam[tgt].dev_refresh) {
191d7ec1
SW
1481 sdp->sendmarker = 1;
1482 sdp->update = 1;
984263bc
MD
1483 break;
1484 }
1485 }
1486}
1487
1488/*
1489 * Fibre Channel specific initialization.
984263bc
MD
1490 */
1491static void
191d7ec1 1492isp_fibre_init(ispsoftc_t *isp)
984263bc
MD
1493{
1494 fcparam *fcp;
1495 isp_icb_t local, *icbp = &local;
1496 mbreg_t mbs;
191d7ec1 1497 int ownloopid;
984263bc
MD
1498
1499 /*
191d7ec1 1500 * We only support one channel on non-24XX cards
984263bc 1501 */
191d7ec1
SW
1502 fcp = FCPARAM(isp, 0);
1503 if (fcp->role == ISP_ROLE_NONE) {
1504 isp->isp_state = ISP_INITSTATE;
984263bc
MD
1505 return;
1506 }
1507
191d7ec1 1508 ISP_MEMZERO(icbp, sizeof (*icbp));
984263bc 1509 icbp->icb_version = ICB_VERSION1;
191d7ec1 1510 icbp->icb_fwoptions = fcp->isp_fwoptions;
984263bc
MD
1511
1512 /*
1513 * Firmware Options are either retrieved from NVRAM or
1514 * are patched elsewhere. We check them for sanity here
1515 * and make changes based on board revision, but otherwise
1516 * let others decide policy.
1517 */
1518
1519 /*
1520 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
1521 */
191d7ec1
SW
1522 if (IS_2100(isp) && isp->isp_revision < 5) {
1523 icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS;
984263bc
MD
1524 }
1525
1526 /*
1527 * We have to use FULL LOGIN even though it resets the loop too much
1528 * because otherwise port database entries don't get updated after
1529 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
1530 */
1531 if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
191d7ec1 1532 icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN;
984263bc
MD
1533 }
1534
1535 /*
1536 * Insist on Port Database Update Async notifications
1537 */
191d7ec1 1538 icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE;
984263bc
MD
1539
1540 /*
1541 * Make sure that target role reflects into fwoptions.
1542 */
191d7ec1
SW
1543 if (fcp->role & ISP_ROLE_TARGET) {
1544 icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
984263bc 1545 } else {
191d7ec1 1546 icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
984263bc
MD
1547 }
1548
191d7ec1
SW
1549 if (fcp->role & ISP_ROLE_INITIATOR) {
1550 icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
1551 } else {
1552 icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
1553 }
1554
1555 icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
1556 if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1557 isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
984263bc
MD
1558 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1559 }
1560 icbp->icb_maxalloc = fcp->isp_maxalloc;
1561 if (icbp->icb_maxalloc < 1) {
191d7ec1 1562 isp_prt(isp, ISP_LOGERR, "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
984263bc
MD
1563 icbp->icb_maxalloc = 16;
1564 }
191d7ec1 1565 icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
984263bc 1566 if (icbp->icb_execthrottle < 1) {
191d7ec1 1567 isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
984263bc
MD
1568 icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1569 }
1570 icbp->icb_retry_delay = fcp->isp_retry_delay;
1571 icbp->icb_retry_count = fcp->isp_retry_count;
191d7ec1
SW
1572 icbp->icb_hardaddr = fcp->isp_loopid;
1573 ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
1574 if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
1575 icbp->icb_hardaddr = 0;
1576 ownloopid = 0;
1577 }
1578
1579 /*
1580 * Our life seems so much better with 2200s and later with
1581 * the latest f/w if we set Hard Address.
1582 */
1583 if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) {
1584 icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
1585 }
1586
984263bc
MD
1587 /*
1588 * Right now we just set extended options to prefer point-to-point
1589 * over loop based upon some soft config options.
191d7ec1 1590 *
984263bc
MD
1591 * NB: for the 2300, ICBOPT_EXTENDED is required.
1592 */
1593 if (IS_2200(isp) || IS_23XX(isp)) {
1594 icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1595 /*
1596 * Prefer or force Point-To-Point instead Loop?
1597 */
191d7ec1 1598 switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
984263bc
MD
1599 case ISP_CFG_NPORT:
1600 icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
1601 break;
1602 case ISP_CFG_NPORT_ONLY:
1603 icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
1604 break;
1605 case ISP_CFG_LPORT_ONLY:
1606 icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
1607 break;
1608 default:
1609 icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
1610 break;
1611 }
191d7ec1
SW
1612 if (IS_2200(isp)) {
1613 /*
1614 * We can't have Fast Posting any more- we now
1615 * have 32 bit handles.
1616 *
1617 * RIO seemed to have to much breakage.
1618 *
1619 * Just opt for safety.
1620 */
1621 icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
1622 icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1623 } else {
984263bc
MD
1624 /*
1625 * QLogic recommends that FAST Posting be turned
1626 * off for 23XX cards and instead allow the HBA
1627 * to write response queue entries and interrupt
1628 * after a delay (ZIO).
984263bc 1629 */
191d7ec1
SW
1630 icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1631 if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) == ICBXOPT_ZIO) {
1632 icbp->icb_xfwoptions |= ICBXOPT_ZIO;
1633 icbp->icb_idelaytimer = 10;
1634 }
984263bc
MD
1635 if (isp->isp_confopts & ISP_CFG_ONEGB) {
1636 icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
1637 } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1638 icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
1639 } else {
1640 icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
1641 }
191d7ec1
SW
1642 if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) {
1643 icbp->icb_zfwoptions |= ICBZOPT_50_OHM;
1644 }
984263bc
MD
1645 }
1646 }
1647
984263bc
MD
1648
1649 /*
191d7ec1 1650 * For 22XX > 2.1.26 && 23XX, set some options.
984263bc
MD
1651 */
1652 if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
191d7ec1
SW
1653 MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1654 mbs.param[1] = IFCOPT1_DISF7SWTCH|IFCOPT1_LIPASYNC|IFCOPT1_LIPF8;
984263bc
MD
1655 mbs.param[2] = 0;
1656 mbs.param[3] = 0;
191d7ec1
SW
1657 if (ISP_FW_NEWER_THAN(isp, 3, 16, 0)) {
1658 mbs.param[1] |= IFCOPT1_EQFQASYNC|IFCOPT1_CTIO_RETRY;
1659 if (fcp->role & ISP_ROLE_TARGET) {
1660 mbs.param[3] = IFCOPT3_NOPRLI;
1661 }
1662 }
1663 isp_mboxcmd(isp, &mbs);
1664 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1665 return;
1666 }
984263bc 1667 }
191d7ec1
SW
1668 icbp->icb_logintime = ICB_LOGIN_TOV;
1669 icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
984263bc 1670
191d7ec1 1671 if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
984263bc 1672 icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
191d7ec1
SW
1673 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1674 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
984263bc
MD
1675 isp_prt(isp, ISP_LOGDEBUG1,
1676 "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
191d7ec1
SW
1677 ((uint32_t) (fcp->isp_wwnn >> 32)),
1678 ((uint32_t) (fcp->isp_wwnn)),
1679 ((uint32_t) (fcp->isp_wwpn >> 32)),
1680 ((uint32_t) (fcp->isp_wwpn)));
1681 } else if (fcp->isp_wwpn) {
1682 icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
1683 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1684 isp_prt(isp, ISP_LOGDEBUG1,
1685 "Setting ICB Port 0x%08x%08x",
1686 ((uint32_t) (fcp->isp_wwpn >> 32)),
1687 ((uint32_t) (fcp->isp_wwpn)));
984263bc 1688 } else {
191d7ec1
SW
1689 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1690 return;
984263bc
MD
1691 }
1692 icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
191d7ec1
SW
1693 if (icbp->icb_rqstqlen < 1) {
1694 isp_prt(isp, ISP_LOGERR, "bad request queue length");
1695 }
984263bc 1696 icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
191d7ec1
SW
1697 if (icbp->icb_rsltqlen < 1) {
1698 isp_prt(isp, ISP_LOGERR, "bad result queue length");
1699 }
984263bc
MD
1700 icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1701 icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1702 icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1703 icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1704 icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1705 icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1706 icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1707 icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
191d7ec1
SW
1708
1709 if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1710 isp_prt(isp, ISP_LOGERR, sacq);
1711 return;
1712 }
1713 isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
984263bc
MD
1714 icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
1715
984263bc
MD
1716 isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
1717
1718 /*
1719 * Init the firmware
1720 */
191d7ec1 1721 MBSINIT(&mbs, MBOX_INIT_FIRMWARE, MBLOGALL, 30000000);
984263bc
MD
1722 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1723 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
984263bc
MD
1724 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1725 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
191d7ec1
SW
1726 mbs.logval = MBLOGALL;
1727 isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)",
1728 fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32),
1729 (uint32_t) fcp->isp_scdma);
1730 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
1731 isp_mboxcmd(isp, &mbs);
1732 FC_SCRATCH_RELEASE(isp, 0);
984263bc 1733 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
191d7ec1 1734 isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
984263bc
MD
1735 return;
1736 }
191d7ec1
SW
1737 isp->isp_reqidx = 0;
1738 isp->isp_reqodx = 0;
984263bc 1739 isp->isp_residx = 0;
984263bc
MD
1740
1741 /*
1742 * Whatever happens, we're now committed to being here.
1743 */
1744 isp->isp_state = ISP_INITSTATE;
1745}
1746
191d7ec1
SW
1747static void
1748isp_fibre_init_2400(ispsoftc_t *isp)
984263bc 1749{
191d7ec1
SW
1750 fcparam *fcp;
1751 isp_icb_2400_t local, *icbp = &local;
984263bc 1752 mbreg_t mbs;
191d7ec1 1753 int chan;
984263bc 1754
984263bc 1755 /*
191d7ec1 1756 * Check to see whether all channels have *some* kind of role
984263bc 1757 */
191d7ec1
SW
1758 for (chan = 0; chan < isp->isp_nchan; chan++) {
1759 fcp = FCPARAM(isp, chan);
1760 if (fcp->role != ISP_ROLE_NONE) {
1761 break;
1762 }
984263bc 1763 }
191d7ec1
SW
1764 if (chan == isp->isp_nchan) {
1765 isp_prt(isp, ISP_LOGDEBUG0, "all %d channels with role 'none'", chan);
1766 isp->isp_state = ISP_INITSTATE;
1767 return;
984263bc 1768 }
984263bc 1769
191d7ec1
SW
1770 /*
1771 * Start with channel 0.
1772 */
1773 fcp = FCPARAM(isp, 0);
984263bc 1774
984263bc 1775 /*
191d7ec1 1776 * Turn on LIP F8 async event (1)
984263bc 1777 */
191d7ec1
SW
1778 MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1779 mbs.param[1] = 1;
1780 isp_mboxcmd(isp, &mbs);
1781 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1782 return;
984263bc 1783 }
984263bc 1784
191d7ec1
SW
1785 ISP_MEMZERO(icbp, sizeof (*icbp));
1786 icbp->icb_fwoptions1 = fcp->isp_fwoptions;
1787 if (fcp->role & ISP_ROLE_TARGET) {
1788 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
1789 } else {
1790 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
1791 }
984263bc 1792
191d7ec1
SW
1793 if (fcp->role & ISP_ROLE_INITIATOR) {
1794 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
1795 } else {
1796 icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
984263bc 1797 }
984263bc 1798
191d7ec1
SW
1799 icbp->icb_version = ICB_VERSION1;
1800 icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
1801 if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1802 isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
1803 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1804 }
984263bc 1805
191d7ec1
SW
1806 icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
1807 if (icbp->icb_execthrottle < 1) {
1808 isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
1809 icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1810 }
1811
1812 if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
1813 /*
1814 * Get current resource count
1815 */
1816 MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
1817 mbs.obits = 0x4cf;
1818 isp_mboxcmd(isp, &mbs);
1819 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1820 return;
1821 }
1822 icbp->icb_xchgcnt = mbs.param[3];
1823 }
984263bc 1824
984263bc 1825
191d7ec1
SW
1826 icbp->icb_hardaddr = fcp->isp_loopid;
1827 if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
1828 icbp->icb_hardaddr = 0;
1829 }
984263bc
MD
1830
1831 /*
191d7ec1 1832 * Force this on.
984263bc 1833 */
191d7ec1 1834 icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
984263bc 1835
191d7ec1
SW
1836 icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
1837 switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
1838#if 0
1839 case ISP_CFG_NPORT:
984263bc 1840 /*
191d7ec1 1841 * XXX: This causes the f/w to crash.
984263bc 1842 */
191d7ec1
SW
1843 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1844 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP;
1845 break;
1846#endif
1847 case ISP_CFG_NPORT_ONLY:
1848 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1849 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
1850 break;
1851 case ISP_CFG_LPORT_ONLY:
1852 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1853 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
1854 break;
1855 default:
1856 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1857 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
1858 break;
1859 }
984263bc 1860
191d7ec1
SW
1861 /* force this on for now */
1862 icbp->icb_fwoptions2 |= ICB2400_OPT2_ZIO;
984263bc 1863
191d7ec1
SW
1864 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
1865 case ICB2400_OPT2_ZIO:
1866 case ICB2400_OPT2_ZIO1:
1867 icbp->icb_idelaytimer = 0;
1868 break;
1869 case 0:
1870 break;
1871 default:
1872 isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
1873 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
1874 break;
984263bc
MD
1875 }
1876
1877 /*
191d7ec1 1878 * We don't support FCTAPE, so clear it.
984263bc 1879 */
191d7ec1
SW
1880 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
1881
1882 icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
1883 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
1884 if (isp->isp_confopts & ISP_CFG_ONEGB) {
1885 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB;
1886 } else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1887 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB;
1888 } else if (isp->isp_confopts & ISP_CFG_FOURGB) {
1889 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB;
1890 } else {
1891 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
984263bc
MD
1892 }
1893
191d7ec1
SW
1894 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
1895 icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
984263bc 1896 }
191d7ec1
SW
1897 icbp->icb_logintime = ICB_LOGIN_TOV;
1898
1899 if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
1900 icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
1901 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1902 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1903 isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwnn >> 32)), ((uint32_t) (fcp->isp_wwnn)),
1904 ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1905 } else if (fcp->isp_wwpn) {
1906 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
1907 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1908 isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node to be same as Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
984263bc 1909 } else {
191d7ec1
SW
1910 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1911 return;
984263bc 1912 }
191d7ec1 1913 icbp->icb_retry_count = fcp->isp_retry_count;
984263bc 1914
191d7ec1
SW
1915 icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1916 if (icbp->icb_rqstqlen < 8) {
1917 isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
1918 return;
1919 }
1920 icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1921 if (icbp->icb_rsltqlen < 8) {
1922 isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
1923 icbp->icb_rsltqlen);
1924 return;
1925 }
1926 icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1927 icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1928 icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1929 icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
984263bc 1930
191d7ec1
SW
1931 icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1932 icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1933 icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1934 icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
984263bc 1935
191d7ec1
SW
1936#ifdef ISP_TARGET_MODE
1937 /* unconditionally set up the ATIO queue if we support target mode */
1938 icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
1939 if (icbp->icb_atioqlen < 8) {
1940 isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
1941 return;
1942 }
1943 icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
1944 icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
1945 icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
1946 icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
1947 isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
1948 DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
1949#endif
984263bc 1950
191d7ec1 1951 isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
984263bc 1952
191d7ec1
SW
1953 isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
1954 DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
1955 DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
1956
1957 if (isp->isp_dblev & ISP_LOGDEBUG1) {
1958 isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp), icbp);
984263bc
MD
1959 }
1960
191d7ec1
SW
1961 if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1962 isp_prt(isp, ISP_LOGERR, sacq);
1963 return;
1964 }
1965 ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
1966 isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
1967
1968 /*
1969 * Now fill in information about any additional channels
1970 */
1971 if (isp->isp_nchan > 1) {
1972 isp_icb_2400_vpinfo_t vpinfo, *vdst;
1973 vp_port_info_t pi, *pdst;
1974 size_t amt = 0;
1975 uint8_t *off;
1976
1977 vpinfo.vp_count = isp->isp_nchan - 1;
1978 vpinfo.vp_global_options = 0;
1979 off = fcp->isp_scratch;
1980 off += ICB2400_VPINFO_OFF;
1981 vdst = (isp_icb_2400_vpinfo_t *) off;
1982 isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
1983 amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
1984 for (chan = 1; chan < isp->isp_nchan; chan++) {
1985 fcparam *fcp2;
1986
1987 ISP_MEMZERO(&pi, sizeof (pi));
1988 fcp2 = FCPARAM(isp, chan);
1989 if (fcp2->role != ISP_ROLE_NONE) {
1990 pi.vp_port_options = ICB2400_VPOPT_ENABLED;
1991 if (fcp2->role & ISP_ROLE_INITIATOR) {
1992 pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
1993 }
1994 if ((fcp2->role & ISP_ROLE_TARGET) == 0) {
1995 pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
1996 }
1997 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
1998 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
984263bc 1999 }
191d7ec1
SW
2000 off = fcp->isp_scratch;
2001 off += ICB2400_VPINFO_PORT_OFF(chan);
2002 pdst = (vp_port_info_t *) off;
2003 isp_put_vp_port_info(isp, &pi, pdst);
2004 amt += ICB2400_VPOPT_WRITE_SIZE;
984263bc
MD
2005 }
2006 }
2007
984263bc 2008 /*
191d7ec1 2009 * Init the firmware
984263bc 2010 */
191d7ec1
SW
2011 MBSINIT(&mbs, 0, MBLOGALL, 30000000);
2012 if (isp->isp_nchan > 1) {
2013 mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
984263bc 2014 } else {
191d7ec1
SW
2015 mbs.param[0] = MBOX_INIT_FIRMWARE;
2016 }
2017 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2018 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2019 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2020 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2021 isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
2022 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
2023 isp_mboxcmd(isp, &mbs);
2024 FC_SCRATCH_RELEASE(isp, 0);
2025
2026 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2027 return;
2028 }
2029 isp->isp_reqidx = 0;
2030 isp->isp_reqodx = 0;
2031 isp->isp_residx = 0;
2032
2033 /*
2034 * Whatever happens, we're now committed to being here.
2035 */
2036 isp->isp_state = ISP_INITSTATE;
2037}
2038
2039static void
2040isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
2041{
2042 fcparam *fcp = FCPARAM(isp, chan);
2043 int i;
2044
2045 if (chan < 0 || chan >= isp->isp_nchan) {
2046 isp_prt(isp, ISP_LOGWARN, "isp_mark_portdb: bad channel %d", chan);
2047 return;
2048 }
2049 for (i = 0; i < MAX_FC_TARG; i++) {
2050 if (fcp->portdb[i].target_mode) {
2051 if (disposition < 0) {
2052 isp_prt(isp, ISP_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%04x port 0x%06x", chan,
2053 fcp->portdb[i].handle, fcp->portdb[i].portid);
2054 ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2055 }
2056 continue;
2057 }
2058 if (disposition == 0) {
2059 ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2060 } else {
2061 switch (fcp->portdb[i].state) {
2062 case FC_PORTDB_STATE_CHANGED:
2063 case FC_PORTDB_STATE_PENDING_VALID:
2064 case FC_PORTDB_STATE_VALID:
2065 case FC_PORTDB_STATE_PROBATIONAL:
2066 fcp->portdb[i].state = FC_PORTDB_STATE_PROBATIONAL;
2067 break;
2068 case FC_PORTDB_STATE_ZOMBIE:
2069 break;
2070 case FC_PORTDB_STATE_NIL:
2071 default:
2072 ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2073 fcp->portdb[i].state = FC_PORTDB_STATE_NIL;
2074 break;
2075 }
2076 }
2077 }
2078}
2079
2080/*
2081 * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
2082 * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
2083 */
2084static int
2085isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags, int gs)
2086{
2087 mbreg_t mbs;
2088 uint8_t q[QENTRY_LEN];
2089 isp_plogx_t *plp;
2090 fcparam *fcp;
2091 uint8_t *scp;
2092 uint32_t sst, parm1;
2093 int rval, lev;
2094 const char *msg;
2095 char buf[64];
2096
2097 if (!IS_24XX(isp)) {
2098 int action = flags & PLOGX_FLG_CMD_MASK;
2099 if (action == PLOGX_FLG_CMD_PLOGI) {
2100 return (isp_port_login(isp, handle, portid));
2101 } else if (action == PLOGX_FLG_CMD_LOGO) {
2102 return (isp_port_logout(isp, handle, portid));
2103 } else {
2104 return (MBOX_INVALID_COMMAND);
2105 }
2106 }
2107
2108 ISP_MEMZERO(q, QENTRY_LEN);
2109 plp = (isp_plogx_t *) q;
2110 plp->plogx_header.rqs_entry_count = 1;
2111 plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
2112 plp->plogx_handle = 0xffffffff;
2113 plp->plogx_nphdl = handle;
2114 plp->plogx_vphdl = chan;
2115 plp->plogx_portlo = portid;
2116 plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
2117 plp->plogx_flags = flags;
2118
2119 if (isp->isp_dblev & ISP_LOGDEBUG1) {
2120 isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
2121 }
2122
2123 if (gs == 0) {
2124 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2125 isp_prt(isp, ISP_LOGERR, sacq);
2126 return (-1);
2127 }
2128 }
2129 fcp = FCPARAM(isp, chan);
2130 scp = fcp->isp_scratch;
2131 isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
2132
2133 MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
2134 mbs.param[1] = QENTRY_LEN;
2135 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2136 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2137 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2138 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2139 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
2140 isp_mboxcmd(isp, &mbs);
2141 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2142 rval = mbs.param[0];
2143 goto out;
2144 }
2145 MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
2146 scp += QENTRY_LEN;
2147 isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
2148 if (isp->isp_dblev & ISP_LOGDEBUG1) {
2149 isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
2150 }
2151
2152 if (plp->plogx_status == PLOGX_STATUS_OK) {
2153 rval = 0;
2154 goto out;
2155 } else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
2156 isp_prt(isp, ISP_LOGWARN,
7a817ab1 2157 "status 0x%x on port login IOCB channel %d",
191d7ec1
SW
2158 plp->plogx_status, chan);
2159 rval = -1;
2160 goto out;
2161 }
2162
2163 sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
2164 parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
2165
2166 rval = -1;
2167 lev = ISP_LOGERR;
2168 msg = NULL;
2169
2170 switch (sst) {
2171 case PLOGX_IOCBERR_NOLINK:
2172 msg = "no link";
2173 break;
2174 case PLOGX_IOCBERR_NOIOCB:
2175 msg = "no IOCB buffer";
2176 break;
2177 case PLOGX_IOCBERR_NOXGHG:
2178 msg = "no Exchange Control Block";
2179 break;
2180 case PLOGX_IOCBERR_FAILED:
2181 ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
2182 msg = buf;
2183 break;
2184 case PLOGX_IOCBERR_NOFABRIC:
2185 msg = "no fabric";
984263bc 2186 break;
191d7ec1
SW
2187 case PLOGX_IOCBERR_NOTREADY:
2188 msg = "firmware not ready";
984263bc 2189 break;
191d7ec1
SW
2190 case PLOGX_IOCBERR_NOLOGIN:
2191 ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
2192 msg = buf;
2193 rval = MBOX_NOT_LOGGED_IN;
984263bc 2194 break;
191d7ec1
SW
2195 case PLOGX_IOCBERR_REJECT:
2196 ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
2197 msg = buf;
984263bc 2198 break;
191d7ec1
SW
2199 case PLOGX_IOCBERR_NOPCB:
2200 msg = "no PCB allocated";
2201 break;
2202 case PLOGX_IOCBERR_EINVAL:
2203 ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
2204 msg = buf;
2205 break;
2206 case PLOGX_IOCBERR_PORTUSED:
2207 lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2208 ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
2209 msg = buf;
2210 rval = MBOX_PORT_ID_USED | (parm1 << 16);
2211 break;
2212 case PLOGX_IOCBERR_HNDLUSED:
2213 lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2214 ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
2215 msg = buf;
2216 rval = MBOX_LOOP_ID_USED;
2217 break;
2218 case PLOGX_IOCBERR_NOHANDLE:
2219 msg = "no handle allocated";
2220 break;
2221 case PLOGX_IOCBERR_NOFLOGI:
2222 msg = "no FLOGI_ACC";
2223 break;
2224 default:
2225 ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags);
2226 msg = buf;
2227 break;
2228 }
2229 if (msg) {
2230 isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", chan, portid, handle, msg);
2231 }
2232out:
2233 if (gs == 0) {
2234 FC_SCRATCH_RELEASE(isp, chan);
2235 }
2236 return (rval);
2237}
2238
2239static int
2240isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2241{
2242 mbreg_t mbs;
2243
2244 MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000);
2245 if (ISP_CAP_2KLOGIN(isp)) {
2246 mbs.param[1] = handle;
2247 mbs.ibits = (1 << 10);
2248 } else {
2249 mbs.param[1] = handle << 8;
2250 }
2251 mbs.param[2] = portid >> 16;
2252 mbs.param[3] = portid;
2253 mbs.logval = MBLOGNONE;
2254 mbs.timeout = 500000;
2255 isp_mboxcmd(isp, &mbs);
2256
2257 switch (mbs.param[0]) {
2258 case MBOX_PORT_ID_USED:
2259 isp_prt(isp, ISP_LOGDEBUG0,
2260 "isp_port_login: portid 0x%06x already logged in as %u",
2261 portid, mbs.param[1]);
2262 return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
2263
2264 case MBOX_LOOP_ID_USED:
2265 isp_prt(isp, ISP_LOGDEBUG0,
2266 "isp_port_login: handle 0x%04x in use for port id 0x%02xXXXX",
2267 handle, mbs.param[1] & 0xff);
2268 return (MBOX_LOOP_ID_USED);
2269
2270 case MBOX_COMMAND_COMPLETE:
2271 return (0);
2272
2273 case MBOX_COMMAND_ERROR:
2274 isp_prt(isp, ISP_LOGINFO,
2275 "isp_port_login: error 0x%x in PLOGI to port 0x%06x",
2276 mbs.param[1], portid);
2277 return (MBOX_COMMAND_ERROR);
2278
2279 case MBOX_ALL_IDS_USED:
2280 isp_prt(isp, ISP_LOGINFO,
2281 "isp_port_login: all IDs used for fabric login");
2282 return (MBOX_ALL_IDS_USED);
2283
2284 default:
2285 isp_prt(isp, ISP_LOGINFO,
2286 "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x",
2287 mbs.param[0], portid, handle);
2288 return (mbs.param[0]);
2289 }
2290}
2291
2292static int
2293isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2294{
2295 mbreg_t mbs;
2296
2297 MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000);
2298 if (ISP_CAP_2KLOGIN(isp)) {
2299 mbs.param[1] = handle;
2300 mbs.ibits = (1 << 10);
2301 } else {
2302 mbs.param[1] = handle << 8;
2303 }
2304 isp_mboxcmd(isp, &mbs);
2305 return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
2306}
2307
2308static int
2309isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
2310{
2311 fcparam *fcp = FCPARAM(isp, chan);
2312 mbreg_t mbs;
2313 union {
2314 isp_pdb_21xx_t fred;
2315 isp_pdb_24xx_t bill;
2316 } un;
2317
2318 MBSINIT(&mbs, MBOX_GET_PORT_DB, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 250000);
2319 if (IS_24XX(isp)) {
2320 mbs.ibits = (1 << 9)|(1 << 10);
2321 mbs.param[1] = id;
2322 mbs.param[9] = chan;
2323 } else if (ISP_CAP_2KLOGIN(isp)) {
2324 mbs.param[1] = id;
2325 } else {
2326 mbs.param[1] = id << 8;
2327 }
2328 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2329 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2330 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2331 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2332 if (dolock) {
2333 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2334 isp_prt(isp, ISP_LOGERR, sacq);
2335 return (-1);
2336 }
2337 }
2338 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un), chan);
2339 isp_mboxcmd(isp, &mbs);
2340 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2341 if (dolock) {
2342 FC_SCRATCH_RELEASE(isp, chan);
2343 }
2344 return (mbs.param[0]);
2345 }
2346 if (IS_24XX(isp)) {
2347 isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
2348 pdb->handle = un.bill.pdb_handle;
2349 pdb->s3_role = un.bill.pdb_prli_svc3;
2350 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
2351 ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
2352 ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
2353 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2354 "Chan %d Port 0x%06x flags 0x%x curstate %x",
2355 chan, pdb->portid, un.bill.pdb_flags,
2356 un.bill.pdb_curstate);
2357 if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE ||
2358 un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
2359 mbs.param[0] = MBOX_NOT_LOGGED_IN;
2360 if (dolock) {
2361 FC_SCRATCH_RELEASE(isp, chan);
2362 }
2363 return (mbs.param[0]);
2364 }
2365 } else {
2366 isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
2367 pdb->handle = un.fred.pdb_loopid;
2368 pdb->s3_role = un.fred.pdb_prli_svc3;
2369 pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
2370 ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
2371 ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
2372 }
2373 if (dolock) {
2374 FC_SCRATCH_RELEASE(isp, chan);
2375 }
2376 return (0);
2377}
2378
2379static void
2380isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
2381{
2382 isp_pdb_t pdb;
2383 int lim, loopid;
2384
2385 if (ISP_CAP_2KLOGIN(isp)) {
2386 lim = NPH_MAX_2K;
2387 } else {
2388 lim = NPH_MAX;
2389 }
2390 for (loopid = 0; loopid != lim; loopid++) {
2391 if (isp_getpdb(isp, chan, loopid, &pdb, dolock)) {
2392 continue;
2393 }
2394 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGINFO, "Chan %d Loopid 0x%04x "
2395 "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
2396 chan, loopid, pdb.portid, pdb.portname[0], pdb.portname[1],
2397 pdb.portname[2], pdb.portname[3], pdb.portname[4],
2398 pdb.portname[5], pdb.portname[6], pdb.portname[7]);
2399 }
2400}
2401
2402static uint64_t
2403isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename)
2404{
2405 uint64_t wwn = INI_NONE;
2406 fcparam *fcp = FCPARAM(isp, chan);
2407 mbreg_t mbs;
2408
2409 if (fcp->isp_fwstate < FW_READY ||
2410 fcp->isp_loopstate < LOOP_PDB_RCVD) {
2411 return (wwn);
2412 }
2413 MBSINIT(&mbs, MBOX_GET_PORT_NAME, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 500000);
2414 if (ISP_CAP_2KLOGIN(isp)) {
2415 mbs.param[1] = loopid;
2416 mbs.ibits = (1 << 10);
2417 if (nodename) {
2418 mbs.param[10] = 1;
2419 }
2420 if (ISP_CAP_MULTI_ID(isp)) {
2421 mbs.ibits |= (1 << 9);
2422 mbs.param[9] = chan;
2423 }
2424 } else {
2425 mbs.param[1] = loopid << 8;
2426 if (nodename) {
2427 mbs.param[1] |= 1;
2428 }
2429 }
2430 isp_mboxcmd(isp, &mbs);
2431 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2432 return (wwn);
2433 }
2434 if (IS_24XX(isp)) {
2435 wwn =
2436 (((uint64_t)(mbs.param[2] >> 8)) << 56) |
2437 (((uint64_t)(mbs.param[2] & 0xff)) << 48) |
2438 (((uint64_t)(mbs.param[3] >> 8)) << 40) |
2439 (((uint64_t)(mbs.param[3] & 0xff)) << 32) |
2440 (((uint64_t)(mbs.param[6] >> 8)) << 24) |
2441 (((uint64_t)(mbs.param[6] & 0xff)) << 16) |
2442 (((uint64_t)(mbs.param[7] >> 8)) << 8) |
2443 (((uint64_t)(mbs.param[7] & 0xff)));
2444 } else {
2445 wwn =
2446 (((uint64_t)(mbs.param[2] & 0xff)) << 56) |
2447 (((uint64_t)(mbs.param[2] >> 8)) << 48) |
2448 (((uint64_t)(mbs.param[3] & 0xff)) << 40) |
2449 (((uint64_t)(mbs.param[3] >> 8)) << 32) |
2450 (((uint64_t)(mbs.param[6] & 0xff)) << 24) |
2451 (((uint64_t)(mbs.param[6] >> 8)) << 16) |
2452 (((uint64_t)(mbs.param[7] & 0xff)) << 8) |
2453 (((uint64_t)(mbs.param[7] >> 8)));
2454 }
2455 return (wwn);
2456}
2457
2458/*
2459 * Make sure we have good FC link.
2460 */
2461
2462static int
2463isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
2464{
2465 mbreg_t mbs;
2466 int count, check_for_fabric, r;
2467 uint8_t lwfs;
2468 int loopid;
2469 fcparam *fcp;
2470 fcportdb_t *lp;
2471 isp_pdb_t pdb;
2472
2473 fcp = FCPARAM(isp, chan);
2474
2475 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Entry", chan);
2476 ISP_MARK_PORTDB(isp, chan, 1);
2477
2478 /*
2479 * Wait up to N microseconds for F/W to go to a ready state.
2480 */
2481 lwfs = FW_CONFIG_WAIT;
2482 count = 0;
2483 while (count < usdelay) {
2484 uint64_t enano;
2485 uint32_t wrk;
2486 NANOTIME_T hra, hrb;
2487
2488 GET_NANOTIME(&hra);
2489 isp_fw_state(isp, chan);
2490 if (lwfs != fcp->isp_fwstate) {
2491 isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG, "Chan %d Firmware State <%s->%s>", chan, isp_fc_fw_statename((int)lwfs), isp_fc_fw_statename((int)fcp->isp_fwstate));
2492 lwfs = fcp->isp_fwstate;
2493 }
2494 if (fcp->isp_fwstate == FW_READY) {
2495 break;
2496 }
2497 GET_NANOTIME(&hrb);
2498
2499 /*
2500 * Get the elapsed time in nanoseconds.
2501 * Always guaranteed to be non-zero.
2502 */
2503 enano = NANOTIME_SUB(&hrb, &hra);
2504
2505 isp_prt(isp, ISP_LOGDEBUG1, "usec%d: 0x%lx->0x%lx enano 0x%x%08x", count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb), (uint32_t)(enano >> 32), (uint32_t)(enano));
2506
2507 /*
2508 * If the elapsed time is less than 1 millisecond,
2509 * delay a period of time up to that millisecond of
2510 * waiting.
2511 *
2512 * This peculiar code is an attempt to try and avoid
2513 * invoking uint64_t math support functions for some
2514 * platforms where linkage is a problem.
2515 */
2516 if (enano < (1000 * 1000)) {
2517 count += 1000;
2518 enano = (1000 * 1000) - enano;
2519 while (enano > (uint64_t) 4000000000U) {
2520 ISP_SLEEP(isp, 4000000);
2521 enano -= (uint64_t) 4000000000U;
2522 }
2523 wrk = enano;
2524 wrk /= 1000;
2525 ISP_SLEEP(isp, wrk);
2526 } else {
2527 while (enano > (uint64_t) 4000000000U) {
2528 count += 4000000;
2529 enano -= (uint64_t) 4000000000U;
2530 }
2531 wrk = enano;
2532 count += (wrk / 1000);
2533 }
2534 }
2535
2536
2537
2538 /*
2539 * If we haven't gone to 'ready' state, return.
2540 */
2541 if (fcp->isp_fwstate != FW_READY) {
2542 isp_prt(isp, ISP_LOGSANCFG, "%s: chan %d not at FW_READY state", __func__, chan);
2543 return (-1);
2544 }
2545
2546 /*
2547 * Get our Loop ID and Port ID.
2548 */
2549 MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
2550 if (ISP_CAP_MULTI_ID(isp)) {
2551 mbs.param[9] = chan;
2552 mbs.ibits = (1 << 9);
2553 mbs.obits = (1 << 7);
2554 }
2555 isp_mboxcmd(isp, &mbs);
2556 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2557 return (-1);
2558 }
2559
2560 if (ISP_CAP_2KLOGIN(isp)) {
2561 fcp->isp_loopid = mbs.param[1];
2562 } else {
2563 fcp->isp_loopid = mbs.param[1] & 0xff;
2564 }
2565
2566 if (IS_2100(isp)) {
2567 fcp->isp_topo = TOPO_NL_PORT;
2568 } else {
2569 int topo = (int) mbs.param[6];
2570 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
2571 topo = TOPO_PTP_STUB;
2572 }
2573 fcp->isp_topo = topo;
2574 }
2575 fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
2576
2577 if (IS_2100(isp)) {
2578 /*
2579 * Don't bother with fabric if we are using really old
2580 * 2100 firmware. It's just not worth it.
2581 */
2582 if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
2583 check_for_fabric = 1;
2584 } else {
2585 check_for_fabric = 0;
2586 }
2587 } else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT) {
2588 check_for_fabric = 1;
2589 } else {
2590 check_for_fabric = 0;
2591 }
2592
2593 /*
2594 * Check to make sure we got a valid loopid
2595 * The 24XX seems to mess this up for multiple channels.
2596 */
2597 if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT) {
2598 uint8_t alpa = fcp->isp_portid;
2599
2600 if (alpa == 0) {
2601 /* "Cannot Happen" */
2602 isp_prt(isp, ISP_LOGWARN, "Zero AL_PA for Loop Topology?");
2603 } else {
2604 int i;
2605 for (i = 0; alpa_map[i]; i++) {
2606 if (alpa_map[i] == alpa) {
2607 break;
2608 }
2609 }
2610 if (alpa_map[i] && fcp->isp_loopid != i) {
2611 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d deriving loopid %d from AL_PA map (AL_PA 0x%x) and ignoring returned value %d (AL_PA 0x%x)", chan, i, alpa_map[i], fcp->isp_loopid, alpa);
2612 fcp->isp_loopid = i;
2613 }
2614 }
2615 }
2616
2617
2618 if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE FOR 2K F/W? XXX */
2619 loopid = NPH_FL_ID;
2620 } else {
2621 loopid = FL_ID;
2622 }
2623 if (check_for_fabric) {
2624 r = isp_getpdb(isp, chan, loopid, &pdb, 1);
2625 if (r && (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT)) {
2626 isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot get info about fabric controller (0x%x)", r);
2627 fcp->isp_topo = TOPO_PTP_STUB;
2628 }
2629 } else {
2630 r = -1;
2631 }
2632 if (r == 0) {
2633 if (IS_2100(isp)) {
2634 fcp->isp_topo = TOPO_FL_PORT;
2635 }
2636 if (pdb.portid == 0) {
2637 /*
2638 * Crock.
2639 */
2640 fcp->isp_topo = TOPO_NL_PORT;
2641 goto not_on_fabric;
2642 }
2643
2644 /*
2645 * Save the Fabric controller's port database entry.
2646 */
2647 lp = &fcp->portdb[FL_ID];
2648 lp->state = FC_PORTDB_STATE_PENDING_VALID;
2649 MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename);
2650 MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname);
2651 lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2652 lp->portid = pdb.portid;
2653 lp->handle = pdb.handle;
2654 lp->new_portid = lp->portid;
2655 lp->new_roles = lp->roles;
2656 if (IS_24XX(isp)) {
2657 fcp->inorder = (mbs.param[7] & ISP24XX_INORDER) != 0;
2658 if (ISP_FW_NEWER_THAN(isp, 4, 0, 27)) {
2659 fcp->npiv_fabric = (mbs.param[7] & ISP24XX_NPIV_SAN) != 0;
2660 if (fcp->npiv_fabric) {
2661 isp_prt(isp, ISP_LOGCONFIG, "fabric supports NP-IV");
2662 }
2663 }
2664 if (chan) {
2665 fcp->isp_sns_hdl = NPH_SNS_HDLBASE + chan;
2666 r = isp_plogx(isp, chan, fcp->isp_sns_hdl, SNS_PORT_ID, PLOGX_FLG_CMD_PLOGI | PLOGX_FLG_COND_PLOGI | PLOGX_FLG_SKIP_PRLI, 0);
2667 if (r) {
2668 isp_prt(isp, ISP_LOGWARN, "%s: Chan %d cannot log into SNS", __func__, chan);
2669 return (-1);
2670 }
2671 } else {
2672 fcp->isp_sns_hdl = NPH_SNS_ID;
2673 }
2674 r = isp_register_fc4_type_24xx(isp, chan);
2675 } else {
2676 fcp->isp_sns_hdl = SNS_ID;
2677 r = isp_register_fc4_type(isp, chan);
2678 }
2679 if (r) {
2680 isp_prt(isp, ISP_LOGWARN|ISP_LOGSANCFG, "%s: register fc4 type failed", __func__);
2681 return (-1);
2682 }
2683 } else {
2684not_on_fabric:
2685 fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL;
2686 }
2687
2688 fcp->isp_gbspeed = 1;
2689 if (IS_23XX(isp) || IS_24XX(isp)) {
2690 MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
2691 mbs.param[1] = MBGSD_GET_RATE;
2692 /* mbs.param[2] undefined if we're just getting rate */
2693 isp_mboxcmd(isp, &mbs);
2694 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2695 if (mbs.param[1] == MBGSD_EIGHTGB) {
2696 isp_prt(isp, ISP_LOGINFO, "Chan %d 8Gb link speed", chan);
2697 fcp->isp_gbspeed = 8;
2698 } else if (mbs.param[1] == MBGSD_FOURGB) {
2699 isp_prt(isp, ISP_LOGINFO, "Chan %d 4Gb link speed", chan);
2700 fcp->isp_gbspeed = 4;
2701 } else if (mbs.param[1] == MBGSD_TWOGB) {
2702 isp_prt(isp, ISP_LOGINFO, "Chan %d 2Gb link speed", chan);
2703 fcp->isp_gbspeed = 2;
2704 } else if (mbs.param[1] == MBGSD_ONEGB) {
2705 isp_prt(isp, ISP_LOGINFO, "Chan %d 1Gb link speed", chan);
2706 fcp->isp_gbspeed = 1;
2707 }
2708 }
2709 }
2710
2711 /*
2712 * Announce ourselves, too.
2713 */
2714 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, chan, (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) fcp->isp_wwpn, fcp->isp_portid, fcp->isp_loopid, isp_fc_toponame(fcp));
2715 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Complete", chan);
2716 return (0);
2717}
2718
2719/*
2720 * Complete the synchronization of our Port Database.
2721 *
2722 * At this point, we've scanned the local loop (if any) and the fabric
2723 * and performed fabric logins on all new devices.
2724 *
2725 * Our task here is to go through our port database and remove any entities
2726 * that are still marked probational (issuing PLOGO for ones which we had
2727 * PLOGI'd into) or are dead.
2728 *
2729 * Our task here is to also check policy to decide whether devices which
2730 * have *changed* in some way should still be kept active. For example,
2731 * if a device has just changed PortID, we can either elect to treat it
2732 * as an old device or as a newly arrived device (and notify the outer
2733 * layer appropriately).
2734 *
2735 * We also do initiator map target id assignment here for new initiator
2736 * devices and refresh old ones ot make sure that they point to the corret
2737 * entities.
2738 */
2739static int
2740isp_pdb_sync(ispsoftc_t *isp, int chan)
2741{
2742 fcparam *fcp = FCPARAM(isp, chan);
2743 fcportdb_t *lp;
2744 uint16_t dbidx;
2745
2746 if (fcp->isp_loopstate == LOOP_READY) {
2747 return (0);
2748 }
2749
2750 /*
2751 * Make sure we're okay for doing this right now.
2752 */
2753 if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
2754 fcp->isp_loopstate != LOOP_FSCAN_DONE &&
2755 fcp->isp_loopstate != LOOP_LSCAN_DONE) {
2756 isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
2757 fcp->isp_loopstate);
2758 return (-1);
2759 }
2760
2761 if (fcp->isp_topo == TOPO_FL_PORT ||
2762 fcp->isp_topo == TOPO_NL_PORT ||
2763 fcp->isp_topo == TOPO_N_PORT) {
2764 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
2765 if (isp_scan_loop(isp, chan) != 0) {
2766 isp_prt(isp, ISP_LOGWARN,
2767 "isp_pdb_sync: isp_scan_loop failed");
2768 return (-1);
2769 }
2770 }
2771 }
2772
2773 if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
2774 if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
2775 if (isp_scan_fabric(isp, chan) != 0) {
2776 isp_prt(isp, ISP_LOGWARN,
2777 "isp_pdb_sync: isp_scan_fabric failed");
2778 return (-1);
2779 }
2780 }
2781 }
2782
2783 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2784 "Chan %d Synchronizing PDBs", chan);
2785
2786 fcp->isp_loopstate = LOOP_SYNCING_PDB;
2787
2788 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2789 lp = &fcp->portdb[dbidx];
2790
2791 if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
2792 continue;
2793 }
2794
2795 if (lp->state == FC_PORTDB_STATE_VALID) {
2796 if (dbidx != FL_ID) {
2797 isp_prt(isp,
2798 ISP_LOGERR, "portdb idx %d already valid",
2799 dbidx);
2800 }
2801 continue;
2802 }
2803
2804 switch (lp->state) {
2805 case FC_PORTDB_STATE_PROBATIONAL:
2806 case FC_PORTDB_STATE_DEAD:
2807 /*
2808 * It's up to the outer layers to clear isp_dev_map.
2809 */
2810 lp->state = FC_PORTDB_STATE_NIL;
2811 isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
2812 if (lp->autologin == 0) {
2813 (void) isp_plogx(isp, chan, lp->handle,
2814 lp->portid,
2815 PLOGX_FLG_CMD_LOGO |
2816 PLOGX_FLG_IMPLICIT |
2817 PLOGX_FLG_FREE_NPHDL, 0);
2818 } else {
2819 lp->autologin = 0;
2820 }
2821 lp->new_roles = 0;
2822 lp->new_portid = 0;
2823 /*
2824 * Note that we might come out of this with our state
2825 * set to FC_PORTDB_STATE_ZOMBIE.
2826 */
2827 break;
2828 case FC_PORTDB_STATE_NEW:
2829 /*
2830 * It's up to the outer layers to assign a virtual
2831 * target id in isp_dev_map (if any).
2832 */
2833 lp->portid = lp->new_portid;
2834 lp->roles = lp->new_roles;
2835 lp->state = FC_PORTDB_STATE_VALID;
2836 isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
2837 lp->new_roles = 0;
2838 lp->new_portid = 0;
2839 lp->reserved = 0;
2840 lp->new_reserved = 0;
2841 break;
2842 case FC_PORTDB_STATE_CHANGED:
2843/*
2844 * XXXX FIX THIS
2845 */
2846 lp->state = FC_PORTDB_STATE_VALID;
2847 isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
2848 lp->new_roles = 0;
2849 lp->new_portid = 0;
2850 lp->reserved = 0;
2851 lp->new_reserved = 0;
2852 break;
2853 case FC_PORTDB_STATE_PENDING_VALID:
2854 lp->portid = lp->new_portid;
2855 lp->roles = lp->new_roles;
2856 if (lp->dev_map_idx) {
2857 int t = lp->dev_map_idx - 1;
2858 fcp->isp_dev_map[t] = dbidx + 1;
2859 }
2860 lp->state = FC_PORTDB_STATE_VALID;
2861 isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
2862 if (dbidx != FL_ID) {
2863 lp->new_roles = 0;
2864 lp->new_portid = 0;
2865 }
2866 lp->reserved = 0;
2867 lp->new_reserved = 0;
2868 break;
2869 case FC_PORTDB_STATE_ZOMBIE:
2870 break;
2871 default:
2872 isp_prt(isp, ISP_LOGWARN,
2873 "isp_scan_loop: state %d for idx %d",
2874 lp->state, dbidx);
2875 isp_dump_portdb(isp, chan);
2876 }
984263bc 2877 }
984263bc 2878
191d7ec1
SW
2879 /*
2880 * If we get here, we've for sure seen not only a valid loop
2881 * but know what is or isn't on it, so mark this for usage
2882 * in isp_start.
2883 */
2884 fcp->loop_seen_once = 1;
2885 fcp->isp_loopstate = LOOP_READY;
2886 return (0);
984263bc
MD
2887}
2888
2889/*
191d7ec1 2890 * Scan local loop for devices.
984263bc 2891 */
984263bc 2892static int
191d7ec1 2893isp_scan_loop(ispsoftc_t *isp, int chan)
984263bc 2894{
191d7ec1
SW
2895 fcportdb_t *lp, tmp;
2896 fcparam *fcp = FCPARAM(isp, chan);
2897 int i;
984263bc 2898 isp_pdb_t pdb;
191d7ec1 2899 uint16_t handle, lim = 0;
984263bc 2900
191d7ec1
SW
2901 if (fcp->isp_fwstate < FW_READY ||
2902 fcp->isp_loopstate < LOOP_PDB_RCVD) {
984263bc
MD
2903 return (-1);
2904 }
2905
191d7ec1 2906 if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) {
984263bc
MD
2907 return (0);
2908 }
2909
2910 /*
191d7ec1
SW
2911 * Check our connection topology.
2912 *
2913 * If we're a public or private loop, we scan 0..125 as handle values.
2914 * The firmware has (typically) peformed a PLOGI for us. We skip this
2915 * step if we're a ISP_24XX in NP-IV mode.
2916 *
2917 * If we're a N-port connection, we treat this is a short loop (0..1).
984263bc 2918 */
191d7ec1
SW
2919 switch (fcp->isp_topo) {
2920 case TOPO_NL_PORT:
2921 lim = LOCAL_LOOP_LIM;
2922 break;
2923 case TOPO_FL_PORT:
2924 if (IS_24XX(isp) && isp->isp_nchan > 1) {
2925 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2926 "Chan %d Skipping Local Loop Scan", chan);
2927 fcp->isp_loopstate = LOOP_LSCAN_DONE;
2928 return (0);
984263bc 2929 }
191d7ec1
SW
2930 lim = LOCAL_LOOP_LIM;
2931 break;
2932 case TOPO_N_PORT:
2933 lim = 2;
2934 break;
2935 default:
2936 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2937 "Chan %d no loop topology to scan", chan);
2938 fcp->isp_loopstate = LOOP_LSCAN_DONE;
2939 return (0);
984263bc
MD
2940 }
2941
191d7ec1
SW
2942 fcp->isp_loopstate = LOOP_SCANNING_LOOP;
2943
2944 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2945 "Chan %d FC scan loop 0..%d", chan, lim-1);
984263bc 2946
984263bc
MD
2947
2948 /*
191d7ec1 2949 * Run through the list and get the port database info for each one.
984263bc 2950 */
191d7ec1
SW
2951 for (handle = 0; handle < lim; handle++) {
2952 int r;
2953 /*
2954 * Don't scan "special" ids.
2955 */
2956 if (handle >= FL_ID && handle <= SNS_ID) {
984263bc
MD
2957 continue;
2958 }
191d7ec1
SW
2959 if (ISP_CAP_2KLOGIN(isp)) {
2960 if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
2961 continue;
2962 }
2963 }
984263bc 2964 /*
191d7ec1
SW
2965 * In older cards with older f/w GET_PORT_DATABASE has been
2966 * known to hang. This trick gets around that problem.
984263bc 2967 */
191d7ec1
SW
2968 if (IS_2100(isp) || IS_2200(isp)) {
2969 uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
2970 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2971 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2972 "Chan %d FC scan loop DONE (bad)", chan);
2973 return (-1);
2974 }
2975 if (node_wwn == INI_NONE) {
2976 continue;
2977 }
984263bc
MD
2978 }
2979
2980 /*
191d7ec1 2981 * Get the port database entity for this index.
984263bc 2982 */
191d7ec1
SW
2983 r = isp_getpdb(isp, chan, handle, &pdb, 1);
2984 if (r != 0) {
2985 isp_prt(isp, ISP_LOGDEBUG1,
2986 "Chan %d FC scan loop handle %d returned %x",
2987 chan, handle, r);
2988 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2989 ISP_MARK_PORTDB(isp, chan, 1);
2990 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2991 "Chan %d FC scan loop DONE (bad)", chan);
2992 return (-1);
2993 }
984263bc
MD
2994 continue;
2995 }
2996
191d7ec1
SW
2997 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2998 ISP_MARK_PORTDB(isp, chan, 1);
2999 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3000 "Chan %d FC scan loop DONE (bad)", chan);
3001 return (-1);
3002 }
984263bc
MD
3003
3004 /*
191d7ec1
SW
3005 * On *very* old 2100 firmware we would end up sometimes
3006 * with the firmware returning the port database entry
3007 * for something else. We used to restart this, but
3008 * now we just punt.
984263bc 3009 */
191d7ec1
SW
3010 if (IS_2100(isp) && pdb.handle != handle) {
3011 isp_prt(isp, ISP_LOGWARN,
3012 "Chan %d cannot synchronize port database", chan);
3013 ISP_MARK_PORTDB(isp, chan, 1);
3014 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3015 "Chan %d FC scan loop DONE (bad)", chan);
984263bc
MD
3016 return (-1);
3017 }
3018
3019 /*
191d7ec1 3020 * Save the pertinent info locally.
984263bc 3021 */
191d7ec1
SW
3022 MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename);
3023 MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname);
3024 tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3025 tmp.portid = pdb.portid;
3026 tmp.handle = pdb.handle;
3027
3028 /*
3029 * Check to make sure it's still a valid entry. The 24XX seems
3030 * to return a portid but not a WWPN/WWNN or role for devices
3031 * which shift on a loop.
3032 */
3033 if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
3034 int a, b, c;
3035 a = (tmp.node_wwn == 0);
3036 b = (tmp.port_wwn == 0);
3037 c = (tmp.portid == 0);
3038 if (a == 0 && b == 0) {
3039 tmp.node_wwn =
3040 isp_get_wwn(isp, chan, handle, 1);
3041 tmp.port_wwn =
3042 isp_get_wwn(isp, chan, handle, 0);
3043 if (tmp.node_wwn && tmp.port_wwn) {
3044 isp_prt(isp, ISP_LOGINFO, "DODGED!");
3045 goto cont;
3046 }
984263bc 3047 }
191d7ec1
SW
3048 isp_prt(isp, ISP_LOGWARN,
3049 "Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
3050 a, b, c, handle);
3051 isp_dump_portdb(isp, chan);
3052 continue;
984263bc 3053 }
191d7ec1 3054 cont:
984263bc
MD
3055
3056 /*
191d7ec1
SW
3057 * Now search the entire port database
3058 * for the same Port and Node WWN.
984263bc 3059 */
191d7ec1
SW
3060 for (i = 0; i < MAX_FC_TARG; i++) {
3061 lp = &fcp->portdb[i];
3062
3063 if (lp->state == FC_PORTDB_STATE_NIL ||
3064 lp->target_mode) {
3065 continue;
3066 }
3067 if (lp->node_wwn != tmp.node_wwn) {
3068 continue;
3069 }
3070 if (lp->port_wwn != tmp.port_wwn) {
3071 continue;
3072 }
3073
3074 /*
3075 * Okay- we've found a non-nil entry that matches.
3076 * Check to make sure it's probational or a zombie.
3077 */
3078 if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
3079 lp->state != FC_PORTDB_STATE_ZOMBIE) {
3080 isp_prt(isp, ISP_LOGERR,
3081 "Chan %d [%d] not probational/zombie (0x%x)",
3082 chan, i, lp->state);
3083 isp_dump_portdb(isp, chan);
3084 ISP_MARK_PORTDB(isp, chan, 1);
3085 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3086 "Chan %d FC scan loop DONE (bad)", chan);
984263bc
MD
3087 return (-1);
3088 }
191d7ec1
SW
3089
3090 /*
3091 * Mark the device as something the f/w logs into
3092 * automatically.
3093 */
3094 lp->autologin = 1;
3095
3096 /*
3097 * Check to make see if really still the same
3098 * device. If it is, we mark it pending valid.
3099 */
3100 if (lp->portid == tmp.portid &&
3101 lp->handle == tmp.handle &&
3102 lp->roles == tmp.roles) {
3103 lp->new_portid = tmp.portid;
3104 lp->new_roles = tmp.roles;
3105 lp->state = FC_PORTDB_STATE_PENDING_VALID;
3106 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3107 "Chan %d Loop Port 0x%06x@0x%04x Pending "
3108 "Valid", chan, tmp.portid, tmp.handle);
984263bc
MD
3109 break;
3110 }
984263bc 3111
191d7ec1
SW
3112 /*
3113 * We can wipe out the old handle value
3114 * here because it's no longer valid.
3115 */
3116 lp->handle = tmp.handle;
984263bc 3117
191d7ec1
SW
3118 /*
3119 * Claim that this has changed and let somebody else
3120 * decide what to do.
3121 */
3122 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3123 "Chan %d Loop Port 0x%06x@0x%04x changed",
3124 chan, tmp.portid, tmp.handle);
3125 lp->state = FC_PORTDB_STATE_CHANGED;
3126 lp->new_portid = tmp.portid;
3127 lp->new_roles = tmp.roles;
3128 break;
984263bc
MD
3129 }
3130
3131 /*
191d7ec1 3132 * Did we find and update an old entry?
984263bc 3133 */
191d7ec1
SW
3134 if (i < MAX_FC_TARG) {
3135 continue;
984263bc
MD
3136 }
3137
984263bc 3138 /*
191d7ec1
SW
3139 * Ah. A new device entry. Find an empty slot
3140 * for it and save info for later disposition.
984263bc 3141 */
191d7ec1
SW
3142 for (i = 0; i < MAX_FC_TARG; i++) {
3143 if (fcp->portdb[i].target_mode) {
3144 continue;
3145 }
3146 if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
3147 break;
3148 }
3149 }
3150 if (i == MAX_FC_TARG) {
3151 isp_prt(isp, ISP_LOGERR,
3152 "Chan %d out of portdb entries", chan);
984263bc
MD
3153 continue;
3154 }
191d7ec1
SW
3155 lp = &fcp->portdb[i];
3156
3157 ISP_MEMZERO(lp, sizeof (fcportdb_t));
3158 lp->autologin = 1;
3159 lp->state = FC_PORTDB_STATE_NEW;
3160 lp->new_portid = tmp.portid;
3161 lp->new_roles = tmp.roles;
3162 lp->handle = tmp.handle;
3163 lp->port_wwn = tmp.port_wwn;
3164 lp->node_wwn = tmp.node_wwn;
3165 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3166 "Chan %d Loop Port 0x%06x@0x%04x is New Entry",
3167 chan, tmp.portid, tmp.handle);
3168 }
3169 fcp->isp_loopstate = LOOP_LSCAN_DONE;
3170 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3171 "Chan %d FC scan loop DONE", chan);
3172 return (0);
3173}
3174
3175/*
3176 * Scan the fabric for devices and add them to our port database.
3177 *
3178 * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
3179 *
3180 * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
3181 * name server commands to the switch management server via the QLogic f/w.
3182 *
3183 * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
3184 * mailbox command.
3185 *
3186 * The net result is to leave the list of Port IDs setting untranslated in
3187 * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
3188 * host order at OGPOFF.
3189 */
3190
3191/*
3192 * Take less than half of our scratch area to store Port IDs
3193 */
3194#define GIDLEN ((ISP_FC_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
3195#define NGENT ((GIDLEN - 16) >> 2)
3196
3197#define IGPOFF (2 * QENTRY_LEN)
3198#define OGPOFF (ISP_FC_SCRLEN >> 1)
3199#define ZTXOFF (ISP_FC_SCRLEN - (1 * QENTRY_LEN))
3200#define CTXOFF (ISP_FC_SCRLEN - (2 * QENTRY_LEN))
3201#define XTXOFF (ISP_FC_SCRLEN - (3 * QENTRY_LEN))
3202
3203static int
3204isp_gid_ft_sns(ispsoftc_t *isp, int chan)
3205{
3206 union {
3207 sns_gid_ft_req_t _x;
3208 uint8_t _y[SNS_GID_FT_REQ_SIZE];
3209 } un;
3210 fcparam *fcp = FCPARAM(isp, chan);
3211 sns_gid_ft_req_t *rq = &un._x;
3212 mbreg_t mbs;
3213
3214 isp_prt(isp, ISP_LOGDEBUG0,
3215 "Chan %d scanning fabric (GID_FT) via SNS", chan);
3216
3217 ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
3218 rq->snscb_rblen = GIDLEN >> 1;
3219 rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
3220 rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
3221 rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
3222 rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
3223 rq->snscb_sblen = 6;
3224 rq->snscb_cmd = SNS_GID_FT;
3225 rq->snscb_mword_div_2 = NGENT;
3226 rq->snscb_fc4_type = FC4_SCSI;
3227
3228 isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
3229 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE, chan);
3230
3231 MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
3232 mbs.param[0] = MBOX_SEND_SNS;
3233 mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
3234 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
3235 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
3236 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
3237 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
3238 isp_mboxcmd(isp, &mbs);
3239 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3240 if (mbs.param[0] == MBOX_INVALID_COMMAND) {
3241 return (1);
3242 } else {
984263bc
MD
3243 return (-1);
3244 }
3245 }
191d7ec1
SW
3246 return (0);
3247}
3248
3249static int
3250isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
3251{
3252 mbreg_t mbs;
3253 fcparam *fcp = FCPARAM(isp, chan);
3254 union {
3255 isp_ct_pt_t plocal;
3256 ct_hdr_t clocal;
3257 uint8_t q[QENTRY_LEN];
3258 } un;
3259 isp_ct_pt_t *pt;
3260 ct_hdr_t *ct;
3261 uint32_t *rp;
3262 uint8_t *scp = fcp->isp_scratch;
3263
3264 isp_prt(isp, ISP_LOGDEBUG0,
3265 "Chan %d scanning fabric (GID_FT) via CT", chan);
3266
3267 if (!IS_24XX(isp)) {
3268 return (1);
3269 }
3270
984263bc 3271 /*
191d7ec1 3272 * Build a Passthrough IOCB in memory.
984263bc 3273 */
191d7ec1
SW
3274 pt = &un.plocal;
3275 ISP_MEMZERO(un.q, QENTRY_LEN);
3276 pt->ctp_header.rqs_entry_count = 1;
3277 pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
3278 pt->ctp_handle = 0xffffffff;
3279 pt->ctp_nphdl = fcp->isp_sns_hdl;
3280 pt->ctp_cmd_cnt = 1;
3281 pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
3282 pt->ctp_time = 30;
3283 pt->ctp_rsp_cnt = 1;
3284 pt->ctp_rsp_bcnt = GIDLEN;
3285 pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
3286 pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
3287 pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
3288 pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
3289 pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
3290 pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
3291 pt->ctp_dataseg[1].ds_count = GIDLEN;
3292 if (isp->isp_dblev & ISP_LOGDEBUG1) {
3293 isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
3294 }
3295 isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
3296
3297 /*
3298 * Build the CT header and command in memory.
3299 *
3300 * Note that the CT header has to end up as Big Endian format in memory.
3301 */
3302 ct = &un.clocal;
3303 ISP_MEMZERO(ct, sizeof (*ct));
3304 ct->ct_revision = CT_REVISION;
3305 ct->ct_fcs_type = CT_FC_TYPE_FC;
3306 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
3307 ct->ct_cmd_resp = SNS_GID_FT;
3308 ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
3309
3310 isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
3311 rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
3312 ISP_IOZPUT_32(isp, FC4_SCSI, rp);
3313 if (isp->isp_dblev & ISP_LOGDEBUG1) {
3314 isp_print_bytes(isp, "CT HDR + payload after put",
3315 sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
3316 }
3317 ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
3318 MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
3319 mbs.param[1] = QENTRY_LEN;
3320 mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
3321 mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
3322 mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
3323 mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
3324 MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
3325 isp_mboxcmd(isp, &mbs);
3326 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3327 return (-1);
3328 }
3329 MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
3330 pt = &un.plocal;
3331 isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
3332 if (isp->isp_dblev & ISP_LOGDEBUG1) {
3333 isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
3334 }
3335
3336 if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
3337 isp_prt(isp, ISP_LOGWARN,
3338 "Chan %d ISP GID FT CT Passthrough returned 0x%x",
3339 chan, pt->ctp_status);
3340 return (-1);
3341 }
3342 MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16, chan);
3343 if (isp->isp_dblev & ISP_LOGDEBUG1) {
3344 isp_print_bytes(isp, "CT response", GIDLEN+16, &scp[IGPOFF]);
3345 }
984263bc
MD
3346 return (0);
3347}
3348
3349static int
191d7ec1 3350isp_scan_fabric(ispsoftc_t *isp, int chan)
984263bc 3351{
191d7ec1
SW
3352 fcparam *fcp = FCPARAM(isp, chan);
3353 uint32_t portid;
3354 uint16_t handle, oldhandle, loopid;
984263bc 3355 isp_pdb_t pdb;
191d7ec1
SW
3356 int portidx, portlim, r;
3357 sns_gid_ft_rsp_t *rs0, *rs1;
984263bc 3358
191d7ec1
SW
3359 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3360 "Chan %d FC Scan Fabric", chan);
3361 if (fcp->isp_fwstate != FW_READY ||
3362 fcp->isp_loopstate < LOOP_LSCAN_DONE) {
3363 return (-1);
3364 }
3365 if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) {
3366 return (0);
3367 }
3368 if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) {
3369 fcp->isp_loopstate = LOOP_FSCAN_DONE;
3370 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3371 "Chan %d FC Scan Fabric Done (no fabric)", chan);
3372 return (0);
3373 }
3374
3375 fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
3376 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3377 isp_prt(isp, ISP_LOGERR, sacq);
3378 ISP_MARK_PORTDB(isp, chan, 1);
3379 return (-1);
3380 }
3381 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3382 FC_SCRATCH_RELEASE(isp, chan);
3383 ISP_MARK_PORTDB(isp, chan, 1);
3384 return (-1);
3385 }
3386
3387 /*
3388 * Make sure we still are logged into the fabric controller.
3389 */
3390 if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE TRUE FOR 2K F/W? XXX */
3391 loopid = NPH_FL_ID;
3392 } else {
3393 loopid = FL_ID;
3394 }
3395 r = isp_getpdb(isp, chan, loopid, &pdb, 0);
3396 if (r == MBOX_NOT_LOGGED_IN) {
3397 isp_dump_chip_portdb(isp, chan, 0);
3398 }
3399 if (r) {
3400 fcp->isp_loopstate = LOOP_PDB_RCVD;
3401 FC_SCRATCH_RELEASE(isp, chan);
3402 ISP_MARK_PORTDB(isp, chan, 1);
3403 return (-1);
3404 }
3405
3406 if (IS_24XX(isp)) {
3407 r = isp_gid_ft_ct_passthru(isp, chan);
3408 } else {
3409 r = isp_gid_ft_sns(isp, chan);
3410 }
3411
3412 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3413 FC_SCRATCH_RELEASE(isp, chan);
3414 ISP_MARK_PORTDB(isp, chan, 1);
3415 return (-1);
3416 }
3417
3418 if (r > 0) {
3419 fcp->isp_loopstate = LOOP_FSCAN_DONE;
3420 FC_SCRATCH_RELEASE(isp, chan);
3421 return (0);
3422 } else if (r < 0) {
3423 fcp->isp_loopstate = LOOP_PDB_RCVD; /* try again */
3424 FC_SCRATCH_RELEASE(isp, chan);
3425 return (0);
3426 }
3427
3428 MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN, chan);
3429 rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
3430 rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
3431 isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
3432 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3433 FC_SCRATCH_RELEASE(isp, chan);
3434 ISP_MARK_PORTDB(isp, chan, 1);
3435 return (-1);
3436 }
3437 if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
3438 int level;
3439 if (rs1->snscb_cthdr.ct_reason == 9 &&
3440 rs1->snscb_cthdr.ct_explanation == 7) {
3441 level = ISP_LOGSANCFG|ISP_LOGDEBUG0;
3442 } else {
3443 level = ISP_LOGWARN;
3444 }
3445 isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
3446 " (Reason=0x%x Expl=0x%x)", chan,
3447 rs1->snscb_cthdr.ct_reason,
3448 rs1->snscb_cthdr.ct_explanation);
3449 FC_SCRATCH_RELEASE(isp, chan);
3450 fcp->isp_loopstate = LOOP_FSCAN_DONE;
984263bc
MD
3451 return (0);
3452 }
191d7ec1 3453
984263bc
MD
3454
3455 /*
191d7ec1 3456 * If we get this far, we certainly still have the fabric controller.
984263bc 3457 */
191d7ec1 3458 fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
984263bc
MD
3459
3460 /*
191d7ec1 3461 * Prime the handle we will start using.
984263bc 3462 */
191d7ec1 3463 oldhandle = FCPARAM(isp, 0)->isp_lasthdl;
984263bc 3464
191d7ec1
SW
3465 /*
3466 * Go through the list and remove duplicate port ids.
3467 */
984263bc 3468
191d7ec1
SW
3469 portlim = 0;
3470 portidx = 0;
3471 for (portidx = 0; portidx < NGENT-1; portidx++) {
3472 if (rs1->snscb_ports[portidx].control & 0x80) {
3473 break;
984263bc 3474 }
191d7ec1 3475 }
984263bc 3476
191d7ec1
SW
3477 /*
3478 * If we're not at the last entry, our list wasn't big enough.
3479 */
3480 if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
3481 isp_prt(isp, ISP_LOGWARN,
3482 "fabric too big for scratch area: increase ISP_FC_SCRLEN");
3483 }
3484 portlim = portidx + 1;
3485 isp_prt(isp, ISP_LOGSANCFG,
3486 "Chan %d got %d ports back from name server", chan, portlim);
984263bc 3487
191d7ec1
SW
3488 for (portidx = 0; portidx < portlim; portidx++) {
3489 int npidx;
3490
3491 portid =
3492 ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3493 ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3494 ((rs1->snscb_ports[portidx].portid[2]));
3495
3496 for (npidx = portidx + 1; npidx < portlim; npidx++) {
3497 uint32_t new_portid =
3498 ((rs1->snscb_ports[npidx].portid[0]) << 16) |
3499 ((rs1->snscb_ports[npidx].portid[1]) << 8) |
3500 ((rs1->snscb_ports[npidx].portid[2]));
3501 if (new_portid == portid) {
3502 break;
984263bc 3503 }
984263bc
MD
3504 }
3505
191d7ec1
SW
3506 if (npidx < portlim) {
3507 rs1->snscb_ports[npidx].portid[0] = 0;
3508 rs1->snscb_ports[npidx].portid[1] = 0;
3509 rs1->snscb_ports[npidx].portid[2] = 0;
3510 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3511 "Chan %d removing duplicate PortID 0x%06x"
3512 " entry from list", chan, portid);
984263bc 3513 }
984263bc
MD
3514 }
3515
3516 /*
191d7ec1
SW
3517 * We now have a list of Port IDs for all FC4 SCSI devices
3518 * that the Fabric Name server knows about.
3519 *
3520 * For each entry on this list go through our port database looking
3521 * for probational entries- if we find one, then an old entry is
3522 * maybe still this one. We get some information to find out.
3523 *
3524 * Otherwise, it's a new fabric device, and we log into it
3525 * (unconditionally). After searching the entire database
3526 * again to make sure that we never ever ever ever have more
3527 * than one entry that has the same PortID or the same
3528 * WWNN/WWPN duple, we enter the device into our database.
984263bc 3529 */
984263bc 3530
191d7ec1
SW
3531 for (portidx = 0; portidx < portlim; portidx++) {
3532 fcportdb_t *lp;
3533 uint64_t wwnn, wwpn;
3534 int dbidx, nr;
984263bc 3535
191d7ec1
SW
3536 portid =
3537 ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3538 ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3539 ((rs1->snscb_ports[portidx].portid[2]));
3540
3541 if (portid == 0) {
3542 isp_prt(isp, ISP_LOGSANCFG,
3543 "Chan %d skipping null PortID at idx %d",
3544 chan, portidx);
984263bc
MD
3545 continue;
3546 }
3547
3548 /*
191d7ec1
SW
3549 * Skip ourselves here and on other channels. If we're
3550 * multi-id, we can't check the portids in other FCPARAM
3551 * arenas because the resolutions here aren't synchronized.
3552 * The best way to do this is to exclude looking at portids
3553 * that have the same domain and area code as our own
3554 * portid.
984263bc 3555 */
191d7ec1
SW
3556 if (ISP_CAP_MULTI_ID(isp)) {
3557 if ((portid >> 8) == (fcp->isp_portid >> 8)) {
3558 isp_prt(isp, ISP_LOGSANCFG,
3559 "Chan %d skip PortID 0x%06x",
3560 chan, portid);
984263bc 3561 continue;
984263bc 3562 }
191d7ec1
SW
3563 } else if (portid == fcp->isp_portid) {
3564 isp_prt(isp, ISP_LOGSANCFG,
3565 "Chan %d skip ourselves on @ PortID 0x%06x",
3566 chan, portid);
984263bc
MD
3567 continue;
3568 }
3569
191d7ec1
SW
3570 isp_prt(isp, ISP_LOGSANCFG,
3571 "Chan %d Checking Fabric Port 0x%06x", chan, portid);
3572
984263bc 3573 /*
191d7ec1
SW
3574 * We now search our Port Database for any
3575 * probational entries with this PortID. We don't
3576 * look for zombies here- only probational
3577 * entries (we've already logged out of zombies).
984263bc 3578 */
191d7ec1
SW
3579 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3580 lp = &fcp->portdb[dbidx];
3581
3582 if (lp->state != FC_PORTDB_STATE_PROBATIONAL ||
3583 lp->target_mode) {
984263bc
MD
3584 continue;
3585 }
191d7ec1
SW
3586 if (lp->portid == portid) {
3587 break;
3588 }
984263bc
MD
3589 }
3590
3591 /*
191d7ec1 3592 * We found a probational entry with this Port ID.
984263bc 3593 */
191d7ec1
SW
3594 if (dbidx < MAX_FC_TARG) {
3595 int handle_changed = 0;
984263bc 3596
191d7ec1 3597 lp = &fcp->portdb[dbidx];
984263bc 3598
191d7ec1
SW
3599 /*
3600 * See if we're still logged into it.
3601 *
3602 * If we aren't, mark it as a dead device and
3603 * leave the new portid in the database entry
3604 * for somebody further along to decide what to
3605 * do (policy choice).
3606 *
3607 * If we are, check to see if it's the same
3608 * device still (it should be). If for some
3609 * reason it isn't, mark it as a changed device
3610 * and leave the new portid and role in the
3611 * database entry for somebody further along to
3612 * decide what to do (policy choice).
3613 *
3614 */
984263bc 3615
191d7ec1
SW
3616 r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
3617 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3618 FC_SCRATCH_RELEASE(isp, chan);
3619 ISP_MARK_PORTDB(isp, chan, 1);
3620 return (-1);
3621 }
3622 if (r != 0) {
3623 lp->new_portid = portid;
3624 lp->state = FC_PORTDB_STATE_DEAD;
3625 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3626 "Chan %d Fabric Port 0x%06x is dead",
3627 chan, portid);
3628 continue;
984263bc 3629 }
984263bc 3630
984263bc 3631
191d7ec1
SW
3632 /*
3633 * Check to make sure that handle, portid, WWPN and
3634 * WWNN agree. If they don't, then the association
3635 * between this PortID and the stated handle has been
3636 * broken by the firmware.
3637 */
3638 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3639 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3640 if (pdb.handle != lp->handle ||
3641 pdb.portid != portid ||
3642 wwpn != lp->port_wwn ||
3643 wwnn != lp->node_wwn) {
3644 isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3645 fconf, chan, dbidx, pdb.handle, pdb.portid,
3646 (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
3647 (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
3648 lp->handle, portid,
3649 (uint32_t) (lp->node_wwn >> 32),
3650 (uint32_t) lp->node_wwn,
3651 (uint32_t) (lp->port_wwn >> 32),
3652 (uint32_t) lp->port_wwn);
3653 /*
3654 * Try to re-login to this device using a
3655 * new handle. If that fails, mark it dead.
3656 *
3657 * isp_login_device will check for handle and
3658 * portid consistency after re-login.
3659 *
3660 */
3661 if (isp_login_device(isp, chan, portid, &pdb,
3662 &oldhandle)) {
3663 lp->new_portid = portid;
3664 lp->state = FC_PORTDB_STATE_DEAD;
3665 if (fcp->isp_loopstate !=
3666 LOOP_SCANNING_FABRIC) {
3667 FC_SCRATCH_RELEASE(isp, chan);
3668 ISP_MARK_PORTDB(isp, chan, 1);
3669 return (-1);
3670 }
3671 continue;
3672 }
3673 if (fcp->isp_loopstate !=
3674 LOOP_SCANNING_FABRIC) {
3675 FC_SCRATCH_RELEASE(isp, chan);
3676 ISP_MARK_PORTDB(isp, chan, 1);
3677 return (-1);
3678 }
3679 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3680 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3681 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3682 if (wwpn != lp->port_wwn ||
3683 wwnn != lp->node_wwn) {
3684 isp_prt(isp, ISP_LOGWARN, "changed WWN"
3685 " after relogin");
3686 lp->new_portid = portid;
3687 lp->state = FC_PORTDB_STATE_DEAD;
3688 continue;
3689 }
984263bc 3690
191d7ec1
SW
3691 lp->handle = pdb.handle;
3692 handle_changed++;
3693 }
984263bc 3694
191d7ec1 3695 nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
984263bc 3696
191d7ec1
SW
3697 /*
3698 * Check to see whether the portid and roles have
3699 * stayed the same. If they have stayed the same,
3700 * we believe that this is the same device and it
3701 * hasn't become disconnected and reconnected, so
3702 * mark it as pending valid.
3703 *
3704 * If they aren't the same, mark the device as a
3705 * changed device and save the new port id and role
3706 * and let somebody else decide.
3707 */
984263bc 3708
191d7ec1
SW
3709 lp->new_portid = portid;
3710 lp->new_roles = nr;
3711 if (pdb.portid != lp->portid || nr != lp->roles ||
3712 handle_changed) {
3713 isp_prt(isp, ISP_LOGSANCFG,
3714 "Chan %d Fabric Port 0x%06x changed",
3715 chan, portid);
3716 lp->state = FC_PORTDB_STATE_CHANGED;
3717 } else {
3718 isp_prt(isp, ISP_LOGSANCFG,
3719 "Chan %d Fabric Port 0x%06x "
3720 "Now Pending Valid", chan, portid);
3721 lp->state = FC_PORTDB_STATE_PENDING_VALID;
984263bc 3722 }
191d7ec1 3723 continue;
984263bc 3724 }
984263bc
MD
3725
3726 /*
191d7ec1
SW
3727 * Ah- a new entry. Search the database again for all non-NIL
3728 * entries to make sure we never ever make a new database entry
3729 * with the same port id. While we're at it, mark where the
3730 * last free entry was.
984263bc 3731 */
984263bc 3732
191d7ec1
SW
3733 dbidx = MAX_FC_TARG;
3734 for (lp = fcp->portdb; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
3735 if (lp >= &fcp->portdb[FL_ID] &&
3736 lp <= &fcp->portdb[SNS_ID]) {
3737 continue;
984263bc 3738 }
191d7ec1
SW
3739 /*
3740 * Skip any target mode entries.
3741 */
3742 if (lp->target_mode) {
3743 continue;
3744 }
3745 if (lp->state == FC_PORTDB_STATE_NIL) {
3746 if (dbidx == MAX_FC_TARG) {
3747 dbidx = lp - fcp->portdb;
3748 }
3749 continue;
3750 }
3751 if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3752 continue;
3753 }
3754 if (lp->portid == portid) {
984263bc
MD
3755 break;
3756 }
984263bc 3757 }
984263bc 3758
191d7ec1
SW
3759 if (lp < &fcp->portdb[MAX_FC_TARG]) {
3760 isp_prt(isp, ISP_LOGWARN, "Chan %d PortID 0x%06x "
3761 "already at %d handle %d state %d",
3762 chan, portid, dbidx, lp->handle, lp->state);
3763 continue;
3764 }
984263bc 3765
191d7ec1
SW
3766 /*
3767 * We should have the index of the first free entry seen.
3768 */
3769 if (dbidx == MAX_FC_TARG) {
3770 isp_prt(isp, ISP_LOGERR,
3771 "port database too small to login PortID 0x%06x"
3772 "- increase MAX_FC_TARG", portid);
3773 continue;
984263bc 3774 }
984263bc 3775
191d7ec1
SW
3776 /*
3777 * Otherwise, point to our new home.
3778 */
3779 lp = &fcp->portdb[dbidx];
984263bc 3780
984263bc 3781 /*
191d7ec1
SW
3782 * Try to see if we are logged into this device,
3783 * and maybe log into it.
3784 *
3785 * isp_login_device will check for handle and
3786 * portid consistency after login.
984263bc 3787 */
191d7ec1 3788 if (isp_login_device(isp, chan, portid, &pdb, &oldhandle)) {
984263bc 3789 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
191d7ec1
SW
3790 FC_SCRATCH_RELEASE(isp, chan);
3791 ISP_MARK_PORTDB(isp, chan, 1);
984263bc
MD
3792 return (-1);
3793 }
3794 continue;
3795 }
191d7ec1
SW
3796 if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3797 FC_SCRATCH_RELEASE(isp, chan);
3798 ISP_MARK_PORTDB(isp, chan, 1);
3799 return (-1);
3800 }
3801 FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3802
3803 handle = pdb.handle;
3804 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3805 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3806 nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3807
984263bc 3808 /*
191d7ec1
SW
3809 * And go through the database *one* more time to make sure
3810 * that we do not make more than one entry that has the same
3811 * WWNN/WWPN duple
984263bc 3812 */
191d7ec1
SW
3813 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3814 if (dbidx >= FL_ID && dbidx <= SNS_ID) {
3815 continue;
3816 }
3817 if (fcp->portdb[dbidx].target_mode) {
3818 continue;
3819 }
3820 if (fcp->portdb[dbidx].node_wwn == wwnn &&
3821 fcp->portdb[dbidx].port_wwn == wwpn) {
3822 break;
984263bc 3823 }
984263bc 3824 }
191d7ec1
SW
3825
3826 if (dbidx == MAX_FC_TARG) {
3827 ISP_MEMZERO(lp, sizeof (fcportdb_t));
3828 lp->handle = handle;