1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2009-2020 Alexander Motin <mav@FreeBSD.org>
5 * Copyright (c) 1997-2009 by Matthew Jacob
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 */
31
32 /*
33 * Machine and OS Independent (well, as best as possible)
34 * code for the Qlogic ISP SCSI and FC-SCSI adapters.
35 */
36
37 /*
38 * Inspiration and ideas about this driver are from Erik Moe's Linux driver
39 * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
40 * ideas dredged from the Solaris driver.
41 */
42
43 /*
44 * Include header file appropriate for platform we're building on.
45 */
46 #ifdef __NetBSD__
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD$");
49 #include <dev/ic/isp_netbsd.h>
50 #endif
51 #ifdef __FreeBSD__
52 #include <sys/param.h>
53 #include <sys/cdefs.h>
54 #include <sys/firmware.h>
55 #include <dev/isp/isp_freebsd.h>
56 #endif
57 #ifdef __OpenBSD__
58 #include <dev/ic/isp_openbsd.h>
59 #endif
60 #ifdef __linux__
61 #include "isp_linux.h"
62 #endif
63 #ifdef __svr4__
64 #include "isp_solaris.h"
65 #endif
66
67 /*
68 * Local static data
69 */
70 static const char notresp[] = "Unknown IOCB in RESPONSE Queue (type 0x%x) @ idx %d (next %d)";
71 static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
72 static const char lipd[] = "Chan %d LIP destroyed %d active commands";
73 static const char sacq[] = "unable to acquire scratch area";
74
75 static const uint8_t alpa_map[] = {
76 0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
77 0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
78 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
79 0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
80 0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
81 0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
82 0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
83 0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
84 0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
85 0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
86 0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
87 0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
88 0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
89 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
90 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
91 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
92 };
93
94 /*
95 * Local function prototypes.
96 */
97 static int isp_handle_control(ispsoftc_t *, isphdr_t *);
98 static void isp_handle_rpt_id_acq(ispsoftc_t *, isphdr_t *);
99 static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *);
100 static void isp_clear_portdb(ispsoftc_t *, int);
101 static void isp_mark_portdb(ispsoftc_t *, int);
102 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int);
103 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *);
104 static int isp_gethandles(ispsoftc_t *, int, uint16_t *, int *, int);
105 static void isp_dump_chip_portdb(ispsoftc_t *, int);
106 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
107 static int isp_fclink_test(ispsoftc_t *, int, int);
108 static int isp_pdb_sync(ispsoftc_t *, int);
109 static int isp_scan_loop(ispsoftc_t *, int);
110 static int isp_gid_pt(ispsoftc_t *, int);
111 static int isp_scan_fabric(ispsoftc_t *, int);
112 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
113 static int isp_register_fc4_type(ispsoftc_t *, int);
114 static int isp_register_fc4_features_24xx(ispsoftc_t *, int);
115 static int isp_register_port_name_24xx(ispsoftc_t *, int);
116 static int isp_register_node_name_24xx(ispsoftc_t *, int);
117 static uint16_t isp_next_handle(ispsoftc_t *, uint16_t *);
118 static int isp_fw_state(ispsoftc_t *, int);
119 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
120
121 static void isp_get_flash_addrs(ispsoftc_t *);
122 static void isp_setdfltfcparm(ispsoftc_t *, int);
123 static int isp_read_flash_dword(ispsoftc_t *, uint32_t, uint32_t *);
124 static int isp_read_flash_data(ispsoftc_t *, uint32_t *, uint32_t, uint32_t);
125 static void isp_rd_2xxx_flash(ispsoftc_t *, uint32_t, uint32_t *);
126 static int isp_read_flthdr_2xxx(ispsoftc_t *);
127 static void isp_parse_flthdr_2xxx(ispsoftc_t *, uint8_t *);
128 static int isp_read_flt_2xxx(ispsoftc_t *);
129 static int isp_parse_flt_2xxx(ispsoftc_t *, uint8_t *);
130 static int isp_read_nvram(ispsoftc_t *);
131 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
132
133 static void isp_print_image(ispsoftc_t *, char *, struct isp_image_status *);
134 static bool isp_check_aux_image_status_signature(struct isp_image_status *);
135 static bool isp_check_image_status_signature(struct isp_image_status *);
136 static unsigned long isp_image_status_checksum(struct isp_image_status *);
137 static void isp_component_status(struct active_regions *, struct isp_image_status *);
138 static int isp_compare_image_generation(ispsoftc_t *, struct isp_image_status *, struct isp_image_status *);
139 static void isp_get_aux_images(ispsoftc_t *, struct active_regions *);
140 static void isp_get_active_image(ispsoftc_t *, struct active_regions *);
141 static bool isp_risc_firmware_invalid(ispsoftc_t *, uint32_t *);
142 static int isp_load_ram(ispsoftc_t *, uint32_t *, uint32_t, uint32_t);
143 static int isp_load_risc_flash(ispsoftc_t *, uint32_t *, uint32_t);
144 static int isp_load_risc(ispsoftc_t *, uint32_t *);
145
146 static void
isp_change_fw_state(ispsoftc_t * isp,int chan,int state)147 isp_change_fw_state(ispsoftc_t *isp, int chan, int state)
148 {
149 fcparam *fcp = FCPARAM(isp, chan);
150
151 if (fcp->isp_fwstate == state)
152 return;
153 isp_prt(isp, ISP_LOGCONFIG|ISP_LOG_SANCFG,
154 "Chan %d Firmware state <%s->%s>", chan,
155 isp_fc_fw_statename(fcp->isp_fwstate), isp_fc_fw_statename(state));
156 fcp->isp_fwstate = state;
157 }
158
159 static void
isp_get_flash_addrs(ispsoftc_t * isp)160 isp_get_flash_addrs(ispsoftc_t *isp)
161 {
162 fcparam *fcp = FCPARAM(isp, 0);
163 int r = 0;
164
165 if (IS_28XX(isp)) {
166 fcp->flash_data_addr = ISP28XX_BASE_ADDR;
167 fcp->flt_region_flt = ISP28XX_FLT_ADDR;
168 } else if (IS_26XX(isp)) { /* 26xx and 27xx are identical */
169 fcp->flash_data_addr = ISP27XX_BASE_ADDR;
170 fcp->flt_region_flt = ISP27XX_FLT_ADDR;
171 } else if (IS_25XX(isp)) {
172 fcp->flash_data_addr = ISP25XX_BASE_ADDR;
173 fcp->flt_region_flt = ISP25XX_FLT_ADDR;
174 } else {
175 fcp->flash_data_addr = ISP24XX_BASE_ADDR;
176 fcp->flt_region_flt = ISP24XX_FLT_ADDR;
177 }
178 fcp->flt_length = 0;
179 r = isp_read_flthdr_2xxx(isp);
180 if (r == 0) {
181 isp_read_flt_2xxx(isp);
182 } else { /* fallback to hardcoded NVRAM address */
183 if (IS_28XX(isp)) {
184 fcp->flt_region_nvram = 0x300000;
185 } else if (IS_26XX(isp)) {
186 fcp->flash_data_addr = 0x7fe7c000;
187 fcp->flt_region_nvram = 0;
188 } else if (IS_25XX(isp)) {
189 fcp->flt_region_nvram = 0x48000;
190 } else {
191 fcp->flash_data_addr = 0x7ffe0000;
192 fcp->flt_region_nvram = 0;
193 }
194 fcp->flt_region_nvram += ISP2400_NVRAM_PORT_ADDR(isp->isp_port);
195 }
196 }
197
198 /*
199 * Reset Hardware.
200 *
201 * Hit the chip over the head, download new f/w if available and set it running.
202 *
203 * Locking done elsewhere.
204 */
205
206 void
isp_reset(ispsoftc_t * isp,int do_load_defaults)207 isp_reset(ispsoftc_t *isp, int do_load_defaults)
208 {
209 mbreg_t mbs;
210 char *buf;
211 uint16_t fwt;
212 uint32_t code_org, val;
213 int loaded_fw, loops, i, dodnld = 1;
214 const char *btype = "????";
215 static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
216
217 isp->isp_state = ISP_NILSTATE;
218 ISP_DISABLE_INTS(isp);
219
220 /*
221 * Put the board into PAUSE mode (so we can read the SXP registers
222 * or write FPM/FBM registers).
223 */
224 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
225 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
226 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
227
228 switch (isp->isp_type) {
229 case ISP_HA_FC_2400:
230 btype = "2422";
231 break;
232 case ISP_HA_FC_2500:
233 btype = "2532";
234 break;
235 case ISP_HA_FC_2600:
236 btype = "2600";
237 break;
238 case ISP_HA_FC_2700:
239 btype = "2700";
240 break;
241 case ISP_HA_FC_2800:
242 btype = "2800";
243 break;
244 default:
245 break;
246 }
247
248 /*
249 * Stop DMA and wait for it to stop.
250 */
251 ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
252 for (loops = 0; loops < 100000; loops++) {
253 ISP_DELAY(10);
254 val = ISP_READ(isp, BIU2400_CSR);
255 if ((val & BIU2400_DMA_ACTIVE) == 0) {
256 break;
257 }
258 }
259 if (val & BIU2400_DMA_ACTIVE)
260 isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
261
262 /*
263 * Hold it in SOFT_RESET and STOP state for 100us.
264 */
265 ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
266 ISP_DELAY(100);
267 for (loops = 0; loops < 10000; loops++) {
268 ISP_DELAY(5);
269 val = ISP_READ(isp, OUTMAILBOX0);
270 if (val != 0x4)
271 break;
272 }
273 switch (val) {
274 case 0x0:
275 break;
276 case 0x4:
277 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
278 return;
279 case 0xf:
280 isp_prt(isp, ISP_LOGERR, "Board configuration error.");
281 return;
282 default:
283 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
284 return;
285 }
286
287 /*
288 * Reset RISC Processor
289 */
290 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
291 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
292 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
293
294 /*
295 * Post-RISC Reset stuff.
296 */
297 for (loops = 0; loops < 10000; loops++) {
298 ISP_DELAY(5);
299 val = ISP_READ(isp, OUTMAILBOX0);
300 if (val != 0x4)
301 break;
302 }
303 switch (val) {
304 case 0x0:
305 break;
306 case 0x4:
307 isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
308 return;
309 case 0xf:
310 isp_prt(isp, ISP_LOGERR, "Board configuration error.");
311 return;
312 default:
313 isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
314 return;
315 }
316
317 isp->isp_reqidx = isp->isp_reqodx = 0;
318 isp->isp_resodx = 0;
319 isp->isp_atioodx = 0;
320 ISP_WRITE(isp, BIU2400_REQINP, 0);
321 ISP_WRITE(isp, BIU2400_REQOUTP, 0);
322 ISP_WRITE(isp, BIU2400_RSPINP, 0);
323 ISP_WRITE(isp, BIU2400_RSPOUTP, 0);
324 if (!IS_26XX(isp)) {
325 ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
326 ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
327 }
328 ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
329 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
330
331 /*
332 * Up until this point we've done everything by just reading or
333 * setting registers. From this point on we rely on at least *some*
334 * kind of firmware running in the card.
335 */
336
337 /*
338 * Do some sanity checking by running a NOP command.
339 * If it succeeds, the ROM firmware is now running.
340 */
341 MBSINIT(&mbs, MBOX_NO_OP, MBLOGALL, 0);
342 isp_mboxcmd(isp, &mbs);
343 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
344 isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
345 return;
346 }
347
348 /*
349 * Do some operational tests
350 */
351 {
352 static const uint16_t patterns[MAX_MAILBOX] = {
353 0x0000, 0xdead, 0xbeef, 0xffff,
354 0xa5a5, 0x5a5a, 0x7f7f, 0x7ff7,
355 0x3421, 0xabcd, 0xdcba, 0xfeef,
356 0xbead, 0xdebe, 0x2222, 0x3333,
357 0x5555, 0x6666, 0x7777, 0xaaaa,
358 0xffff, 0xdddd, 0x9999, 0x1fbc,
359 0x6666, 0x6677, 0x1122, 0x33ff,
360 0x0000, 0x0001, 0x1000, 0x1010,
361 };
362 int nmbox = ISP_NMBOX(isp);
363 MBSINIT(&mbs, MBOX_MAILBOX_REG_TEST, MBLOGALL, 0);
364 for (i = 1; i < nmbox; i++) {
365 mbs.param[i] = patterns[i];
366 }
367 isp_mboxcmd(isp, &mbs);
368 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
369 return;
370 }
371 for (i = 1; i < nmbox; i++) {
372 if (mbs.param[i] != patterns[i]) {
373 isp_prt(isp, ISP_LOGERR, "Register Test Failed at Register %d: should have 0x%04x but got 0x%04x", i, patterns[i], mbs.param[i]);
374 return;
375 }
376 }
377 }
378
379 /*
380 * Early setup DMA for the request and response queues.
381 * We do this now so we can use the request queue
382 * for dma to load firmware from.
383 */
384
385 if (ISP_MBOXDMASETUP(isp) != 0) {
386 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
387 return;
388 }
389
390 /*
391 * FW load priority
392 * For 27xx and newer:
393 * Load ispfw(4) firmware unless requested not to do so.
394 * Request (active) flash firmware information. Compare
395 * version numbers of ispfw(4) and flash firmware. Load
396 * the highest version into RAM of the adapter.
397 * If loading ispfw(4) is disabled or loading it failed
398 * (eg. no firmware available) we just load firmware from
399 * flash. If this fails for whatever reason we fallback
400 * to let the adapter MBOX_LOAD_FLASH_FIRMWARE by itself
401 * followed by MBOX_EXEC_FIRMWARE and hope the best to
402 * get it up and running.
403 *
404 * For 26xx and older:
405 * Load ispfw(4) firmware unless requested not to do so
406 * and load it into RAM of the adapter. If loading
407 * ispfw(4) is disabled or loading it failed (eg. no
408 * firmware available) we just let the adapter
409 * MBOX_EXEC_FIRMWARE to start the flash firmware.
410 * For the 26xx a preceding MBOX_LOAD_FLASH_FIRMWARE
411 * is required.
412 */
413
414 fcparam *fcp = FCPARAM(isp, 0);
415
416 /* read FLT to get flash region addresses */
417 isp_get_flash_addrs(isp);
418
419 /* set informational sysctl(8) to sane value */
420 snprintf(fcp->fw_version_ispfw, sizeof(fcp->fw_version_ispfw),
421 "not loaded");
422 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
423 "not loaded");
424 snprintf(fcp->fw_version_run, sizeof(fcp->fw_version_run),
425 "not loaded");
426
427
428 /* Try to load ispfw(4) first */
429 if (!(isp->isp_confopts & ISP_CFG_NORELOAD)) {
430 char fwname[32];
431 snprintf(fwname, sizeof(fwname), "isp_%04x", isp->isp_did);
432 isp->isp_osinfo.ispfw = firmware_get(fwname);
433 if (isp->isp_osinfo.ispfw != NULL) {
434 isp->isp_mdvec->dv_ispfw = isp->isp_osinfo.ispfw->data;
435 const uint32_t *ispfwptr = isp->isp_mdvec->dv_ispfw;
436 for (i = 0; i < 4; i++)
437 fcp->fw_ispfwrev[i] = ispfwptr[4 + i];
438 isp_prt(isp, ISP_LOGCONFIG,
439 "Loaded ispfw(4) firmware %s", fwname);
440 snprintf(fcp->fw_version_ispfw,
441 sizeof(fcp->fw_version_ispfw),
442 "%u.%u.%u", fcp->fw_ispfwrev[0],
443 fcp->fw_ispfwrev[1], fcp->fw_ispfwrev[2]);
444 isp_prt(isp, ISP_LOGCONFIG,
445 "Firmware revision (ispfw) %u.%u.%u (%x).",
446 fcp->fw_ispfwrev[0], fcp->fw_ispfwrev[1],
447 fcp->fw_ispfwrev[2], fcp->fw_ispfwrev[3]);
448 } else {
449 isp_prt(isp, ISP_LOGDEBUG0,
450 "Unable to load ispfw(4) firmware %s", fwname);
451 }
452 }
453
454 loaded_fw = 0;
455 dodnld = 0;
456
457 if (IS_27XX(isp)) {
458 switch (isp_load_risc(isp, 0)) {
459 case ISP_ABORTED:
460 /*
461 * download ispfw(4) as it's newer than flash, or
462 * the user requested it.
463 */
464 dodnld = 1;
465 break;
466 case ISP_SUCCESS:
467 /* We've loaded flash firmware */
468 loaded_fw = 1;
469 break;
470 default:
471 /*
472 * Fall through to use ispfw(4) if available or
473 * just fall back to use MBOX_LOAD_FLASH_FIRMWARE
474 */
475 if (isp->isp_osinfo.ispfw != NULL)
476 dodnld = 1;
477 break;
478 }
479 } else {
480 /* Fall through to load ispfw(4) or simply MBOX_EXEC_FIRMWARE */
481 if (isp->isp_osinfo.ispfw != NULL)
482 dodnld = 1;
483 }
484
485 code_org = ISP_CODE_ORG_2400;
486 if (dodnld) {
487 const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
488 uint32_t la, wi, wl;
489
490 /* Keep loading until we run out of f/w. */
491 code_org = ptr[2]; /* 1st load address is our start addr */
492 for (;;) {
493 isp_prt(isp, ISP_LOGDEBUG2,
494 "Load 0x%x words of code at load address 0x%x",
495 ptr[3], ptr[2]);
496
497 wi = 0;
498 la = ptr[2];
499 wl = ptr[3];
500 while (wi < ptr[3]) {
501 uint32_t *cp;
502 uint32_t nw;
503
504 nw = min(wl, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4);
505 cp = isp->isp_rquest;
506 for (i = 0; i < nw; i++)
507 ISP_IOXPUT_32(isp, ptr[wi + i], &cp[i]);
508 if (isp_load_ram(isp, cp, la, nw) != 0) {
509 isp_prt(isp, ISP_LOGERR,
510 "Failed to load firmware fragment.");
511 return;
512 }
513 la += nw;
514 wi += nw;
515 wl -= nw;
516 }
517
518 if (ptr[1] == 0) {
519 break;
520 }
521 ptr += ptr[3];
522 }
523 loaded_fw = 1;
524 /* Drop reference to ispfw(4) firmware */
525 if (isp->isp_osinfo.ispfw != NULL)
526 firmware_put(isp->isp_osinfo.ispfw, FIRMWARE_UNLOAD);
527 } else {
528 isp_prt(isp, ISP_LOGCONFIG,
529 "Skipping ispfw(4) firmware download");
530 }
531
532 /* If we loaded firmware, verify its checksum. */
533 if (loaded_fw) {
534 MBSINIT(&mbs, MBOX_VERIFY_CHECKSUM, MBLOGNONE, 0);
535 mbs.param[1] = code_org >> 16;
536 mbs.param[2] = code_org;
537 isp_mboxcmd(isp, &mbs);
538 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
539 isp_prt(isp, ISP_LOGERR, "%s: 0x%x", dcrc,
540 (mbs.param[2] << 16 | mbs.param[1]));
541 return;
542 }
543 } else if (IS_26XX(isp)) {
544 isp_prt(isp, ISP_LOGCONFIG,
545 "Instruct RISC to load firmware from flash by itself");
546 MBSINIT(&mbs, MBOX_LOAD_FLASH_FIRMWARE, MBLOGALL, 5000000);
547 isp_mboxcmd(isp, &mbs);
548 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
549 isp_prt(isp, ISP_LOGERR, "Flash F/W load failed");
550 return;
551 }
552 }
553
554 /*
555 * Now start it rolling.
556 *
557 * If we didn't actually download f/w,
558 * we still need to (re)start it.
559 */
560 MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 5000000);
561 mbs.param[1] = code_org >> 16;
562 mbs.param[2] = code_org;
563 if (!IS_26XX(isp))
564 mbs.param[3] = loaded_fw ? 0 : 1;
565 mbs.param[4] = 0;
566 if (IS_27XX(isp))
567 mbs.param[4] |= 0x08; /* NVME_ENABLE_FLAG */
568 mbs.param[11] = 0;
569 isp_mboxcmd(isp, &mbs);
570 if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
571 return;
572 fcp->fw_ability_mask = (mbs.param[3] << 16) | mbs.param[2];
573 isp_prt(isp, ISP_LOGDEBUG0, "Firmware ability mask: 0x%x",
574 fcp->fw_ability_mask);
575 if (IS_26XX(isp)) {
576 fcp->max_supported_speed = mbs.param[2] & (0x1 | 0x2);
577 isp_prt(isp, ISP_LOGINFO, "Maximum supported speed: %s",
578 fcp->max_supported_speed == 0 ? "16Gbit/s" :
579 fcp->max_supported_speed == 1 ? "32Gbit/s" :
580 fcp->max_supported_speed == 2 ? "64Gbit/s" : "unknown");
581 }
582 if (IS_28XX(isp) && (mbs.param[5] & 0x400)) {
583 isp_prt(isp, ISP_LOGINFO,
584 "HW supports EDIF (Encryption of data in flight)");
585 }
586
587 /*
588 * Ask the chip for the current firmware version.
589 * This should prove that the new firmware is working.
590 */
591 MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 5000000);
592 isp_mboxcmd(isp, &mbs);
593 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
594 return;
595 }
596
597 isp->isp_fwrev[0] = mbs.param[1];
598 isp->isp_fwrev[1] = mbs.param[2];
599 isp->isp_fwrev[2] = mbs.param[3];
600 isp->isp_fwattr = mbs.param[6];
601 isp->isp_fwattr_h = mbs.param[15];
602 if (isp->isp_fwattr & ISP_FW_ATTR_EXTNDED) {
603 isp->isp_fwattr_ext[0] = mbs.param[16];
604 isp->isp_fwattr_ext[1] = mbs.param[17];
605 }
606
607 isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
608 btype, isp->isp_revision, dodnld ? "loaded" : "resident",
609 isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
610 snprintf(fcp->fw_version_run, sizeof(fcp->fw_version_run),
611 "%u.%u.%u", isp->isp_fwrev[0], isp->isp_fwrev[1],
612 isp->isp_fwrev[2]);
613 if (!dodnld && !IS_26XX(isp))
614 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
615 "%s", fcp->fw_version_run);
616
617 fwt = isp->isp_fwattr;
618 buf = FCPARAM(isp, 0)->isp_scanscratch;
619 ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "FW Attributes Lower:");
620 if (fwt & ISP_FW_ATTR_CLASS2) {
621 fwt ^= ISP_FW_ATTR_CLASS2;
622 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s Class2", buf);
623 }
624 if (fwt & ISP_FW_ATTR_IP) {
625 fwt ^= ISP_FW_ATTR_IP;
626 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s IP", buf);
627 }
628 if (fwt & ISP_FW_ATTR_MULTIID) {
629 fwt ^= ISP_FW_ATTR_MULTIID;
630 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MultiID", buf);
631 }
632 if (fwt & ISP_FW_ATTR_SB2) {
633 fwt ^= ISP_FW_ATTR_SB2;
634 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SB2", buf);
635 }
636 if (fwt & ISP_FW_ATTR_T10CRC) {
637 fwt ^= ISP_FW_ATTR_T10CRC;
638 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s T10CRC", buf);
639 }
640 if (fwt & ISP_FW_ATTR_VI) {
641 fwt ^= ISP_FW_ATTR_VI;
642 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VI", buf);
643 }
644 if (fwt & ISP_FW_ATTR_MQ) {
645 fwt ^= ISP_FW_ATTR_MQ;
646 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MQ", buf);
647 }
648 if (fwt & ISP_FW_ATTR_MSIX) {
649 fwt ^= ISP_FW_ATTR_MSIX;
650 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MSIX", buf);
651 }
652 if (fwt & ISP_FW_ATTR_FCOE) {
653 fwt ^= ISP_FW_ATTR_FCOE;
654 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s FCOE", buf);
655 }
656 if (fwt & ISP_FW_ATTR_VP0) {
657 fwt ^= ISP_FW_ATTR_VP0;
658 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VP0_Decoupling", buf);
659 }
660 if (fwt & ISP_FW_ATTR_EXPFW) {
661 fwt ^= ISP_FW_ATTR_EXPFW;
662 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (Experimental)", buf);
663 }
664 if (fwt & ISP_FW_ATTR_HOTFW) {
665 fwt ^= ISP_FW_ATTR_HOTFW;
666 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s HotFW", buf);
667 }
668 fwt &= ~ISP_FW_ATTR_EXTNDED;
669 if (fwt) {
670 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
671 "%s (unknown 0x%04x)", buf, fwt);
672 }
673 isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
674
675 fwt = isp->isp_fwattr_h;
676 buf = FCPARAM(isp, 0)->isp_scanscratch;
677 ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "FW Attributes Upper:");
678 if (fwt & ISP_FW_ATTR_H_EXTVP) {
679 fwt ^= ISP_FW_ATTR_H_EXTVP;
680 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ExtVP", buf);
681 }
682 if (fwt & ISP_FW_ATTR_H_VN2VN) {
683 fwt ^= ISP_FW_ATTR_H_VN2VN;
684 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VN2VN", buf);
685 }
686 if (fwt & ISP_FW_ATTR_H_EXMOFF) {
687 fwt ^= ISP_FW_ATTR_H_EXMOFF;
688 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s EXMOFF", buf);
689 }
690 if (fwt & ISP_FW_ATTR_H_NPMOFF) {
691 fwt ^= ISP_FW_ATTR_H_NPMOFF;
692 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NPMOFF", buf);
693 }
694 if (fwt & ISP_FW_ATTR_H_DIFCHOP) {
695 fwt ^= ISP_FW_ATTR_H_DIFCHOP;
696 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s DIFCHOP", buf);
697 }
698 if (fwt & ISP_FW_ATTR_H_SRIOV) {
699 fwt ^= ISP_FW_ATTR_H_SRIOV;
700 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SRIOV", buf);
701 }
702 if (fwt & ISP_FW_ATTR_H_NVME) {
703 fwt ^= ISP_FW_ATTR_H_NVME;
704 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe", buf);
705 }
706 if (fwt & ISP_FW_ATTR_H_NVME_UP) {
707 fwt ^= ISP_FW_ATTR_H_NVME_UP;
708 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe(updated)", buf);
709 }
710 if (fwt & (ISP_FW_ATTR_H_NVME_FB)) {
711 fwt ^= (ISP_FW_ATTR_H_NVME_FB);
712 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe(first burst)", buf);
713 }
714 if (fwt) {
715 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
716 "%s (unknown 0x%04x)", buf, fwt);
717 }
718 isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
719
720 fwt = isp->isp_fwattr_ext[0];
721 buf = FCPARAM(isp, 0)->isp_scanscratch;
722 ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "FW Ext. Attributes Lower:");
723 if (fwt & ISP_FW_ATTR_E0_ASICTMP) {
724 fwt ^= ISP_FW_ATTR_E0_ASICTMP;
725 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ASICTMP", buf);
726 }
727 if (fwt & ISP_FW_ATTR_E0_ATIOMQ) {
728 fwt ^= ISP_FW_ATTR_E0_ATIOMQ;
729 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ATIOMQ", buf);
730 }
731 if (fwt & ISP_FW_ATTR_E0_EDIF) {
732 fwt ^= ISP_FW_ATTR_E0_EDIF;
733 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s EDIF", buf);
734 }
735 if (fwt & ISP_FW_ATTR_E0_SCM) {
736 fwt ^= ISP_FW_ATTR_E0_SCM;
737 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SCM", buf);
738 }
739 if (fwt & ISP_FW_ATTR_E0_NVME2) {
740 fwt ^= ISP_FW_ATTR_E0_NVME2;
741 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe-2", buf);
742 }
743 if (fwt) {
744 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
745 "%s (unknown 0x%04x)", buf, fwt);
746 }
747 isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
748
749 fwt = isp->isp_fwattr_ext[1];
750 buf = FCPARAM(isp, 0)->isp_scanscratch;
751 ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "FW Ext. Attributes Upper:");
752 if (fwt) {
753 ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
754 "%s (unknown 0x%04x)", buf, fwt);
755 }
756 isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
757
758 /*
759 * For the maximum number of commands take free exchange control block
760 * buffer count reported by firmware, limiting it to the maximum of our
761 * hardcoded handle format (16K now) minus some management reserve.
762 */
763 MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
764 isp_mboxcmd(isp, &mbs);
765 if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
766 return;
767 isp->isp_maxcmds = MIN(mbs.param[3], ISP_HANDLE_MAX - ISP_HANDLE_RESERVE);
768 isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
769
770 /*
771 * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
772 * Only make this check for non-SCSI cards (I'm not sure firmware attributes
773 * work for them).
774 */
775 if (isp->isp_nchan > 1) {
776 if (!ISP_CAP_MULTI_ID(isp)) {
777 isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, "
778 "only can enable 1 of %d channels", isp->isp_nchan);
779 isp->isp_nchan = 1;
780 } else if (!ISP_CAP_VP0(isp)) {
781 isp_prt(isp, ISP_LOGWARN, "We can not use MULTIID "
782 "feature properly without VP0_Decoupling");
783 isp->isp_nchan = 1;
784 }
785 }
786
787 /*
788 * Final DMA setup after we got isp_maxcmds.
789 */
790 if (ISP_MBOXDMASETUP(isp) != 0) {
791 isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
792 return;
793 }
794
795 /*
796 * Setup interrupts.
797 */
798 if (ISP_IRQSETUP(isp) != 0) {
799 isp_prt(isp, ISP_LOGERR, "Cannot setup IRQ");
800 return;
801 }
802 ISP_ENABLE_INTS(isp);
803
804 for (i = 0; i < isp->isp_nchan; i++)
805 isp_change_fw_state(isp, i, FW_CONFIG_WAIT);
806
807 isp->isp_state = ISP_RESETSTATE;
808
809 /*
810 * We get some default values established. As a side
811 * effect, NVRAM is read here (unless overridden by
812 * a configuration flag).
813 */
814 if (do_load_defaults) {
815 for (i = 0; i < isp->isp_nchan; i++)
816 isp_setdfltfcparm(isp, i);
817 }
818 }
819
820 /*
821 * Clean firmware shutdown.
822 */
823 static int
isp_stop(ispsoftc_t * isp)824 isp_stop(ispsoftc_t *isp)
825 {
826 mbreg_t mbs;
827
828 isp->isp_state = ISP_NILSTATE;
829 MBSINIT(&mbs, MBOX_STOP_FIRMWARE, MBLOGALL, 500000);
830 mbs.param[1] = 0;
831 mbs.param[2] = 0;
832 mbs.param[3] = 0;
833 mbs.param[4] = 0;
834 mbs.param[5] = 0;
835 mbs.param[6] = 0;
836 mbs.param[7] = 0;
837 mbs.param[8] = 0;
838 isp_mboxcmd(isp, &mbs);
839 return (mbs.param[0] == MBOX_COMMAND_COMPLETE ? 0 : mbs.param[0]);
840 }
841
842 /*
843 * Hardware shutdown.
844 */
845 void
isp_shutdown(ispsoftc_t * isp)846 isp_shutdown(ispsoftc_t *isp)
847 {
848
849 if (isp->isp_state >= ISP_RESETSTATE)
850 isp_stop(isp);
851 ISP_DISABLE_INTS(isp);
852 ISP_WRITE(isp, BIU2400_ICR, 0);
853 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
854 }
855
856 /*
857 * Initialize Parameters of Hardware to a known state.
858 *
859 * Locks are held before coming here.
860 */
861 void
isp_init(ispsoftc_t * isp)862 isp_init(ispsoftc_t *isp)
863 {
864 fcparam *fcp;
865 isp_icb_2400_t local, *icbp = &local;
866 mbreg_t mbs;
867 int chan;
868 int ownloopid = 0;
869
870 /*
871 * Check to see whether all channels have *some* kind of role
872 */
873 for (chan = 0; chan < isp->isp_nchan; chan++) {
874 fcp = FCPARAM(isp, chan);
875 if (fcp->role != ISP_ROLE_NONE) {
876 break;
877 }
878 }
879 if (chan == isp->isp_nchan) {
880 isp_prt(isp, ISP_LOG_WARN1, "all %d channels with role 'none'", chan);
881 return;
882 }
883
884 isp->isp_state = ISP_INITSTATE;
885
886 /*
887 * Start with channel 0.
888 */
889 fcp = FCPARAM(isp, 0);
890
891 /*
892 * Turn on LIP F8 async event (1)
893 */
894 MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
895 mbs.param[1] = 1;
896 isp_mboxcmd(isp, &mbs);
897 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
898 return;
899 }
900
901 ISP_MEMZERO(icbp, sizeof (*icbp));
902 icbp->icb_fwoptions1 = fcp->isp_fwoptions;
903 icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
904 icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
905 if (isp->isp_nchan > 1 && ISP_CAP_VP0(isp)) {
906 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
907 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
908 } else {
909 if (fcp->role & ISP_ROLE_TARGET)
910 icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
911 else
912 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
913 if (fcp->role & ISP_ROLE_INITIATOR)
914 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
915 else
916 icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
917 }
918
919 icbp->icb_version = ICB_VERSION1;
920 icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
921 if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
922 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
923 if (IS_28XX(isp))
924 icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN_28XX;
925
926 isp_prt(isp, ISP_LOGERR,
927 "bad frame length (%d) from NVRAM - using %d",
928 DEFAULT_FRAMESIZE(isp), icbp->icb_maxfrmlen);
929 }
930
931 if (!IS_26XX(isp))
932 icbp->icb_execthrottle = 0xffff;
933
934 #ifdef ISP_TARGET_MODE
935 /*
936 * Set target exchange count. Take half if we are supporting both roles.
937 */
938 if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
939 if ((icbp->icb_fwoptions1 & ICB2400_OPT1_INI_DISABLE) == 0)
940 icbp->icb_xchgcnt = MIN(isp->isp_maxcmds / 2, ATPDPSIZE);
941 else
942 icbp->icb_xchgcnt = isp->isp_maxcmds;
943 }
944 #endif
945
946 ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
947 icbp->icb_hardaddr = fcp->isp_loopid;
948 if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
949 icbp->icb_hardaddr = 0;
950 ownloopid = 0;
951 }
952
953 if (ownloopid)
954 icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
955
956 if (isp->isp_confopts & ISP_CFG_NOFCTAPE) {
957 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
958 }
959 if (isp->isp_confopts & ISP_CFG_FCTAPE) {
960 icbp->icb_fwoptions2 |= ICB2400_OPT2_FCTAPE;
961 }
962
963 for (chan = 0; chan < isp->isp_nchan; chan++) {
964 if (icbp->icb_fwoptions2 & ICB2400_OPT2_FCTAPE)
965 FCPARAM(isp, chan)->fctape_enabled = 1;
966 else
967 FCPARAM(isp, chan)->fctape_enabled = 0;
968 }
969
970 switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
971 case ISP_CFG_LPORT_ONLY:
972 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
973 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
974 break;
975 case ISP_CFG_NPORT_ONLY:
976 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
977 icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
978 break;
979 case ISP_CFG_NPORT:
980 /* ISP_CFG_PTP_2_LOOP not available in 24XX/25XX */
981 case ISP_CFG_LPORT:
982 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
983 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
984 break;
985 default:
986 /* Let NVRAM settings define it if they are sane */
987 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TOPO_MASK) {
988 case ICB2400_OPT2_LOOP_ONLY:
989 case ICB2400_OPT2_PTP_ONLY:
990 case ICB2400_OPT2_LOOP_2_PTP:
991 break;
992 default:
993 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
994 icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
995 }
996 break;
997 }
998
999 switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
1000 case ICB2400_OPT2_ZIO:
1001 case ICB2400_OPT2_ZIO1:
1002 icbp->icb_idelaytimer = 0;
1003 break;
1004 case 0:
1005 break;
1006 default:
1007 isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
1008 icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
1009 break;
1010 }
1011
1012 if (IS_26XX(isp)) {
1013 /* Use handshake to reduce global lock congestion. */
1014 icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHR;
1015 icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHA;
1016 }
1017
1018 if ((icbp->icb_fwoptions3 & ICB2400_OPT3_RSPSZ_MASK) == 0) {
1019 icbp->icb_fwoptions3 |= ICB2400_OPT3_RSPSZ_24;
1020 }
1021 if (isp->isp_confopts & ISP_CFG_1GB) {
1022 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1023 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_1GB;
1024 } else if (isp->isp_confopts & ISP_CFG_2GB) {
1025 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1026 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_2GB;
1027 } else if (isp->isp_confopts & ISP_CFG_4GB) {
1028 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1029 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_4GB;
1030 } else if (isp->isp_confopts & ISP_CFG_8GB) {
1031 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1032 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_8GB;
1033 } else if (isp->isp_confopts & ISP_CFG_16GB) {
1034 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1035 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_16GB;
1036 } else if (isp->isp_confopts & ISP_CFG_32GB) {
1037 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1038 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_32GB;
1039 } else if (isp->isp_confopts & ISP_CFG_64GB) {
1040 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1041 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_64GB;
1042 } else {
1043 switch (icbp->icb_fwoptions3 & ICB2400_OPT3_RATE_MASK) {
1044 case ICB2400_OPT3_RATE_4GB:
1045 case ICB2400_OPT3_RATE_8GB:
1046 case ICB2400_OPT3_RATE_16GB:
1047 case ICB2400_OPT3_RATE_32GB:
1048 case ICB2400_OPT3_RATE_64GB:
1049 case ICB2400_OPT3_RATE_AUTO:
1050 break;
1051 case ICB2400_OPT3_RATE_2GB:
1052 if (isp->isp_type <= ISP_HA_FC_2500)
1053 break;
1054 /*FALLTHROUGH*/
1055 case ICB2400_OPT3_RATE_1GB:
1056 if (isp->isp_type <= ISP_HA_FC_2400)
1057 break;
1058 /*FALLTHROUGH*/
1059 default:
1060 icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1061 icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
1062 break;
1063 }
1064 }
1065 if (ownloopid == 0) {
1066 icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
1067 }
1068 icbp->icb_logintime = ICB_LOGIN_TOV;
1069
1070 if (fcp->isp_wwnn && fcp->isp_wwpn) {
1071 icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
1072 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1073 MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1074 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)),
1075 ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1076 } else if (fcp->isp_wwpn) {
1077 icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
1078 MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1079 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)));
1080 } else {
1081 isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1082 return;
1083 }
1084 icbp->icb_rspnsin = isp->isp_resodx;
1085 icbp->icb_rqstout = isp->isp_reqidx;
1086 icbp->icb_retry_count = fcp->isp_retry_count;
1087
1088 icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1089 if (icbp->icb_rqstqlen < 8) {
1090 isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
1091 return;
1092 }
1093 icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1094 if (icbp->icb_rsltqlen < 8) {
1095 isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
1096 icbp->icb_rsltqlen);
1097 return;
1098 }
1099 icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1100 icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1101 icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1102 icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1103
1104 icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1105 icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1106 icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1107 icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1108
1109 #ifdef ISP_TARGET_MODE
1110 /* unconditionally set up the ATIO queue if we support target mode */
1111 icbp->icb_atio_in = isp->isp_atioodx;
1112 icbp->icb_atioqlen = ATIO_QUEUE_LEN(isp);
1113 if (icbp->icb_atioqlen < 8) {
1114 isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
1115 return;
1116 }
1117 icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
1118 icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
1119 icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
1120 icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
1121 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
1122 DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
1123 #endif
1124
1125 if (ISP_CAP_MSIX(isp) && isp->isp_nirq >= 2) {
1126 icbp->icb_msixresp = 1;
1127 if (IS_26XX(isp) && isp->isp_nirq >= 3)
1128 icbp->icb_msixatio = 2;
1129 }
1130
1131 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
1132
1133 isp_prt(isp, ISP_LOGDEBUG0, "isp_init: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
1134 DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
1135 DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
1136
1137 if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1138 isp_prt(isp, ISP_LOGERR, sacq);
1139 return;
1140 }
1141 ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
1142 isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
1143 if (isp->isp_dblev & ISP_LOGDEBUG1) {
1144 isp_print_bytes(isp, "isp_init",
1145 sizeof (*icbp), fcp->isp_scratch);
1146 }
1147
1148 /*
1149 * Now fill in information about any additional channels
1150 */
1151 if (isp->isp_nchan > 1) {
1152 isp_icb_2400_vpinfo_t vpinfo, *vdst;
1153 vp_port_info_t pi, *pdst;
1154 size_t amt = 0;
1155 uint8_t *off;
1156
1157 vpinfo.vp_global_options = ICB2400_VPGOPT_GEN_RIDA;
1158 if (ISP_CAP_VP0(isp)) {
1159 vpinfo.vp_global_options |= ICB2400_VPGOPT_VP0_DECOUPLE;
1160 vpinfo.vp_count = isp->isp_nchan;
1161 chan = 0;
1162 } else {
1163 vpinfo.vp_count = isp->isp_nchan - 1;
1164 chan = 1;
1165 }
1166 off = fcp->isp_scratch;
1167 off += ICB2400_VPINFO_OFF;
1168 vdst = (isp_icb_2400_vpinfo_t *) off;
1169 isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
1170 amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
1171 for (; chan < isp->isp_nchan; chan++) {
1172 fcparam *fcp2;
1173
1174 ISP_MEMZERO(&pi, sizeof (pi));
1175 fcp2 = FCPARAM(isp, chan);
1176 if (fcp2->role != ISP_ROLE_NONE) {
1177 pi.vp_port_options = ICB2400_VPOPT_ENABLED |
1178 ICB2400_VPOPT_ENA_SNSLOGIN;
1179 if (fcp2->role & ISP_ROLE_INITIATOR)
1180 pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
1181 if ((fcp2->role & ISP_ROLE_TARGET) == 0)
1182 pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
1183 if (fcp2->isp_loopid < LOCAL_LOOP_LIM) {
1184 pi.vp_port_loopid = fcp2->isp_loopid;
1185 if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
1186 pi.vp_port_options |= ICB2400_VPOPT_HARD_ADDRESS;
1187 }
1188
1189 }
1190 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
1191 MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
1192 off = fcp->isp_scratch;
1193 if (ISP_CAP_VP0(isp))
1194 off += ICB2400_VPINFO_PORT_OFF(chan);
1195 else
1196 off += ICB2400_VPINFO_PORT_OFF(chan - 1);
1197 pdst = (vp_port_info_t *) off;
1198 isp_put_vp_port_info(isp, &pi, pdst);
1199 amt += ICB2400_VPOPT_WRITE_SIZE;
1200 }
1201 if (isp->isp_dblev & ISP_LOGDEBUG1) {
1202 isp_print_bytes(isp, "isp_init",
1203 amt - ICB2400_VPINFO_OFF,
1204 (char *)fcp->isp_scratch + ICB2400_VPINFO_OFF);
1205 }
1206 }
1207
1208 /*
1209 * Init the firmware
1210 */
1211 MBSINIT(&mbs, 0, MBLOGALL, 30000000);
1212 if (isp->isp_nchan > 1) {
1213 mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
1214 } else {
1215 mbs.param[0] = MBOX_INIT_FIRMWARE;
1216 }
1217 mbs.param[1] = 0;
1218 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1219 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1220 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1221 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1222 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));
1223 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
1224 isp_mboxcmd(isp, &mbs);
1225 FC_SCRATCH_RELEASE(isp, 0);
1226
1227 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1228 return;
1229 }
1230
1231 /*
1232 * Whatever happens, we're now committed to being here.
1233 */
1234 isp->isp_state = ISP_RUNSTATE;
1235 }
1236
1237 static int
isp_fc_enable_vp(ispsoftc_t * isp,int chan)1238 isp_fc_enable_vp(ispsoftc_t *isp, int chan)
1239 {
1240 fcparam *fcp = FCPARAM(isp, chan);
1241 vp_modify_t vp;
1242 int retval;
1243
1244 /* Build a VP MODIFY command in memory */
1245 ISP_MEMZERO(&vp, sizeof(vp));
1246 vp.vp_mod_hdr.rqs_entry_type = RQSTYPE_VP_MODIFY;
1247 vp.vp_mod_hdr.rqs_entry_count = 1;
1248 vp.vp_mod_cnt = 1;
1249 vp.vp_mod_idx0 = chan;
1250 vp.vp_mod_cmd = VP_MODIFY_ENA;
1251 vp.vp_mod_ports[0].options = ICB2400_VPOPT_ENABLED |
1252 ICB2400_VPOPT_ENA_SNSLOGIN;
1253 if (fcp->role & ISP_ROLE_INITIATOR)
1254 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_INI_ENABLE;
1255 if ((fcp->role & ISP_ROLE_TARGET) == 0)
1256 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_TGT_DISABLE;
1257 if (fcp->isp_loopid < LOCAL_LOOP_LIM) {
1258 vp.vp_mod_ports[0].loopid = fcp->isp_loopid;
1259 if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
1260 vp.vp_mod_ports[0].options |= ICB2400_VPOPT_HARD_ADDRESS;
1261 }
1262 MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwpn, fcp->isp_wwpn);
1263 MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwnn, fcp->isp_wwnn);
1264
1265 retval = isp_exec_entry_queue(isp, &vp, &vp, 5);
1266 if (retval != 0) {
1267 isp_prt(isp, ISP_LOGERR, "%s: VP_MODIFY of chan %d error %d",
1268 __func__, chan, retval);
1269 return (retval);
1270 }
1271
1272 if (vp.vp_mod_hdr.rqs_flags != 0 || vp.vp_mod_status != VP_STS_OK) {
1273 isp_prt(isp, ISP_LOGERR,
1274 "%s: VP_MODIFY of Chan %d failed with flags %x status %d",
1275 __func__, chan, vp.vp_mod_hdr.rqs_flags, vp.vp_mod_status);
1276 return (EIO);
1277 }
1278 return (0);
1279 }
1280
1281 static int
isp_fc_disable_vp(ispsoftc_t * isp,int chan)1282 isp_fc_disable_vp(ispsoftc_t *isp, int chan)
1283 {
1284 vp_ctrl_info_t vp;
1285 int retval;
1286
1287 /* Build a VP CTRL command in memory */
1288 ISP_MEMZERO(&vp, sizeof(vp));
1289 vp.vp_ctrl_hdr.rqs_entry_type = RQSTYPE_VP_CTRL;
1290 vp.vp_ctrl_hdr.rqs_entry_count = 1;
1291 if (ISP_CAP_VP0(isp)) {
1292 vp.vp_ctrl_status = 1;
1293 } else {
1294 vp.vp_ctrl_status = 0;
1295 chan--; /* VP0 can not be controlled in this case. */
1296 }
1297 vp.vp_ctrl_command = VP_CTRL_CMD_DISABLE_VP_LOGO_ALL;
1298 vp.vp_ctrl_vp_count = 1;
1299 vp.vp_ctrl_idmap[chan / 16] |= (1 << chan % 16);
1300
1301 retval = isp_exec_entry_queue(isp, &vp, &vp, 5);
1302 if (retval != 0) {
1303 isp_prt(isp, ISP_LOGERR, "%s: VP_CTRL of chan %d error %d",
1304 __func__, chan, retval);
1305 return (retval);
1306 }
1307
1308 if (vp.vp_ctrl_hdr.rqs_flags != 0 || vp.vp_ctrl_status != 0) {
1309 isp_prt(isp, ISP_LOGERR,
1310 "%s: VP_CTRL of Chan %d failed with flags %x status %d %d",
1311 __func__, chan, vp.vp_ctrl_hdr.rqs_flags,
1312 vp.vp_ctrl_status, vp.vp_ctrl_index_fail);
1313 return (EIO);
1314 }
1315 return (0);
1316 }
1317
1318 static int
isp_fc_change_role(ispsoftc_t * isp,int chan,int new_role)1319 isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
1320 {
1321 fcparam *fcp = FCPARAM(isp, chan);
1322 int i, was, res = 0;
1323
1324 if (chan >= isp->isp_nchan) {
1325 isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan);
1326 return (ENXIO);
1327 }
1328 if (fcp->role == new_role)
1329 return (0);
1330 for (was = 0, i = 0; i < isp->isp_nchan; i++) {
1331 if (FCPARAM(isp, i)->role != ISP_ROLE_NONE)
1332 was++;
1333 }
1334 if (was == 0 || (was == 1 && fcp->role != ISP_ROLE_NONE)) {
1335 fcp->role = new_role;
1336 return (isp_reinit(isp, 0));
1337 }
1338 if (fcp->role != ISP_ROLE_NONE) {
1339 res = isp_fc_disable_vp(isp, chan);
1340 isp_clear_portdb(isp, chan);
1341 }
1342 fcp->role = new_role;
1343 if (fcp->role != ISP_ROLE_NONE)
1344 res = isp_fc_enable_vp(isp, chan);
1345 return (res);
1346 }
1347
1348 static void
isp_clear_portdb(ispsoftc_t * isp,int chan)1349 isp_clear_portdb(ispsoftc_t *isp, int chan)
1350 {
1351 fcparam *fcp = FCPARAM(isp, chan);
1352 fcportdb_t *lp;
1353 int i;
1354
1355 for (i = 0; i < MAX_FC_TARG; i++) {
1356 lp = &fcp->portdb[i];
1357 switch (lp->state) {
1358 case FC_PORTDB_STATE_DEAD:
1359 case FC_PORTDB_STATE_CHANGED:
1360 case FC_PORTDB_STATE_VALID:
1361 lp->state = FC_PORTDB_STATE_NIL;
1362 isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
1363 break;
1364 case FC_PORTDB_STATE_NIL:
1365 case FC_PORTDB_STATE_NEW:
1366 lp->state = FC_PORTDB_STATE_NIL;
1367 break;
1368 case FC_PORTDB_STATE_ZOMBIE:
1369 break;
1370 default:
1371 panic("Don't know how to clear state %d\n", lp->state);
1372 }
1373 }
1374 }
1375
1376 static void
isp_mark_portdb(ispsoftc_t * isp,int chan)1377 isp_mark_portdb(ispsoftc_t *isp, int chan)
1378 {
1379 fcparam *fcp = FCPARAM(isp, chan);
1380 fcportdb_t *lp;
1381 int i;
1382
1383 for (i = 0; i < MAX_FC_TARG; i++) {
1384 lp = &fcp->portdb[i];
1385 if (lp->state == FC_PORTDB_STATE_NIL)
1386 continue;
1387 if (lp->portid >= DOMAIN_CONTROLLER_BASE &&
1388 lp->portid <= DOMAIN_CONTROLLER_END)
1389 continue;
1390 fcp->portdb[i].probational = 1;
1391 }
1392 }
1393
1394 /*
1395 * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
1396 * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
1397 */
1398 static int
isp_plogx(ispsoftc_t * isp,int chan,uint16_t handle,uint32_t portid,int flags)1399 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags)
1400 {
1401 isp_plogx_t pl;
1402 uint32_t sst, parm1;
1403 int retval, lev;
1404 const char *msg;
1405 char buf[64];
1406
1407 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d PLOGX %s PortID 0x%06x nphdl 0x%x",
1408 chan, (flags & PLOGX_FLG_CMD_MASK) == PLOGX_FLG_CMD_PLOGI ?
1409 "Login":"Logout", portid, handle);
1410
1411 ISP_MEMZERO(&pl, sizeof(pl));
1412 pl.plogx_header.rqs_entry_count = 1;
1413 pl.plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
1414 pl.plogx_nphdl = handle;
1415 pl.plogx_vphdl = chan;
1416 pl.plogx_portlo = portid;
1417 pl.plogx_rspsz_porthi = (portid >> 16) & 0xff;
1418 pl.plogx_flags = flags;
1419
1420 retval = isp_exec_entry_queue(isp, &pl, &pl, 3 * ICB_LOGIN_TOV);
1421 if (retval != 0) {
1422 isp_prt(isp, ISP_LOGERR, "%s: PLOGX of chan %d error %d",
1423 __func__, chan, retval);
1424 return (retval);
1425 }
1426
1427 if (pl.plogx_status == PLOGX_STATUS_OK) {
1428 return (0);
1429 } else if (pl.plogx_status != PLOGX_STATUS_IOCBERR) {
1430 isp_prt(isp, ISP_LOGWARN,
1431 "status 0x%x on port login IOCB channel %d",
1432 pl.plogx_status, chan);
1433 return (-1);
1434 }
1435
1436 sst = pl.plogx_ioparm[0].lo16 | (pl.plogx_ioparm[0].hi16 << 16);
1437 parm1 = pl.plogx_ioparm[1].lo16 | (pl.plogx_ioparm[1].hi16 << 16);
1438
1439 retval = -1;
1440 lev = ISP_LOGERR;
1441 msg = NULL;
1442
1443 switch (sst) {
1444 case PLOGX_IOCBERR_NOLINK:
1445 msg = "no link";
1446 break;
1447 case PLOGX_IOCBERR_NOIOCB:
1448 msg = "no IOCB buffer";
1449 break;
1450 case PLOGX_IOCBERR_NOXGHG:
1451 msg = "no Exchange Control Block";
1452 break;
1453 case PLOGX_IOCBERR_FAILED:
1454 ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
1455 msg = buf;
1456 break;
1457 case PLOGX_IOCBERR_NOFABRIC:
1458 msg = "no fabric";
1459 break;
1460 case PLOGX_IOCBERR_NOTREADY:
1461 msg = "firmware not ready";
1462 break;
1463 case PLOGX_IOCBERR_NOLOGIN:
1464 ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
1465 msg = buf;
1466 retval = MBOX_NOT_LOGGED_IN;
1467 break;
1468 case PLOGX_IOCBERR_REJECT:
1469 ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
1470 msg = buf;
1471 break;
1472 case PLOGX_IOCBERR_NOPCB:
1473 msg = "no PCB allocated";
1474 break;
1475 case PLOGX_IOCBERR_EINVAL:
1476 ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
1477 msg = buf;
1478 break;
1479 case PLOGX_IOCBERR_PORTUSED:
1480 lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
1481 ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
1482 msg = buf;
1483 retval = MBOX_PORT_ID_USED | (parm1 << 16);
1484 break;
1485 case PLOGX_IOCBERR_HNDLUSED:
1486 lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
1487 ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
1488 msg = buf;
1489 retval = MBOX_LOOP_ID_USED;
1490 break;
1491 case PLOGX_IOCBERR_NOHANDLE:
1492 msg = "no handle allocated";
1493 break;
1494 case PLOGX_IOCBERR_NOFLOGI:
1495 msg = "no FLOGI_ACC";
1496 break;
1497 default:
1498 ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", pl.plogx_status, flags);
1499 msg = buf;
1500 break;
1501 }
1502 if (msg) {
1503 isp_prt(isp, lev, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
1504 chan, portid, handle, msg);
1505 }
1506 return (retval);
1507 }
1508
1509 static int
isp_getpdb(ispsoftc_t * isp,int chan,uint16_t id,isp_pdb_t * pdb)1510 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb)
1511 {
1512 mbreg_t mbs;
1513 union {
1514 isp_pdb_24xx_t bill;
1515 } un;
1516
1517 MBSINIT(&mbs, MBOX_GET_PORT_DB,
1518 MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 250000);
1519 mbs.ibits = (1 << 9)|(1 << 10);
1520 mbs.param[1] = id;
1521 mbs.param[2] = DMA_WD1(isp->isp_iocb_dma);
1522 mbs.param[3] = DMA_WD0(isp->isp_iocb_dma);
1523 mbs.param[6] = DMA_WD3(isp->isp_iocb_dma);
1524 mbs.param[7] = DMA_WD2(isp->isp_iocb_dma);
1525 mbs.param[9] = chan;
1526 MEMORYBARRIER(isp, SYNC_IFORDEV, 0, sizeof(un), chan);
1527
1528 isp_mboxcmd(isp, &mbs);
1529 if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
1530 return (mbs.param[0] | (mbs.param[1] << 16));
1531
1532 MEMORYBARRIER(isp, SYNC_IFORCPU, 0, sizeof(un), chan);
1533 isp_get_pdb_24xx(isp, isp->isp_iocb, &un.bill);
1534 pdb->handle = un.bill.pdb_handle;
1535 pdb->prli_word0 = un.bill.pdb_prli_svc0;
1536 pdb->prli_word3 = un.bill.pdb_prli_svc3;
1537 pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
1538 ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
1539 ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
1540 isp_prt(isp, ISP_LOGDEBUG0,
1541 "Chan %d handle 0x%x Port 0x%06x flags 0x%x curstate %x laststate %x",
1542 chan, id, pdb->portid, un.bill.pdb_flags,
1543 un.bill.pdb_curstate, un.bill.pdb_laststate);
1544
1545 /*
1546 * XXX KDM this is broken for NVMe. Need to determine whether this
1547 * is an NVMe target, and if so, check the NVMe status bits. We are
1548 * probably missing more bits for proper NVMe support, though.
1549 */
1550 if (((un.bill.pdb_curstate & PDB2400_STATE_FCP_MASK) <
1551 PDB2400_STATE_PLOGI_DONE)
1552 || ((un.bill.pdb_curstate & PDB2400_STATE_FCP_MASK) >
1553 PDB2400_STATE_LOGGED_IN)) {
1554 mbs.param[0] = MBOX_NOT_LOGGED_IN;
1555 return (mbs.param[0]);
1556 }
1557 return (0);
1558 }
1559
1560 static int
isp_gethandles(ispsoftc_t * isp,int chan,uint16_t * handles,int * num,int loop)1561 isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num, int loop)
1562 {
1563 fcparam *fcp = FCPARAM(isp, chan);
1564 mbreg_t mbs;
1565 isp_pnhle_24xx_t el4, *elp4;
1566 int i, j;
1567 uint32_t p;
1568
1569 MBSINIT(&mbs, MBOX_GET_ID_LIST, MBLOGALL, 250000);
1570 mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1571 mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1572 mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1573 mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1574 mbs.param[8] = ISP_FC_SCRLEN;
1575 mbs.param[9] = chan;
1576 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
1577 isp_prt(isp, ISP_LOGERR, sacq);
1578 return (-1);
1579 }
1580 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, ISP_FC_SCRLEN, chan);
1581 isp_mboxcmd(isp, &mbs);
1582 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1583 FC_SCRATCH_RELEASE(isp, chan);
1584 return (mbs.param[0] | (mbs.param[1] << 16));
1585 }
1586 MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan);
1587 elp4 = fcp->isp_scratch;
1588 for (i = 0, j = 0; i < mbs.param[1] && j < *num; i++) {
1589 isp_get_pnhle_24xx(isp, &elp4[i], &el4);
1590 p = el4.pnhle_port_id_lo | (el4.pnhle_port_id_hi << 16);
1591 if (loop && (p >> 8) != (fcp->isp_portid >> 8))
1592 continue;
1593 handles[j++] = el4.pnhle_handle;
1594 }
1595 *num = j;
1596 FC_SCRATCH_RELEASE(isp, chan);
1597 return (0);
1598 }
1599
1600 static void
isp_dump_chip_portdb(ispsoftc_t * isp,int chan)1601 isp_dump_chip_portdb(ispsoftc_t *isp, int chan)
1602 {
1603 isp_pdb_t pdb;
1604 uint16_t nphdl;
1605
1606 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d chip port dump", chan);
1607 for (nphdl = 0; nphdl != NPH_MAX_2K; nphdl++) {
1608 if (isp_getpdb(isp, chan, nphdl, &pdb)) {
1609 continue;
1610 }
1611 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d Handle 0x%04x "
1612 "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
1613 chan, nphdl, pdb.portid, pdb.portname[0], pdb.portname[1],
1614 pdb.portname[2], pdb.portname[3], pdb.portname[4],
1615 pdb.portname[5], pdb.portname[6], pdb.portname[7]);
1616 }
1617 }
1618
1619 static uint64_t
isp_get_wwn(ispsoftc_t * isp,int chan,int nphdl,int nodename)1620 isp_get_wwn(ispsoftc_t *isp, int chan, int nphdl, int nodename)
1621 {
1622 uint64_t wwn = INI_NONE;
1623 mbreg_t mbs;
1624
1625 MBSINIT(&mbs, MBOX_GET_PORT_NAME,
1626 MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 500000);
1627 mbs.param[1] = nphdl;
1628 if (nodename)
1629 mbs.param[10] = 1;
1630 mbs.param[9] = chan;
1631 isp_mboxcmd(isp, &mbs);
1632 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1633 return (wwn);
1634 }
1635 wwn = (((uint64_t)(mbs.param[2] >> 8)) << 56) |
1636 (((uint64_t)(mbs.param[2] & 0xff))<< 48) |
1637 (((uint64_t)(mbs.param[3] >> 8)) << 40) |
1638 (((uint64_t)(mbs.param[3] & 0xff))<< 32) |
1639 (((uint64_t)(mbs.param[6] >> 8)) << 24) |
1640 (((uint64_t)(mbs.param[6] & 0xff))<< 16) |
1641 (((uint64_t)(mbs.param[7] >> 8)) << 8) |
1642 (((uint64_t)(mbs.param[7] & 0xff)));
1643 return (wwn);
1644 }
1645
1646 /*
1647 * Make sure we have good FC link.
1648 */
1649
1650 static int
isp_fclink_test(ispsoftc_t * isp,int chan,int usdelay)1651 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
1652 {
1653 mbreg_t mbs;
1654 int i, r, topo;
1655 fcparam *fcp;
1656 isp_pdb_t pdb;
1657 NANOTIME_T hra, hrb;
1658
1659 fcp = FCPARAM(isp, chan);
1660
1661 if (fcp->isp_loopstate < LOOP_HAVE_LINK)
1662 return (-1);
1663 if (fcp->isp_loopstate >= LOOP_LTEST_DONE)
1664 return (0);
1665
1666 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test", chan);
1667
1668 /*
1669 * Wait up to N microseconds for F/W to go to a ready state.
1670 */
1671 GET_NANOTIME(&hra);
1672 while (1) {
1673 isp_change_fw_state(isp, chan, isp_fw_state(isp, chan));
1674 if (fcp->isp_fwstate == FW_READY) {
1675 break;
1676 }
1677 if (fcp->isp_loopstate < LOOP_HAVE_LINK)
1678 goto abort;
1679 GET_NANOTIME(&hrb);
1680 if ((NANOTIME_SUB(&hrb, &hra) / 1000 + 1000 >= usdelay))
1681 break;
1682 ISP_SLEEP(isp, 1000);
1683 }
1684 if (fcp->isp_fwstate != FW_READY) {
1685 isp_prt(isp, ISP_LOG_SANCFG,
1686 "Chan %d Firmware is not ready (%s)",
1687 chan, isp_fc_fw_statename(fcp->isp_fwstate));
1688 return (-1);
1689 }
1690
1691 /*
1692 * Get our Loop ID and Port ID.
1693 */
1694 MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
1695 mbs.param[9] = chan;
1696 isp_mboxcmd(isp, &mbs);
1697 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1698 return (-1);
1699 }
1700
1701 topo = (int) mbs.param[6];
1702 if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
1703 topo = TOPO_PTP_STUB;
1704 fcp->isp_topo = topo;
1705 fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
1706
1707 if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
1708 fcp->isp_loopid = mbs.param[1] & 0xff;
1709 } else if (fcp->isp_topo != TOPO_F_PORT) {
1710 uint8_t alpa = fcp->isp_portid;
1711
1712 for (i = 0; alpa_map[i]; i++) {
1713 if (alpa_map[i] == alpa)
1714 break;
1715 }
1716 if (alpa_map[i])
1717 fcp->isp_loopid = i;
1718 }
1719
1720 #if 0
1721 fcp->isp_loopstate = LOOP_HAVE_ADDR;
1722 #endif
1723 fcp->isp_loopstate = LOOP_TESTING_LINK;
1724
1725 if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
1726 r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb);
1727 if (r != 0 || pdb.portid == 0) {
1728 isp_prt(isp, ISP_LOGWARN,
1729 "fabric topology, but cannot get info about fabric controller (0x%x)", r);
1730 fcp->isp_topo = TOPO_PTP_STUB;
1731 goto not_on_fabric;
1732 }
1733
1734 fcp->isp_fabric_params = mbs.param[7];
1735 fcp->isp_sns_hdl = NPH_SNS_ID;
1736 r = isp_register_fc4_type(isp, chan);
1737 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1738 goto abort;
1739 if (r != 0)
1740 goto not_on_fabric;
1741 r = isp_register_fc4_features_24xx(isp, chan);
1742 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1743 goto abort;
1744 if (r != 0)
1745 goto not_on_fabric;
1746 r = isp_register_port_name_24xx(isp, chan);
1747 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1748 goto abort;
1749 if (r != 0)
1750 goto not_on_fabric;
1751 isp_register_node_name_24xx(isp, chan);
1752 if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1753 goto abort;
1754 }
1755
1756 not_on_fabric:
1757 /* Get link speed. */
1758 fcp->isp_gbspeed = 1;
1759 MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
1760 mbs.param[1] = MBGSD_GET_RATE;
1761 /* mbs.param[2] undefined if we're just getting rate */
1762 isp_mboxcmd(isp, &mbs);
1763 if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1764 if (mbs.param[1] == MBGSD_10GB)
1765 fcp->isp_gbspeed = 10;
1766 else if (mbs.param[1] == MBGSD_64GB)
1767 fcp->isp_gbspeed = 64;
1768 else if (mbs.param[1] == MBGSD_32GB)
1769 fcp->isp_gbspeed = 32;
1770 else if (mbs.param[1] == MBGSD_16GB)
1771 fcp->isp_gbspeed = 16;
1772 else if (mbs.param[1] == MBGSD_8GB)
1773 fcp->isp_gbspeed = 8;
1774 else if (mbs.param[1] == MBGSD_4GB)
1775 fcp->isp_gbspeed = 4;
1776 else if (mbs.param[1] == MBGSD_2GB)
1777 fcp->isp_gbspeed = 2;
1778 else if (mbs.param[1] == MBGSD_1GB)
1779 fcp->isp_gbspeed = 1;
1780 }
1781
1782 if (fcp->isp_loopstate < LOOP_TESTING_LINK) {
1783 abort:
1784 isp_prt(isp, ISP_LOG_SANCFG,
1785 "Chan %d FC link test aborted", chan);
1786 return (1);
1787 }
1788 fcp->isp_loopstate = LOOP_LTEST_DONE;
1789 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
1790 "Chan %d WWPN %016jx WWNN %016jx",
1791 chan, (uintmax_t)fcp->isp_wwpn, (uintmax_t)fcp->isp_wwnn);
1792 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
1793 "Chan %d %dGb %s PortID 0x%06x LoopID 0x%02x",
1794 chan, fcp->isp_gbspeed, isp_fc_toponame(fcp), fcp->isp_portid,
1795 fcp->isp_loopid);
1796 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test done", chan);
1797 return (0);
1798 }
1799
1800 /*
1801 * Complete the synchronization of our Port Database.
1802 *
1803 * At this point, we've scanned the local loop (if any) and the fabric
1804 * and performed fabric logins on all new devices.
1805 *
1806 * Our task here is to go through our port database removing any entities
1807 * that are still marked probational (issuing PLOGO for ones which we had
1808 * PLOGI'd into) or are dead, and notifying upper layers about new/changed
1809 * devices.
1810 */
1811 static int
isp_pdb_sync(ispsoftc_t * isp,int chan)1812 isp_pdb_sync(ispsoftc_t *isp, int chan)
1813 {
1814 fcparam *fcp = FCPARAM(isp, chan);
1815 fcportdb_t *lp;
1816 uint16_t dbidx;
1817
1818 if (fcp->isp_loopstate < LOOP_FSCAN_DONE)
1819 return (-1);
1820 if (fcp->isp_loopstate >= LOOP_READY)
1821 return (0);
1822
1823 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync", chan);
1824
1825 fcp->isp_loopstate = LOOP_SYNCING_PDB;
1826
1827 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
1828 lp = &fcp->portdb[dbidx];
1829
1830 if (lp->state == FC_PORTDB_STATE_NIL)
1831 continue;
1832 if (lp->probational && lp->state != FC_PORTDB_STATE_ZOMBIE)
1833 lp->state = FC_PORTDB_STATE_DEAD;
1834 switch (lp->state) {
1835 case FC_PORTDB_STATE_DEAD:
1836 lp->state = FC_PORTDB_STATE_NIL;
1837 isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
1838 if ((lp->portid & 0xffff00) != 0) {
1839 (void) isp_plogx(isp, chan, lp->handle,
1840 lp->portid,
1841 PLOGX_FLG_CMD_LOGO |
1842 PLOGX_FLG_IMPLICIT |
1843 PLOGX_FLG_FREE_NPHDL);
1844 }
1845 /*
1846 * Note that we might come out of this with our state
1847 * set to FC_PORTDB_STATE_ZOMBIE.
1848 */
1849 break;
1850 case FC_PORTDB_STATE_NEW:
1851 lp->state = FC_PORTDB_STATE_VALID;
1852 isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
1853 break;
1854 case FC_PORTDB_STATE_CHANGED:
1855 lp->state = FC_PORTDB_STATE_VALID;
1856 isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
1857 lp->portid = lp->new_portid;
1858 lp->prli_word0 = lp->new_prli_word0;
1859 lp->prli_word3 = lp->new_prli_word3;
1860 break;
1861 case FC_PORTDB_STATE_VALID:
1862 isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
1863 break;
1864 case FC_PORTDB_STATE_ZOMBIE:
1865 break;
1866 default:
1867 isp_prt(isp, ISP_LOGWARN,
1868 "isp_pdb_sync: state %d for idx %d",
1869 lp->state, dbidx);
1870 isp_dump_portdb(isp, chan);
1871 }
1872 }
1873
1874 if (fcp->isp_loopstate < LOOP_SYNCING_PDB) {
1875 isp_prt(isp, ISP_LOG_SANCFG,
1876 "Chan %d FC PDB sync aborted", chan);
1877 return (1);
1878 }
1879
1880 fcp->isp_loopstate = LOOP_READY;
1881 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync done", chan);
1882 return (0);
1883 }
1884
1885 static void
isp_pdb_add_update(ispsoftc_t * isp,int chan,isp_pdb_t * pdb)1886 isp_pdb_add_update(ispsoftc_t *isp, int chan, isp_pdb_t *pdb)
1887 {
1888 fcportdb_t *lp;
1889 uint64_t wwnn, wwpn;
1890
1891 MAKE_WWN_FROM_NODE_NAME(wwnn, pdb->nodename);
1892 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb->portname);
1893
1894 /* Search port database for the same WWPN. */
1895 if (isp_find_pdb_by_wwpn(isp, chan, wwpn, &lp)) {
1896 if (!lp->probational) {
1897 isp_prt(isp, ISP_LOGERR,
1898 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
1899 chan, lp->portid, lp->handle,
1900 FC_PORTDB_TGT(isp, chan, lp), lp->state);
1901 isp_dump_portdb(isp, chan);
1902 return;
1903 }
1904 lp->probational = 0;
1905 lp->node_wwn = wwnn;
1906
1907 /* Old device, nothing new. */
1908 if (lp->portid == pdb->portid &&
1909 lp->handle == pdb->handle &&
1910 lp->prli_word3 == pdb->prli_word3 &&
1911 ((pdb->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR) ==
1912 (lp->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR))) {
1913 if (lp->state != FC_PORTDB_STATE_NEW)
1914 lp->state = FC_PORTDB_STATE_VALID;
1915 isp_prt(isp, ISP_LOG_SANCFG,
1916 "Chan %d Port 0x%06x@0x%04x is valid",
1917 chan, pdb->portid, pdb->handle);
1918 return;
1919 }
1920
1921 /* Something has changed. */
1922 lp->state = FC_PORTDB_STATE_CHANGED;
1923 lp->handle = pdb->handle;
1924 lp->new_portid = pdb->portid;
1925 lp->new_prli_word0 = pdb->prli_word0;
1926 lp->new_prli_word3 = pdb->prli_word3;
1927 isp_prt(isp, ISP_LOG_SANCFG,
1928 "Chan %d Port 0x%06x@0x%04x is changed",
1929 chan, pdb->portid, pdb->handle);
1930 return;
1931 }
1932
1933 /* It seems like a new port. Find an empty slot for it. */
1934 if (!isp_find_pdb_empty(isp, chan, &lp)) {
1935 isp_prt(isp, ISP_LOGERR, "Chan %d out of portdb entries", chan);
1936 return;
1937 }
1938
1939 ISP_MEMZERO(lp, sizeof (fcportdb_t));
1940 lp->probational = 0;
1941 lp->state = FC_PORTDB_STATE_NEW;
1942 lp->portid = lp->new_portid = pdb->portid;
1943 lp->prli_word0 = lp->new_prli_word0 = pdb->prli_word0;
1944 lp->prli_word3 = lp->new_prli_word3 = pdb->prli_word3;
1945 lp->handle = pdb->handle;
1946 lp->port_wwn = wwpn;
1947 lp->node_wwn = wwnn;
1948 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x@0x%04x is new",
1949 chan, pdb->portid, pdb->handle);
1950 }
1951
1952 /*
1953 * Scan local loop for devices.
1954 */
1955 static int
isp_scan_loop(ispsoftc_t * isp,int chan)1956 isp_scan_loop(ispsoftc_t *isp, int chan)
1957 {
1958 fcparam *fcp = FCPARAM(isp, chan);
1959 int idx, lim, r;
1960 isp_pdb_t pdb;
1961 uint16_t *handles;
1962 uint16_t handle;
1963
1964 if (fcp->isp_loopstate < LOOP_LTEST_DONE)
1965 return (-1);
1966 if (fcp->isp_loopstate >= LOOP_LSCAN_DONE)
1967 return (0);
1968
1969 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan);
1970 fcp->isp_loopstate = LOOP_SCANNING_LOOP;
1971 if (TOPO_IS_FABRIC(fcp->isp_topo)) {
1972 isp_prt(isp, ISP_LOG_SANCFG,
1973 "Chan %d FC loop scan done (no loop)", chan);
1974 fcp->isp_loopstate = LOOP_LSCAN_DONE;
1975 return (0);
1976 }
1977
1978 handles = (uint16_t *)fcp->isp_scanscratch;
1979 lim = ISP_FC_SCRLEN / 2;
1980 r = isp_gethandles(isp, chan, handles, &lim, 1);
1981 if (r != 0) {
1982 isp_prt(isp, ISP_LOG_SANCFG,
1983 "Chan %d Getting list of handles failed with %x", chan, r);
1984 isp_prt(isp, ISP_LOG_SANCFG,
1985 "Chan %d FC loop scan done (bad)", chan);
1986 return (-1);
1987 }
1988
1989 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Got %d handles",
1990 chan, lim);
1991
1992 /*
1993 * Run through the list and get the port database info for each one.
1994 */
1995 isp_mark_portdb(isp, chan);
1996 for (idx = 0; idx < lim; idx++) {
1997 handle = handles[idx];
1998
1999 /*
2000 * Don't scan "special" ids.
2001 */
2002 if (handle >= NPH_RESERVED)
2003 continue;
2004
2005 /*
2006 * Get the port database entity for this index.
2007 */
2008 r = isp_getpdb(isp, chan, handle, &pdb);
2009 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2010 abort:
2011 isp_prt(isp, ISP_LOG_SANCFG,
2012 "Chan %d FC loop scan aborted", chan);
2013 return (1);
2014 }
2015 if (r != 0) {
2016 isp_prt(isp, ISP_LOGDEBUG1,
2017 "Chan %d FC Scan Loop handle %d returned %x",
2018 chan, handle, r);
2019 continue;
2020 }
2021
2022 isp_pdb_add_update(isp, chan, &pdb);
2023 }
2024 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2025 goto abort;
2026 fcp->isp_loopstate = LOOP_LSCAN_DONE;
2027 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan done", chan);
2028 return (0);
2029 }
2030
2031 static int
isp_ct_passthru(ispsoftc_t * isp,int chan,uint32_t cmd_bcnt,uint32_t rsp_bcnt)2032 isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt)
2033 {
2034 fcparam *fcp = FCPARAM(isp, chan);
2035 isp_ct_pt_t pt;
2036 int retval;
2037
2038 if (isp->isp_dblev & ISP_LOGDEBUG1)
2039 isp_print_bytes(isp, "CT request", cmd_bcnt, fcp->isp_scratch);
2040
2041 /*
2042 * Build a Passthrough IOCB in memory.
2043 */
2044 ISP_MEMZERO(&pt, sizeof(pt));
2045 pt.ctp_header.rqs_entry_count = 1;
2046 pt.ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
2047 pt.ctp_nphdl = fcp->isp_sns_hdl;
2048 pt.ctp_cmd_cnt = 1;
2049 pt.ctp_vpidx = ISP_GET_VPIDX(isp, chan);
2050 pt.ctp_time = 10;
2051 pt.ctp_rsp_cnt = 1;
2052 pt.ctp_rsp_bcnt = rsp_bcnt;
2053 pt.ctp_cmd_bcnt = cmd_bcnt;
2054 pt.ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma);
2055 pt.ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma);
2056 pt.ctp_dataseg[0].ds_count = cmd_bcnt;
2057 pt.ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma);
2058 pt.ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma);
2059 pt.ctp_dataseg[1].ds_count = rsp_bcnt;
2060
2061 retval = isp_exec_entry_queue(isp, &pt, &pt, 2 * pt.ctp_time);
2062 if (retval != 0) {
2063 isp_prt(isp, ISP_LOGERR, "%s: CTP of chan %d error %d",
2064 __func__, chan, retval);
2065 return (retval);
2066 }
2067
2068 if (pt.ctp_status && pt.ctp_status != RQCS_DATA_UNDERRUN) {
2069 isp_prt(isp, ISP_LOGWARN,
2070 "Chan %d CT pass-through returned 0x%x",
2071 chan, pt.ctp_status);
2072 return (-1);
2073 }
2074
2075 if (isp->isp_dblev & ISP_LOGDEBUG1)
2076 isp_print_bytes(isp, "CT response", rsp_bcnt, fcp->isp_scratch);
2077
2078 return (0);
2079 }
2080
2081 /*
2082 * Scan the fabric for devices and add them to our port database.
2083 *
2084 * Use the GID_PT command to get list of all Nx_Port IDs SNS knows.
2085 * Use GFF_ID and GFT_ID to check port type (FCP) and features (target).
2086 *
2087 * We use CT Pass-through IOCB.
2088 */
2089 #define GIDLEN ISP_FC_SCRLEN
2090 #define NGENT ((GIDLEN - 16) >> 2)
2091
2092 static int
isp_gid_pt(ispsoftc_t * isp,int chan)2093 isp_gid_pt(ispsoftc_t *isp, int chan)
2094 {
2095 fcparam *fcp = FCPARAM(isp, chan);
2096 ct_hdr_t ct;
2097 uint8_t *scp = fcp->isp_scratch;
2098
2099 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_PT", chan);
2100 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2101 isp_prt(isp, ISP_LOGERR, sacq);
2102 return (-1);
2103 }
2104
2105 /* Build the CT command and execute via pass-through. */
2106 ISP_MEMZERO(&ct, sizeof (ct));
2107 ct.ct_revision = CT_REVISION;
2108 ct.ct_fcs_type = CT_FC_TYPE_FC;
2109 ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2110 ct.ct_cmd_resp = SNS_GID_PT;
2111 ct.ct_bcnt_resid = (GIDLEN - 16) >> 2;
2112 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
2113 scp[sizeof(ct)] = 0x7f; /* Port Type = Nx_Port */
2114 scp[sizeof(ct)+1] = 0; /* Domain_ID = any */
2115 scp[sizeof(ct)+2] = 0; /* Area_ID = any */
2116 scp[sizeof(ct)+3] = 0; /* Flags = no Area_ID */
2117
2118 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) {
2119 FC_SCRATCH_RELEASE(isp, chan);
2120 return (-1);
2121 }
2122
2123 isp_get_gid_xx_response(isp, (sns_gid_xx_rsp_t *)scp,
2124 (sns_gid_xx_rsp_t *)fcp->isp_scanscratch, NGENT);
2125 FC_SCRATCH_RELEASE(isp, chan);
2126 return (0);
2127 }
2128
2129 static int
isp_gff_id(ispsoftc_t * isp,int chan,uint32_t portid)2130 isp_gff_id(ispsoftc_t *isp, int chan, uint32_t portid)
2131 {
2132 fcparam *fcp = FCPARAM(isp, chan);
2133 ct_hdr_t ct;
2134 uint32_t *rp;
2135 uint8_t *scp = fcp->isp_scratch;
2136 sns_gff_id_rsp_t rsp;
2137 int i, res = -1;
2138
2139 if (!fcp->isp_use_gff_id) /* User may block GFF_ID use. */
2140 return (res);
2141
2142 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFF_ID", chan);
2143 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2144 isp_prt(isp, ISP_LOGERR, sacq);
2145 return (res);
2146 }
2147
2148 /* Build the CT command and execute via pass-through. */
2149 ISP_MEMZERO(&ct, sizeof (ct));
2150 ct.ct_revision = CT_REVISION;
2151 ct.ct_fcs_type = CT_FC_TYPE_FC;
2152 ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2153 ct.ct_cmd_resp = SNS_GFF_ID;
2154 ct.ct_bcnt_resid = (SNS_GFF_ID_RESP_SIZE - sizeof(ct)) / 4;
2155 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
2156 rp = (uint32_t *) &scp[sizeof(ct)];
2157 ISP_IOZPUT_32(isp, portid, rp);
2158
2159 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t),
2160 SNS_GFF_ID_RESP_SIZE)) {
2161 FC_SCRATCH_RELEASE(isp, chan);
2162 return (res);
2163 }
2164
2165 isp_get_gff_id_response(isp, (sns_gff_id_rsp_t *)scp, &rsp);
2166 if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) {
2167 for (i = 0; i < 32; i++) {
2168 if (rsp.snscb_fc4_features[i] != 0) {
2169 res = 0;
2170 break;
2171 }
2172 }
2173 if (((rsp.snscb_fc4_features[FC4_SCSI / 8] >>
2174 ((FC4_SCSI % 8) * 4)) & 0x01) != 0)
2175 res = 1;
2176 /* Workaround for broken Brocade firmware. */
2177 if (((ISP_SWAP32(isp, rsp.snscb_fc4_features[FC4_SCSI / 8]) >>
2178 ((FC4_SCSI % 8) * 4)) & 0x01) != 0)
2179 res = 1;
2180 }
2181 FC_SCRATCH_RELEASE(isp, chan);
2182 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFF_ID result is %d", chan, res);
2183 return (res);
2184 }
2185
2186 static int
isp_gft_id(ispsoftc_t * isp,int chan,uint32_t portid)2187 isp_gft_id(ispsoftc_t *isp, int chan, uint32_t portid)
2188 {
2189 fcparam *fcp = FCPARAM(isp, chan);
2190 ct_hdr_t ct;
2191 uint32_t *rp;
2192 uint8_t *scp = fcp->isp_scratch;
2193 sns_gft_id_rsp_t rsp;
2194 int i, res = -1;
2195
2196 if (!fcp->isp_use_gft_id) /* User may block GFT_ID use. */
2197 return (res);
2198
2199 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFT_ID", chan);
2200 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2201 isp_prt(isp, ISP_LOGERR, sacq);
2202 return (res);
2203 }
2204
2205 /* Build the CT command and execute via pass-through. */
2206 ISP_MEMZERO(&ct, sizeof (ct));
2207 ct.ct_revision = CT_REVISION;
2208 ct.ct_fcs_type = CT_FC_TYPE_FC;
2209 ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2210 ct.ct_cmd_resp = SNS_GFT_ID;
2211 ct.ct_bcnt_resid = (SNS_GFT_ID_RESP_SIZE - sizeof(ct)) / 4;
2212 isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
2213 rp = (uint32_t *) &scp[sizeof(ct)];
2214 ISP_IOZPUT_32(isp, portid, rp);
2215
2216 if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t),
2217 SNS_GFT_ID_RESP_SIZE)) {
2218 FC_SCRATCH_RELEASE(isp, chan);
2219 return (res);
2220 }
2221
2222 isp_get_gft_id_response(isp, (sns_gft_id_rsp_t *)scp, &rsp);
2223 if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) {
2224 for (i = 0; i < 8; i++) {
2225 if (rsp.snscb_fc4_types[i] != 0) {
2226 res = 0;
2227 break;
2228 }
2229 }
2230 if (((rsp.snscb_fc4_types[FC4_SCSI / 32] >>
2231 (FC4_SCSI % 32)) & 0x01) != 0)
2232 res = 1;
2233 }
2234 FC_SCRATCH_RELEASE(isp, chan);
2235 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFT_ID result is %d", chan, res);
2236 return (res);
2237 }
2238
2239 static int
isp_scan_fabric(ispsoftc_t * isp,int chan)2240 isp_scan_fabric(ispsoftc_t *isp, int chan)
2241 {
2242 fcparam *fcp = FCPARAM(isp, chan);
2243 fcportdb_t *lp;
2244 uint32_t portid;
2245 isp_pdb_t pdb;
2246 int portidx, portlim, r;
2247 sns_gid_xx_rsp_t *rs;
2248
2249 if (fcp->isp_loopstate < LOOP_LSCAN_DONE)
2250 return (-1);
2251 if (fcp->isp_loopstate >= LOOP_FSCAN_DONE)
2252 return (0);
2253
2254 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan);
2255 fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2256 if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
2257 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2258 isp_prt(isp, ISP_LOG_SANCFG,
2259 "Chan %d FC fabric scan done (no fabric)", chan);
2260 return (0);
2261 }
2262
2263 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
2264 abort:
2265 FC_SCRATCH_RELEASE(isp, chan);
2266 isp_prt(isp, ISP_LOG_SANCFG,
2267 "Chan %d FC fabric scan aborted", chan);
2268 return (1);
2269 }
2270
2271 /*
2272 * Make sure we still are logged into the fabric controller.
2273 */
2274 r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb);
2275 if ((r & 0xffff) == MBOX_NOT_LOGGED_IN) {
2276 isp_dump_chip_portdb(isp, chan);
2277 }
2278 if (r) {
2279 fcp->isp_loopstate = LOOP_LTEST_DONE;
2280 fail:
2281 isp_prt(isp, ISP_LOG_SANCFG,
2282 "Chan %d FC fabric scan done (bad)", chan);
2283 return (-1);
2284 }
2285
2286 /* Get list of port IDs from SNS. */
2287 r = isp_gid_pt(isp, chan);
2288 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2289 goto abort;
2290 if (r > 0) {
2291 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2292 return (-1);
2293 } else if (r < 0) {
2294 fcp->isp_loopstate = LOOP_LTEST_DONE; /* try again */
2295 return (-1);
2296 }
2297
2298 rs = (sns_gid_xx_rsp_t *) fcp->isp_scanscratch;
2299 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2300 goto abort;
2301 if (rs->snscb_cthdr.ct_cmd_resp != LS_ACC) {
2302 int level;
2303 /* FC-4 Type and Port Type not registered are not errors. */
2304 if (rs->snscb_cthdr.ct_reason == 9 &&
2305 (rs->snscb_cthdr.ct_explanation == 0x07 ||
2306 rs->snscb_cthdr.ct_explanation == 0x0a)) {
2307 level = ISP_LOG_SANCFG;
2308 } else {
2309 level = ISP_LOGWARN;
2310 }
2311 isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_PT"
2312 " (Reason=0x%x Expl=0x%x)", chan,
2313 rs->snscb_cthdr.ct_reason,
2314 rs->snscb_cthdr.ct_explanation);
2315 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2316 return (-1);
2317 }
2318
2319 /* Check our buffer was big enough to get the full list. */
2320 for (portidx = 0; portidx < NGENT-1; portidx++) {
2321 if (rs->snscb_ports[portidx].control & 0x80)
2322 break;
2323 }
2324 if ((rs->snscb_ports[portidx].control & 0x80) == 0) {
2325 isp_prt(isp, ISP_LOGWARN,
2326 "fabric too big for scratch area: increase ISP_FC_SCRLEN");
2327 }
2328 portlim = portidx + 1;
2329 isp_prt(isp, ISP_LOG_SANCFG,
2330 "Chan %d Got %d ports back from name server", chan, portlim);
2331
2332 /* Go through the list and remove duplicate port ids. */
2333 for (portidx = 0; portidx < portlim; portidx++) {
2334 int npidx;
2335
2336 portid =
2337 ((rs->snscb_ports[portidx].portid[0]) << 16) |
2338 ((rs->snscb_ports[portidx].portid[1]) << 8) |
2339 ((rs->snscb_ports[portidx].portid[2]));
2340
2341 for (npidx = portidx + 1; npidx < portlim; npidx++) {
2342 uint32_t new_portid =
2343 ((rs->snscb_ports[npidx].portid[0]) << 16) |
2344 ((rs->snscb_ports[npidx].portid[1]) << 8) |
2345 ((rs->snscb_ports[npidx].portid[2]));
2346 if (new_portid == portid) {
2347 break;
2348 }
2349 }
2350
2351 if (npidx < portlim) {
2352 rs->snscb_ports[npidx].portid[0] = 0;
2353 rs->snscb_ports[npidx].portid[1] = 0;
2354 rs->snscb_ports[npidx].portid[2] = 0;
2355 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d removing duplicate PortID 0x%06x entry from list", chan, portid);
2356 }
2357 }
2358
2359 /*
2360 * We now have a list of Port IDs for all FC4 SCSI devices
2361 * that the Fabric Name server knows about.
2362 *
2363 * For each entry on this list go through our port database looking
2364 * for probational entries- if we find one, then an old entry is
2365 * maybe still this one. We get some information to find out.
2366 *
2367 * Otherwise, it's a new fabric device, and we log into it
2368 * (unconditionally). After searching the entire database
2369 * again to make sure that we never ever ever ever have more
2370 * than one entry that has the same PortID or the same
2371 * WWNN/WWPN duple, we enter the device into our database.
2372 */
2373 isp_mark_portdb(isp, chan);
2374 for (portidx = 0; portidx < portlim; portidx++) {
2375 portid = ((rs->snscb_ports[portidx].portid[0]) << 16) |
2376 ((rs->snscb_ports[portidx].portid[1]) << 8) |
2377 ((rs->snscb_ports[portidx].portid[2]));
2378 isp_prt(isp, ISP_LOG_SANCFG,
2379 "Chan %d Checking fabric port 0x%06x", chan, portid);
2380 if (portid == 0) {
2381 isp_prt(isp, ISP_LOG_SANCFG,
2382 "Chan %d Port at idx %d is zero",
2383 chan, portidx);
2384 continue;
2385 }
2386 if (portid == fcp->isp_portid) {
2387 isp_prt(isp, ISP_LOG_SANCFG,
2388 "Chan %d Port 0x%06x is our", chan, portid);
2389 continue;
2390 }
2391
2392 /* Now search the entire port database for the same portid. */
2393 if (isp_find_pdb_by_portid(isp, chan, portid, &lp)) {
2394 if (!lp->probational) {
2395 isp_prt(isp, ISP_LOGERR,
2396 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
2397 chan, lp->portid, lp->handle,
2398 FC_PORTDB_TGT(isp, chan, lp), lp->state);
2399 isp_dump_portdb(isp, chan);
2400 goto fail;
2401 }
2402
2403 if (lp->state == FC_PORTDB_STATE_ZOMBIE)
2404 goto relogin;
2405
2406 /*
2407 * See if we're still logged into it.
2408 *
2409 * If we aren't, mark it as a dead device and
2410 * leave the new portid in the database entry
2411 * for somebody further along to decide what to
2412 * do (policy choice).
2413 *
2414 * If we are, check to see if it's the same
2415 * device still (it should be). If for some
2416 * reason it isn't, mark it as a changed device
2417 * and leave the new portid and role in the
2418 * database entry for somebody further along to
2419 * decide what to do (policy choice).
2420 */
2421 r = isp_getpdb(isp, chan, lp->handle, &pdb);
2422 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2423 goto abort;
2424 if (r != 0) {
2425 lp->state = FC_PORTDB_STATE_DEAD;
2426 isp_prt(isp, ISP_LOG_SANCFG,
2427 "Chan %d Port 0x%06x handle 0x%x is dead (%d)",
2428 chan, portid, lp->handle, r);
2429 goto relogin;
2430 }
2431
2432 isp_pdb_add_update(isp, chan, &pdb);
2433 continue;
2434 }
2435
2436 relogin:
2437 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
2438 isp_prt(isp, ISP_LOG_SANCFG,
2439 "Chan %d Port 0x%06x is not logged in", chan, portid);
2440 continue;
2441 }
2442
2443 r = isp_gff_id(isp, chan, portid);
2444 if (r == 0) {
2445 isp_prt(isp, ISP_LOG_SANCFG,
2446 "Chan %d Port 0x%06x is not an FCP target", chan, portid);
2447 continue;
2448 }
2449 if (r < 0)
2450 r = isp_gft_id(isp, chan, portid);
2451 if (r == 0) {
2452 isp_prt(isp, ISP_LOG_SANCFG,
2453 "Chan %d Port 0x%06x is not FCP", chan, portid);
2454 continue;
2455 }
2456
2457 if (isp_login_device(isp, chan, portid, &pdb,
2458 &FCPARAM(isp, 0)->isp_lasthdl)) {
2459 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2460 goto abort;
2461 continue;
2462 }
2463
2464 isp_pdb_add_update(isp, chan, &pdb);
2465 }
2466
2467 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2468 goto abort;
2469 fcp->isp_loopstate = LOOP_FSCAN_DONE;
2470 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan done", chan);
2471 return (0);
2472 }
2473
2474 /*
2475 * Find an unused handle and try and use to login to a port.
2476 */
2477 static int
isp_login_device(ispsoftc_t * isp,int chan,uint32_t portid,isp_pdb_t * p,uint16_t * ohp)2478 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
2479 {
2480 int i, r;
2481 uint16_t handle;
2482
2483 handle = isp_next_handle(isp, ohp);
2484 for (i = 0; i < NPH_MAX_2K; i++) {
2485 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2486 return (-1);
2487
2488 /* Check if this handle is free. */
2489 r = isp_getpdb(isp, chan, handle, p);
2490 if (r == 0) {
2491 if (p->portid != portid) {
2492 /* This handle is busy, try next one. */
2493 handle = isp_next_handle(isp, ohp);
2494 continue;
2495 }
2496 break;
2497 }
2498 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2499 return (-1);
2500
2501 /*
2502 * Now try and log into the device
2503 */
2504 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
2505 if (r == 0) {
2506 break;
2507 } else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
2508 /*
2509 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
2510 * handle. We need to break that association. We used to try and just substitute the handle, but then
2511 * failed to get any data via isp_getpdb (below).
2512 */
2513 if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL)) {
2514 isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
2515 }
2516 if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2517 return (-1);
2518 r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
2519 if (r != 0)
2520 i = NPH_MAX_2K;
2521 break;
2522 } else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
2523 /* Try the next handle. */
2524 handle = isp_next_handle(isp, ohp);
2525 } else {
2526 /* Give up. */
2527 i = NPH_MAX_2K;
2528 break;
2529 }
2530 }
2531
2532 if (i == NPH_MAX_2K) {
2533 isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
2534 return (-1);
2535 }
2536
2537 /*
2538 * If we successfully logged into it, get the PDB for it
2539 * so we can crosscheck that it is still what we think it
2540 * is and that we also have the role it plays
2541 */
2542 r = isp_getpdb(isp, chan, handle, p);
2543 if (r != 0) {
2544 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
2545 return (-1);
2546 }
2547
2548 if (p->handle != handle || p->portid != portid) {
2549 isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
2550 chan, portid, handle, p->portid, p->handle);
2551 return (-1);
2552 }
2553 return (0);
2554 }
2555
2556 static int
isp_register_fc4_type(ispsoftc_t * isp,int chan)2557 isp_register_fc4_type(ispsoftc_t *isp, int chan)
2558 {
2559 fcparam *fcp = FCPARAM(isp, chan);
2560 rft_id_t rp;
2561 ct_hdr_t *ct = &rp.rftid_hdr;
2562 uint8_t *scp = fcp->isp_scratch;
2563
2564 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2565 isp_prt(isp, ISP_LOGERR, sacq);
2566 return (-1);
2567 }
2568
2569 /* Build the CT command and execute via pass-through. */
2570 ISP_MEMZERO(&rp, sizeof(rp));
2571 ct->ct_revision = CT_REVISION;
2572 ct->ct_fcs_type = CT_FC_TYPE_FC;
2573 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2574 ct->ct_cmd_resp = SNS_RFT_ID;
2575 ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
2576 rp.rftid_portid[0] = fcp->isp_portid >> 16;
2577 rp.rftid_portid[1] = fcp->isp_portid >> 8;
2578 rp.rftid_portid[2] = fcp->isp_portid;
2579 rp.rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
2580 isp_put_rft_id(isp, &rp, (rft_id_t *)scp);
2581
2582 if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
2583 FC_SCRATCH_RELEASE(isp, chan);
2584 return (-1);
2585 }
2586
2587 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2588 FC_SCRATCH_RELEASE(isp, chan);
2589 if (ct->ct_cmd_resp == LS_RJT) {
2590 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "Chan %d Register FC4 Type rejected", chan);
2591 return (-1);
2592 } else if (ct->ct_cmd_resp == LS_ACC) {
2593 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Register FC4 Type accepted", chan);
2594 } else {
2595 isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", chan, ct->ct_cmd_resp);
2596 return (-1);
2597 }
2598 return (0);
2599 }
2600
2601 static int
isp_register_fc4_features_24xx(ispsoftc_t * isp,int chan)2602 isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
2603 {
2604 fcparam *fcp = FCPARAM(isp, chan);
2605 ct_hdr_t *ct;
2606 rff_id_t rp;
2607 uint8_t *scp = fcp->isp_scratch;
2608
2609 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2610 isp_prt(isp, ISP_LOGERR, sacq);
2611 return (-1);
2612 }
2613
2614 /*
2615 * Build the CT header and command in memory.
2616 */
2617 ISP_MEMZERO(&rp, sizeof(rp));
2618 ct = &rp.rffid_hdr;
2619 ct->ct_revision = CT_REVISION;
2620 ct->ct_fcs_type = CT_FC_TYPE_FC;
2621 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2622 ct->ct_cmd_resp = SNS_RFF_ID;
2623 ct->ct_bcnt_resid = (sizeof (rff_id_t) - sizeof (ct_hdr_t)) >> 2;
2624 rp.rffid_portid[0] = fcp->isp_portid >> 16;
2625 rp.rffid_portid[1] = fcp->isp_portid >> 8;
2626 rp.rffid_portid[2] = fcp->isp_portid;
2627 rp.rffid_fc4features = 0;
2628 if (fcp->role & ISP_ROLE_TARGET)
2629 rp.rffid_fc4features |= 1;
2630 if (fcp->role & ISP_ROLE_INITIATOR)
2631 rp.rffid_fc4features |= 2;
2632 rp.rffid_fc4type = FC4_SCSI;
2633 isp_put_rff_id(isp, &rp, (rff_id_t *)scp);
2634 if (isp->isp_dblev & ISP_LOGDEBUG1)
2635 isp_print_bytes(isp, "CT request", sizeof(rft_id_t), scp);
2636
2637 if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
2638 FC_SCRATCH_RELEASE(isp, chan);
2639 return (-1);
2640 }
2641
2642 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2643 FC_SCRATCH_RELEASE(isp, chan);
2644 if (ct->ct_cmd_resp == LS_RJT) {
2645 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2646 "Chan %d Register FC4 Features rejected", chan);
2647 return (-1);
2648 } else if (ct->ct_cmd_resp == LS_ACC) {
2649 isp_prt(isp, ISP_LOG_SANCFG,
2650 "Chan %d Register FC4 Features accepted", chan);
2651 } else {
2652 isp_prt(isp, ISP_LOGWARN,
2653 "Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp);
2654 return (-1);
2655 }
2656 return (0);
2657 }
2658
2659 static int
isp_register_port_name_24xx(ispsoftc_t * isp,int chan)2660 isp_register_port_name_24xx(ispsoftc_t *isp, int chan)
2661 {
2662 fcparam *fcp = FCPARAM(isp, chan);
2663 ct_hdr_t *ct;
2664 rspn_id_t rp;
2665 uint8_t *scp = fcp->isp_scratch;
2666 int len;
2667
2668 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2669 isp_prt(isp, ISP_LOGERR, sacq);
2670 return (-1);
2671 }
2672
2673 /*
2674 * Build the CT header and command in memory.
2675 */
2676 ISP_MEMZERO(&rp, sizeof(rp));
2677 ct = &rp.rspnid_hdr;
2678 ct->ct_revision = CT_REVISION;
2679 ct->ct_fcs_type = CT_FC_TYPE_FC;
2680 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2681 ct->ct_cmd_resp = SNS_RSPN_ID;
2682 rp.rspnid_portid[0] = fcp->isp_portid >> 16;
2683 rp.rspnid_portid[1] = fcp->isp_portid >> 8;
2684 rp.rspnid_portid[2] = fcp->isp_portid;
2685 rp.rspnid_length = 0;
2686 len = offsetof(rspn_id_t, rspnid_name);
2687 mtx_lock(&prison0.pr_mtx);
2688 rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
2689 "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
2690 mtx_unlock(&prison0.pr_mtx);
2691 rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
2692 ":%s", device_get_nameunit(isp->isp_dev));
2693 if (chan != 0) {
2694 rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
2695 "/%d", chan);
2696 }
2697 len += rp.rspnid_length;
2698 ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
2699 isp_put_rspn_id(isp, &rp, (rspn_id_t *)scp);
2700
2701 if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
2702 FC_SCRATCH_RELEASE(isp, chan);
2703 return (-1);
2704 }
2705
2706 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2707 FC_SCRATCH_RELEASE(isp, chan);
2708 if (ct->ct_cmd_resp == LS_RJT) {
2709 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2710 "Chan %d Register Symbolic Port Name rejected", chan);
2711 return (-1);
2712 } else if (ct->ct_cmd_resp == LS_ACC) {
2713 isp_prt(isp, ISP_LOG_SANCFG,
2714 "Chan %d Register Symbolic Port Name accepted", chan);
2715 } else {
2716 isp_prt(isp, ISP_LOGWARN,
2717 "Chan %d Register Symbolic Port Name: 0x%x", chan, ct->ct_cmd_resp);
2718 return (-1);
2719 }
2720 return (0);
2721 }
2722
2723 static int
isp_register_node_name_24xx(ispsoftc_t * isp,int chan)2724 isp_register_node_name_24xx(ispsoftc_t *isp, int chan)
2725 {
2726 fcparam *fcp = FCPARAM(isp, chan);
2727 ct_hdr_t *ct;
2728 rsnn_nn_t rp;
2729 uint8_t *scp = fcp->isp_scratch;
2730 int len;
2731
2732 if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2733 isp_prt(isp, ISP_LOGERR, sacq);
2734 return (-1);
2735 }
2736
2737 /*
2738 * Build the CT header and command in memory.
2739 */
2740 ISP_MEMZERO(&rp, sizeof(rp));
2741 ct = &rp.rsnnnn_hdr;
2742 ct->ct_revision = CT_REVISION;
2743 ct->ct_fcs_type = CT_FC_TYPE_FC;
2744 ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2745 ct->ct_cmd_resp = SNS_RSNN_NN;
2746 MAKE_NODE_NAME_FROM_WWN(rp.rsnnnn_nodename, fcp->isp_wwnn);
2747 rp.rsnnnn_length = 0;
2748 len = offsetof(rsnn_nn_t, rsnnnn_name);
2749 mtx_lock(&prison0.pr_mtx);
2750 rp.rsnnnn_length += sprintf(&scp[len + rp.rsnnnn_length],
2751 "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
2752 mtx_unlock(&prison0.pr_mtx);
2753 len += rp.rsnnnn_length;
2754 ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
2755 isp_put_rsnn_nn(isp, &rp, (rsnn_nn_t *)scp);
2756
2757 if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
2758 FC_SCRATCH_RELEASE(isp, chan);
2759 return (-1);
2760 }
2761
2762 isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2763 FC_SCRATCH_RELEASE(isp, chan);
2764 if (ct->ct_cmd_resp == LS_RJT) {
2765 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2766 "Chan %d Register Symbolic Node Name rejected", chan);
2767 return (-1);
2768 } else if (ct->ct_cmd_resp == LS_ACC) {
2769 isp_prt(isp, ISP_LOG_SANCFG,
2770 "Chan %d Register Symbolic Node Name accepted", chan);
2771 } else {
2772 isp_prt(isp, ISP_LOGWARN,
2773 "Chan %d Register Symbolic Node Name: 0x%x", chan, ct->ct_cmd_resp);
2774 return (-1);
2775 }
2776 return (0);
2777 }
2778
2779 static uint16_t
isp_next_handle(ispsoftc_t * isp,uint16_t * ohp)2780 isp_next_handle(ispsoftc_t *isp, uint16_t *ohp)
2781 {
2782 fcparam *fcp;
2783 int i, chan, wrap;
2784 uint16_t handle;
2785
2786 handle = *ohp;
2787 wrap = 0;
2788
2789 next:
2790 if (handle == NIL_HANDLE) {
2791 handle = 0;
2792 } else {
2793 handle++;
2794 if (handle > NPH_RESERVED - 1) {
2795 if (++wrap >= 2) {
2796 isp_prt(isp, ISP_LOGERR, "Out of port handles!");
2797 return (NIL_HANDLE);
2798 }
2799 handle = 0;
2800 }
2801 }
2802 for (chan = 0; chan < isp->isp_nchan; chan++) {
2803 fcp = FCPARAM(isp, chan);
2804 if (fcp->role == ISP_ROLE_NONE)
2805 continue;
2806 for (i = 0; i < MAX_FC_TARG; i++) {
2807 if (fcp->portdb[i].state != FC_PORTDB_STATE_NIL &&
2808 fcp->portdb[i].handle == handle)
2809 goto next;
2810 }
2811 }
2812 *ohp = handle;
2813 return (handle);
2814 }
2815
2816 /*
2817 * Start a command. Locking is assumed done in the caller.
2818 */
2819
2820 int
isp_start(XS_T * xs)2821 isp_start(XS_T *xs)
2822 {
2823 ispsoftc_t *isp;
2824 fcparam *fcp;
2825 uint32_t cdblen;
2826 ispreqt7_t local, *reqp = &local;
2827 void *qep;
2828 fcportdb_t *lp;
2829 int target, dmaresult;
2830
2831 XS_INITERR(xs);
2832 isp = XS_ISP(xs);
2833
2834 /*
2835 * Check command CDB length, etc.. We really are limited to 16 bytes
2836 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
2837 * but probably only if we're running fairly new firmware (we'll
2838 * let the old f/w choke on an extended command queue entry).
2839 */
2840
2841 if (XS_CDBLEN(xs) > 16 || XS_CDBLEN(xs) == 0) {
2842 isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
2843 XS_SETERR(xs, HBA_REQINVAL);
2844 return (CMD_COMPLETE);
2845 }
2846
2847 /*
2848 * Translate the target to device handle as appropriate, checking
2849 * for correct device state as well.
2850 */
2851 target = XS_TGT(xs);
2852 fcp = FCPARAM(isp, XS_CHANNEL(xs));
2853
2854 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
2855 isp_prt(isp, ISP_LOG_WARN1,
2856 "%d.%d.%jx I am not an initiator",
2857 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2858 XS_SETERR(xs, HBA_SELTIMEOUT);
2859 return (CMD_COMPLETE);
2860 }
2861
2862 if (isp->isp_state != ISP_RUNSTATE) {
2863 isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
2864 XS_SETERR(xs, HBA_BOTCH);
2865 return (CMD_COMPLETE);
2866 }
2867
2868 isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d", target);
2869 lp = &fcp->portdb[target];
2870 if (target < 0 || target >= MAX_FC_TARG ||
2871 lp->is_target == 0) {
2872 XS_SETERR(xs, HBA_SELTIMEOUT);
2873 return (CMD_COMPLETE);
2874 }
2875 if (fcp->isp_loopstate != LOOP_READY) {
2876 isp_prt(isp, ISP_LOGDEBUG1,
2877 "%d.%d.%jx loop is not ready",
2878 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2879 return (CMD_RQLATER);
2880 }
2881 if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
2882 isp_prt(isp, ISP_LOGDEBUG1,
2883 "%d.%d.%jx target zombie",
2884 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2885 return (CMD_RQLATER);
2886 }
2887 if (lp->state != FC_PORTDB_STATE_VALID) {
2888 isp_prt(isp, ISP_LOGDEBUG1,
2889 "%d.%d.%jx bad db port state 0x%x",
2890 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs), lp->state);
2891 XS_SETERR(xs, HBA_SELTIMEOUT);
2892 return (CMD_COMPLETE);
2893 }
2894
2895 start_again:
2896
2897 qep = isp_getrqentry(isp);
2898 if (qep == NULL) {
2899 isp_prt(isp, ISP_LOG_WARN1, "Request Queue Overflow");
2900 XS_SETERR(xs, HBA_BOTCH);
2901 return (CMD_EAGAIN);
2902 }
2903 XS_SETERR(xs, HBA_NOERROR);
2904
2905 /*
2906 * Now see if we need to synchronize the ISP with respect to anything.
2907 * We do dual duty here (cough) for synchronizing for buses other
2908 * than which we got here to send a command to.
2909 */
2910 ISP_MEMZERO(reqp, QENTRY_LEN);
2911 if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
2912 isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
2913 m->mrk_header.rqs_entry_count = 1;
2914 m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
2915 m->mrk_modifier = SYNC_ALL;
2916 m->mrk_vphdl = XS_CHANNEL(xs);
2917 isp_put_marker_24xx(isp, m, qep);
2918 ISP_SYNC_REQUEST(isp);
2919 ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
2920 goto start_again;
2921 }
2922
2923 /*
2924 * NB: we do not support long CDBs (yet)
2925 */
2926 cdblen = XS_CDBLEN(xs);
2927 if (cdblen > sizeof (reqp->req_cdb)) {
2928 isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
2929 XS_SETERR(xs, HBA_REQINVAL);
2930 return (CMD_COMPLETE);
2931 }
2932
2933 reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
2934 reqp->req_header.rqs_entry_count = 1;
2935 reqp->req_nphdl = lp->handle;
2936 reqp->req_time = XS_TIME(xs);
2937 be64enc(reqp->req_lun, CAM_EXTLUN_BYTE_SWIZZLE(XS_LUN(xs)));
2938 if (XS_XFRIN(xs))
2939 reqp->req_alen_datadir = FCP_CMND_DATA_READ;
2940 else if (XS_XFROUT(xs))
2941 reqp->req_alen_datadir = FCP_CMND_DATA_WRITE;
2942 if (XS_TAG_P(xs))
2943 reqp->req_task_attribute = XS_TAG_TYPE(xs);
2944 else
2945 reqp->req_task_attribute = FCP_CMND_TASK_ATTR_SIMPLE;
2946 reqp->req_task_attribute |= (XS_PRIORITY(xs) << FCP_CMND_PRIO_SHIFT) &
2947 FCP_CMND_PRIO_MASK;
2948 if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) {
2949 if (FCP_NEXT_CRN(isp, &reqp->req_crn, xs)) {
2950 isp_prt(isp, ISP_LOG_WARN1,
2951 "%d.%d.%jx cannot generate next CRN",
2952 XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2953 XS_SETERR(xs, HBA_BOTCH);
2954 return (CMD_EAGAIN);
2955 }
2956 }
2957 ISP_MEMCPY(reqp->req_cdb, XS_CDBP(xs), cdblen);
2958 reqp->req_dl = XS_XFRLEN(xs);
2959 reqp->req_tidlo = lp->portid;
2960 reqp->req_tidhi = lp->portid >> 16;
2961 reqp->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
2962
2963 /* Whew. Thankfully the same for type 7 requests */
2964 reqp->req_handle = isp_allocate_handle(isp, xs, ISP_HANDLE_INITIATOR);
2965 if (reqp->req_handle == 0) {
2966 isp_prt(isp, ISP_LOG_WARN1, "out of xflist pointers");
2967 XS_SETERR(xs, HBA_BOTCH);
2968 return (CMD_EAGAIN);
2969 }
2970
2971 /*
2972 * Set up DMA and/or do any platform dependent swizzling of the request entry
2973 * so that the Qlogic F/W understands what is being asked of it.
2974 *
2975 * The callee is responsible for adding all requests at this point.
2976 */
2977 dmaresult = ISP_DMASETUP(isp, xs, reqp);
2978 if (dmaresult != 0) {
2979 isp_destroy_handle(isp, reqp->req_handle);
2980 /*
2981 * dmasetup sets actual error in packet, and
2982 * return what we were given to return.
2983 */
2984 return (dmaresult);
2985 }
2986 isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
2987 return (0);
2988 }
2989
2990 /*
2991 * isp control
2992 * Locks (ints blocked) assumed held.
2993 */
2994
2995 int
isp_control(ispsoftc_t * isp,ispctl_t ctl,...)2996 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
2997 {
2998 fcparam *fcp;
2999 fcportdb_t *lp;
3000 XS_T *xs;
3001 mbreg_t *mbr;
3002 int chan, tgt;
3003 uint32_t handle;
3004 va_list ap;
3005 uint8_t local[QENTRY_LEN];
3006
3007 switch (ctl) {
3008 case ISPCTL_RESET_BUS:
3009 /*
3010 * Issue a bus reset.
3011 */
3012 isp_prt(isp, ISP_LOGERR, "BUS RESET NOT IMPLEMENTED");
3013 break;
3014
3015 case ISPCTL_RESET_DEV:
3016 {
3017 isp24xx_tmf_t *tmf;
3018 isp24xx_statusreq_t *sp;
3019
3020 va_start(ap, ctl);
3021 chan = va_arg(ap, int);
3022 tgt = va_arg(ap, int);
3023 va_end(ap);
3024 fcp = FCPARAM(isp, chan);
3025
3026 if (tgt < 0 || tgt >= MAX_FC_TARG) {
3027 isp_prt(isp, ISP_LOGWARN, "Chan %d trying to reset bad target %d", chan, tgt);
3028 break;
3029 }
3030 lp = &fcp->portdb[tgt];
3031 if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) {
3032 isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
3033 break;
3034 }
3035
3036 tmf = (isp24xx_tmf_t *) local;
3037 ISP_MEMZERO(tmf, QENTRY_LEN);
3038 tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
3039 tmf->tmf_header.rqs_entry_count = 1;
3040 tmf->tmf_nphdl = lp->handle;
3041 tmf->tmf_delay = 2;
3042 tmf->tmf_timeout = 4;
3043 tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
3044 tmf->tmf_tidlo = lp->portid;
3045 tmf->tmf_tidhi = lp->portid >> 16;
3046 tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
3047 fcp->sendmarker = 1;
3048 isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
3049
3050 sp = (isp24xx_statusreq_t *) local;
3051 if (isp_exec_entry_mbox(isp, tmf, sp, 2 * tmf->tmf_timeout))
3052 break;
3053
3054 if (sp->req_completion_status == 0)
3055 return (0);
3056 isp_prt(isp, ISP_LOGWARN, "Chan %d reset of target %d returned 0x%x", chan, tgt, sp->req_completion_status);
3057 break;
3058 }
3059 case ISPCTL_ABORT_CMD:
3060 {
3061 isp24xx_abrt_t *ab = (isp24xx_abrt_t *)&local;
3062
3063 va_start(ap, ctl);
3064 xs = va_arg(ap, XS_T *);
3065 va_end(ap);
3066
3067 tgt = XS_TGT(xs);
3068 chan = XS_CHANNEL(xs);
3069
3070 handle = isp_find_handle(isp, xs);
3071 if (handle == 0) {
3072 isp_prt(isp, ISP_LOGWARN, "cannot find handle for command to abort");
3073 break;
3074 }
3075
3076 fcp = FCPARAM(isp, chan);
3077 if (tgt < 0 || tgt >= MAX_FC_TARG) {
3078 isp_prt(isp, ISP_LOGWARN, "Chan %d trying to abort bad target %d", chan, tgt);
3079 break;
3080 }
3081 lp = &fcp->portdb[tgt];
3082 if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) {
3083 isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
3084 break;
3085 }
3086 isp_prt(isp, ISP_LOGALL, "Chan %d Abort Cmd for N-Port 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
3087 ISP_MEMZERO(ab, QENTRY_LEN);
3088 ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
3089 ab->abrt_header.rqs_entry_count = 1;
3090 ab->abrt_handle = lp->handle;
3091 ab->abrt_cmd_handle = handle;
3092 ab->abrt_tidlo = lp->portid;
3093 ab->abrt_tidhi = lp->portid >> 16;
3094 ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
3095
3096 if (isp_exec_entry_mbox(isp, ab, ab, 5))
3097 break;
3098
3099 if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY)
3100 return (0);
3101 isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d abort returned 0x%x", chan, tgt, ab->abrt_nphdl);
3102 break;
3103 }
3104 case ISPCTL_FCLINK_TEST:
3105 {
3106 int usdelay;
3107
3108 va_start(ap, ctl);
3109 chan = va_arg(ap, int);
3110 usdelay = va_arg(ap, int);
3111 va_end(ap);
3112 if (usdelay == 0)
3113 usdelay = 250000;
3114 return (isp_fclink_test(isp, chan, usdelay));
3115 }
3116 case ISPCTL_SCAN_FABRIC:
3117
3118 va_start(ap, ctl);
3119 chan = va_arg(ap, int);
3120 va_end(ap);
3121 return (isp_scan_fabric(isp, chan));
3122
3123 case ISPCTL_SCAN_LOOP:
3124
3125 va_start(ap, ctl);
3126 chan = va_arg(ap, int);
3127 va_end(ap);
3128 return (isp_scan_loop(isp, chan));
3129
3130 case ISPCTL_PDB_SYNC:
3131
3132 va_start(ap, ctl);
3133 chan = va_arg(ap, int);
3134 va_end(ap);
3135 return (isp_pdb_sync(isp, chan));
3136
3137 case ISPCTL_SEND_LIP:
3138 break;
3139
3140 case ISPCTL_GET_PDB:
3141 {
3142 isp_pdb_t *pdb;
3143 va_start(ap, ctl);
3144 chan = va_arg(ap, int);
3145 tgt = va_arg(ap, int);
3146 pdb = va_arg(ap, isp_pdb_t *);
3147 va_end(ap);
3148 return (isp_getpdb(isp, chan, tgt, pdb));
3149 }
3150 case ISPCTL_GET_NAMES:
3151 {
3152 uint64_t *wwnn, *wwnp;
3153 va_start(ap, ctl);
3154 chan = va_arg(ap, int);
3155 tgt = va_arg(ap, int);
3156 wwnn = va_arg(ap, uint64_t *);
3157 wwnp = va_arg(ap, uint64_t *);
3158 va_end(ap);
3159 if (wwnn == NULL && wwnp == NULL) {
3160 break;
3161 }
3162 if (wwnn) {
3163 *wwnn = isp_get_wwn(isp, chan, tgt, 1);
3164 if (*wwnn == INI_NONE) {
3165 break;
3166 }
3167 }
3168 if (wwnp) {
3169 *wwnp = isp_get_wwn(isp, chan, tgt, 0);
3170 if (*wwnp == INI_NONE) {
3171 break;
3172 }
3173 }
3174 return (0);
3175 }
3176 case ISPCTL_RUN_MBOXCMD:
3177 {
3178 va_start(ap, ctl);
3179 mbr = va_arg(ap, mbreg_t *);
3180 va_end(ap);
3181 isp_mboxcmd(isp, mbr);
3182 return (0);
3183 }
3184 case ISPCTL_PLOGX:
3185 {
3186 isp_plcmd_t *p;
3187 int r;
3188
3189 va_start(ap, ctl);
3190 p = va_arg(ap, isp_plcmd_t *);
3191 va_end(ap);
3192
3193 if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
3194 return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags));
3195 }
3196 do {
3197 isp_next_handle(isp, &p->handle);
3198 r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags);
3199 if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3200 p->handle = r >> 16;
3201 r = 0;
3202 break;
3203 }
3204 } while ((r & 0xffff) == MBOX_LOOP_ID_USED);
3205 return (r);
3206 }
3207 case ISPCTL_CHANGE_ROLE:
3208 {
3209 int role;
3210
3211 va_start(ap, ctl);
3212 chan = va_arg(ap, int);
3213 role = va_arg(ap, int);
3214 va_end(ap);
3215 return (isp_fc_change_role(isp, chan, role));
3216 }
3217 default:
3218 isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
3219 break;
3220
3221 }
3222 return (-1);
3223 }
3224
3225 /*
3226 * Interrupt Service Routine(s).
3227 *
3228 * External (OS) framework has done the appropriate locking,
3229 * and the locking will be held throughout this function.
3230 */
3231
3232 #ifdef ISP_TARGET_MODE
3233 void
isp_intr_atioq(ispsoftc_t * isp)3234 isp_intr_atioq(ispsoftc_t *isp)
3235 {
3236 void *addr;
3237 uint32_t iptr, optr, oop;
3238
3239 iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
3240 optr = isp->isp_atioodx;
3241 while (optr != iptr) {
3242 oop = optr;
3243 MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
3244 addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
3245 switch (((isphdr_t *)addr)->rqs_entry_type) {
3246 case RQSTYPE_NOTIFY:
3247 case RQSTYPE_ATIO:
3248 case RQSTYPE_NOTIFY_ACK: /* Can be set to ATIO queue.*/
3249 case RQSTYPE_ABTS_RCVD: /* Can be set to ATIO queue.*/
3250 (void) isp_target_notify(isp, addr, &oop,
3251 ATIO_QUEUE_LEN(isp));
3252 break;
3253 case RQSTYPE_RPT_ID_ACQ: /* Can be set to ATIO queue.*/
3254 default:
3255 isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
3256 break;
3257 }
3258 optr = ISP_NXT_QENTRY(oop, ATIO_QUEUE_LEN(isp));
3259 }
3260 if (isp->isp_atioodx != optr) {
3261 ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
3262 isp->isp_atioodx = optr;
3263 }
3264 }
3265 #endif
3266
3267 void
isp_intr_mbox(ispsoftc_t * isp,uint16_t mbox0)3268 isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0)
3269 {
3270 int i, obits;
3271
3272 if (!isp->isp_mboxbsy) {
3273 isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0);
3274 return;
3275 }
3276 obits = isp->isp_obits;
3277 isp->isp_mboxtmp[0] = mbox0;
3278 for (i = 1; i < ISP_NMBOX(isp); i++) {
3279 if ((obits & (1 << i)) == 0)
3280 continue;
3281 isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
3282 }
3283 isp->isp_mboxbsy = 0;
3284 }
3285
3286 void
isp_intr_respq(ispsoftc_t * isp)3287 isp_intr_respq(ispsoftc_t *isp)
3288 {
3289 XS_T *xs, *cont_xs;
3290 uint8_t qe[QENTRY_LEN];
3291 isp24xx_statusreq_t *sp = (isp24xx_statusreq_t *)qe;
3292 ispstatus_cont_t *scp = (ispstatus_cont_t *)qe;
3293 isphdr_t *hp;
3294 uint8_t *resp, *snsp, etype;
3295 uint16_t scsi_status;
3296 uint32_t iptr, cont = 0, cptr, optr, rlen, slen, totslen;
3297 #ifdef ISP_TARGET_MODE
3298 uint32_t sptr;
3299 #endif
3300
3301 /*
3302 * We can't be getting this now.
3303 */
3304 if (isp->isp_state != ISP_RUNSTATE) {
3305 isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready");
3306 return;
3307 }
3308
3309 iptr = ISP_READ(isp, BIU2400_RSPINP);
3310 optr = isp->isp_resodx;
3311 while (optr != iptr) {
3312 cptr = optr;
3313 #ifdef ISP_TARGET_MODE
3314 sptr = optr;
3315 #endif
3316 hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, cptr);
3317 optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
3318
3319 /*
3320 * Synchronize our view of this response queue entry.
3321 */
3322 MEMORYBARRIER(isp, SYNC_RESULT, cptr, QENTRY_LEN, -1);
3323 if (isp->isp_dblev & ISP_LOGDEBUG1)
3324 isp_print_qentry(isp, "Response Queue Entry", cptr, hp);
3325 isp_get_hdr(isp, hp, &sp->req_header);
3326
3327 /*
3328 * Log IOCBs rejected by the firmware. We can't really do
3329 * much more about them, since it just should not happen.
3330 */
3331 if (sp->req_header.rqs_flags & RQSFLAG_BADTYPE) {
3332 isp_print_qentry(isp, "invalid entry type", cptr, hp);
3333 continue;
3334 }
3335 if (sp->req_header.rqs_flags & RQSFLAG_BADPARAM) {
3336 isp_print_qentry(isp, "invalid entry parameter", cptr, hp);
3337 continue;
3338 }
3339 if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
3340 isp_print_qentry(isp, "invalid entry count", cptr, hp);
3341 continue;
3342 }
3343 if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
3344 isp_print_qentry(isp, "invalid entry order", cptr, hp);
3345 continue;
3346 }
3347
3348 etype = sp->req_header.rqs_entry_type;
3349
3350 /* We expected Status Continuation, but got different IOCB. */
3351 if (cont > 0 && etype != RQSTYPE_STATUS_CONT) {
3352 cont = 0;
3353 isp_done(cont_xs);
3354 }
3355
3356 if (isp_handle_control(isp, hp)) {
3357 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3358 continue;
3359 }
3360
3361 switch (etype) {
3362 case RQSTYPE_RESPONSE:
3363 isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp);
3364 break;
3365 case RQSTYPE_MARKER:
3366 isp_prt(isp, ISP_LOG_WARN1, "Marker Response");
3367 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3368 continue;
3369 case RQSTYPE_STATUS_CONT:
3370 isp_get_cont_response(isp, (ispstatus_cont_t *)hp, scp);
3371 if (cont > 0) {
3372 slen = min(cont, sizeof(scp->req_sense_data));
3373 XS_SENSE_APPEND(cont_xs, scp->req_sense_data, slen);
3374 cont -= slen;
3375 if (cont == 0) {
3376 isp_done(cont_xs);
3377 } else {
3378 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3379 "Expecting Status Continuations for %u bytes",
3380 cont);
3381 }
3382 } else {
3383 isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
3384 }
3385 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3386 continue;
3387 #ifdef ISP_TARGET_MODE
3388 case RQSTYPE_NOTIFY_ACK: /* Can be set to ATIO queue. */
3389 case RQSTYPE_CTIO7:
3390 case RQSTYPE_ABTS_RCVD: /* Can be set to ATIO queue. */
3391 case RQSTYPE_ABTS_RSP:
3392 isp_target_notify(isp, hp, &cptr, RESULT_QUEUE_LEN(isp));
3393 /* More then one IOCB could be consumed. */
3394 while (sptr != cptr) {
3395 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3396 sptr = ISP_NXT_QENTRY(sptr, RESULT_QUEUE_LEN(isp));
3397 hp = (isphdr_t *)ISP_QUEUE_ENTRY(isp->isp_result, sptr);
3398 }
3399 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3400 optr = ISP_NXT_QENTRY(cptr, RESULT_QUEUE_LEN(isp));
3401 continue;
3402 #endif
3403 case RQSTYPE_RPT_ID_ACQ: /* Can be set to ATIO queue.*/
3404 isp_handle_rpt_id_acq(isp, hp);
3405 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3406 continue;
3407 default:
3408 /* We don't know what was this -- log and skip. */
3409 isp_prt(isp, ISP_LOGERR, notresp, etype, cptr, optr);
3410 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3411 continue;
3412 }
3413
3414 xs = isp_find_xs(isp, sp->req_handle);
3415 if (xs == NULL) {
3416 /*
3417 * Only whine if this isn't the expected fallout of
3418 * aborting the command or resetting the target.
3419 */
3420 if (sp->req_completion_status != RQCS_ABORTED &&
3421 sp->req_completion_status != RQCS_RESET_OCCURRED)
3422 isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)",
3423 sp->req_handle, sp->req_completion_status);
3424 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3425 continue;
3426 }
3427
3428 resp = snsp = sp->req_rsp_sense;
3429 rlen = slen = totslen = 0;
3430 scsi_status = sp->req_scsi_status;
3431 if (scsi_status & RQCS_RV) {
3432 rlen = sp->req_response_len;
3433 snsp += rlen;
3434 }
3435 if (scsi_status & RQCS_SV) {
3436 totslen = sp->req_sense_len;
3437 slen = MIN(totslen, sizeof(sp->req_rsp_sense) - rlen);
3438 }
3439 *XS_STSP(xs) = scsi_status & 0xff;
3440 if (scsi_status & RQCS_RESID)
3441 XS_SET_RESID(xs, sp->req_fcp_residual);
3442 else
3443 XS_SET_RESID(xs, 0);
3444
3445 if (rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
3446 const char *ptr;
3447 char lb[64];
3448 const char *rnames[10] = {
3449 "Task Management function complete",
3450 "FCP_DATA length different than FCP_BURST_LEN",
3451 "FCP_CMND fields invalid",
3452 "FCP_DATA parameter mismatch with FCP_DATA_RO",
3453 "Task Management function rejected",
3454 "Task Management function failed",
3455 NULL,
3456 NULL,
3457 "Task Management function succeeded",
3458 "Task Management function incorrect logical unit number",
3459 };
3460 uint8_t code = resp[FCP_RSPNS_CODE_OFFSET];
3461 if (code >= nitems(rnames) || rnames[code] == NULL) {
3462 ISP_SNPRINTF(lb, sizeof(lb),
3463 "Unknown FCP Response Code 0x%x", code);
3464 ptr = lb;
3465 } else {
3466 ptr = rnames[code];
3467 }
3468 isp_xs_prt(isp, xs, ISP_LOGWARN,
3469 "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x",
3470 rlen, ptr, XS_CDBP(xs)[0] & 0xff);
3471 if (code != FCP_RSPNS_TMF_DONE &&
3472 code != FCP_RSPNS_TMF_SUCCEEDED)
3473 XS_SETERR(xs, HBA_BOTCH);
3474 }
3475 isp_parse_status_24xx(isp, sp, xs);
3476 if (slen > 0) {
3477 XS_SAVE_SENSE(xs, snsp, slen);
3478 if (totslen > slen) {
3479 cont = totslen - slen;
3480 cont_xs = xs;
3481 isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3482 "Expecting Status Continuations for %u bytes",
3483 cont);
3484 }
3485 }
3486
3487 ISP_DMAFREE(isp, xs);
3488 isp_destroy_handle(isp, sp->req_handle);
3489 ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
3490
3491 /* Complete command if we expect no Status Continuations. */
3492 if (cont == 0)
3493 isp_done(xs);
3494 }
3495
3496 /* We haven't received all Status Continuations, but that is it. */
3497 if (cont > 0)
3498 isp_done(cont_xs);
3499
3500 /* If we processed any IOCBs, let ISP know about it. */
3501 if (optr != isp->isp_resodx) {
3502 ISP_WRITE(isp, BIU2400_RSPOUTP, optr);
3503 isp->isp_resodx = optr;
3504 }
3505 }
3506
3507
3508 void
isp_intr_async(ispsoftc_t * isp,uint16_t mbox)3509 isp_intr_async(ispsoftc_t *isp, uint16_t mbox)
3510 {
3511 fcparam *fcp;
3512 uint16_t chan;
3513
3514 isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
3515
3516 switch (mbox) {
3517 case ASYNC_SYSTEM_ERROR:
3518 isp->isp_state = ISP_CRASHED;
3519 for (chan = 0; chan < isp->isp_nchan; chan++) {
3520 FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
3521 isp_change_fw_state(isp, chan, FW_CONFIG_WAIT);
3522 }
3523 /*
3524 * Were we waiting for a mailbox command to complete?
3525 * If so, it's dead, so wake up the waiter.
3526 */
3527 if (isp->isp_mboxbsy) {
3528 isp->isp_obits = 1;
3529 isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
3530 isp->isp_mboxbsy = 0;
3531 }
3532 /*
3533 * It's up to the handler for isp_async to reinit stuff and
3534 * restart the firmware
3535 */
3536 isp_async(isp, ISPASYNC_FW_CRASH);
3537 break;
3538
3539 case ASYNC_RQS_XFER_ERR:
3540 isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
3541 break;
3542
3543 case ASYNC_RSP_XFER_ERR:
3544 isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
3545 break;
3546
3547 case ASYNC_ATIO_XFER_ERR:
3548 isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
3549 break;
3550
3551 case ASYNC_LIP_OCCURRED:
3552 case ASYNC_LIP_NOS_OLS_RECV:
3553 case ASYNC_LIP_ERROR:
3554 case ASYNC_PTPMODE:
3555 /*
3556 * These are broadcast events that have to be sent across
3557 * all active channels.
3558 */
3559 for (chan = 0; chan < isp->isp_nchan; chan++) {
3560 fcp = FCPARAM(isp, chan);
3561 int topo = fcp->isp_topo;
3562
3563 if (fcp->role == ISP_ROLE_NONE)
3564 continue;
3565 if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3566 fcp->isp_loopstate = LOOP_HAVE_LINK;
3567 ISP_SET_SENDMARKER(isp, chan, 1);
3568 isp_async(isp, ISPASYNC_LIP, chan);
3569 #ifdef ISP_TARGET_MODE
3570 isp_target_async(isp, chan, mbox);
3571 #endif
3572 /*
3573 * We've had problems with data corruption occurring on
3574 * commands that complete (with no apparent error) after
3575 * we receive a LIP. This has been observed mostly on
3576 * Local Loop topologies. To be safe, let's just mark
3577 * all active initiator commands as dead.
3578 */
3579 if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
3580 int i, j;
3581 for (i = j = 0; i < ISP_HANDLE_NUM(isp); i++) {
3582 XS_T *xs;
3583 isp_hdl_t *hdp;
3584
3585 hdp = &isp->isp_xflist[i];
3586 if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
3587 continue;
3588 }
3589 xs = hdp->cmd;
3590 if (XS_CHANNEL(xs) != chan) {
3591 continue;
3592 }
3593 j++;
3594 isp_prt(isp, ISP_LOG_WARN1,
3595 "%d.%d.%jx bus reset set at %s:%u",
3596 XS_CHANNEL(xs), XS_TGT(xs),
3597 (uintmax_t)XS_LUN(xs),
3598 __func__, __LINE__);
3599 XS_SETERR(xs, HBA_BUSRESET);
3600 }
3601 if (j) {
3602 isp_prt(isp, ISP_LOGERR, lipd, chan, j);
3603 }
3604 }
3605 }
3606 break;
3607
3608 case ASYNC_LOOP_UP:
3609 /*
3610 * This is a broadcast event that has to be sent across
3611 * all active channels.
3612 */
3613 for (chan = 0; chan < isp->isp_nchan; chan++) {
3614 fcp = FCPARAM(isp, chan);
3615 if (fcp->role == ISP_ROLE_NONE)
3616 continue;
3617 fcp->isp_linkstate = 1;
3618 if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3619 fcp->isp_loopstate = LOOP_HAVE_LINK;
3620 ISP_SET_SENDMARKER(isp, chan, 1);
3621 isp_async(isp, ISPASYNC_LOOP_UP, chan);
3622 #ifdef ISP_TARGET_MODE
3623 isp_target_async(isp, chan, mbox);
3624 #endif
3625 }
3626 break;
3627
3628 case ASYNC_LOOP_DOWN:
3629 /*
3630 * This is a broadcast event that has to be sent across
3631 * all active channels.
3632 */
3633 for (chan = 0; chan < isp->isp_nchan; chan++) {
3634 fcp = FCPARAM(isp, chan);
3635 if (fcp->role == ISP_ROLE_NONE)
3636 continue;
3637 ISP_SET_SENDMARKER(isp, chan, 1);
3638 fcp->isp_linkstate = 0;
3639 fcp->isp_loopstate = LOOP_NIL;
3640 isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
3641 #ifdef ISP_TARGET_MODE
3642 isp_target_async(isp, chan, mbox);
3643 #endif
3644 }
3645 break;
3646
3647 case ASYNC_LOOP_RESET:
3648 /*
3649 * This is a broadcast event that has to be sent across
3650 * all active channels.
3651 */
3652 for (chan = 0; chan < isp->isp_nchan; chan++) {
3653 fcp = FCPARAM(isp, chan);
3654 if (fcp->role == ISP_ROLE_NONE)
3655 continue;
3656 ISP_SET_SENDMARKER(isp, chan, 1);
3657 if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3658 fcp->isp_loopstate = LOOP_HAVE_LINK;
3659 isp_async(isp, ISPASYNC_LOOP_RESET, chan);
3660 #ifdef ISP_TARGET_MODE
3661 isp_target_async(isp, chan, mbox);
3662 #endif
3663 }
3664 break;
3665
3666 case ASYNC_PDB_CHANGED:
3667 {
3668 int echan, nphdl, nlstate, reason;
3669
3670 nphdl = ISP_READ(isp, OUTMAILBOX1);
3671 nlstate = ISP_READ(isp, OUTMAILBOX2);
3672 reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
3673 if (ISP_CAP_MULTI_ID(isp)) {
3674 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3675 if (chan == 0xff || nphdl == NIL_HANDLE) {
3676 chan = 0;
3677 echan = isp->isp_nchan - 1;
3678 } else if (chan >= isp->isp_nchan) {
3679 break;
3680 } else {
3681 echan = chan;
3682 }
3683 } else {
3684 chan = echan = 0;
3685 }
3686 for (; chan <= echan; chan++) {
3687 fcp = FCPARAM(isp, chan);
3688 if (fcp->role == ISP_ROLE_NONE)
3689 continue;
3690 if (fcp->isp_loopstate > LOOP_LTEST_DONE) {
3691 if (nphdl != NIL_HANDLE &&
3692 nphdl == fcp->isp_login_hdl &&
3693 reason == PDB24XX_AE_OPN_2)
3694 continue;
3695 fcp->isp_loopstate = LOOP_LTEST_DONE;
3696 } else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3697 fcp->isp_loopstate = LOOP_HAVE_LINK;
3698 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3699 ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
3700 }
3701 break;
3702 }
3703 case ASYNC_CHANGE_NOTIFY:
3704 {
3705 int portid;
3706
3707 portid = ((ISP_READ(isp, OUTMAILBOX1) & 0xff) << 16) |
3708 ISP_READ(isp, OUTMAILBOX2);
3709 if (ISP_CAP_MULTI_ID(isp)) {
3710 chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3711 if (chan >= isp->isp_nchan)
3712 break;
3713 } else {
3714 chan = 0;
3715 }
3716 fcp = FCPARAM(isp, chan);
3717 if (fcp->role == ISP_ROLE_NONE)
3718 break;
3719 if (fcp->isp_loopstate > LOOP_LTEST_DONE)
3720 fcp->isp_loopstate = LOOP_LTEST_DONE;
3721 else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3722 fcp->isp_loopstate = LOOP_HAVE_LINK;
3723 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3724 ISPASYNC_CHANGE_SNS, portid);
3725 break;
3726 }
3727 case ASYNC_ERR_LOGGING_DISABLED:
3728 isp_prt(isp, ISP_LOGWARN, "Error logging disabled (reason 0x%x)",
3729 ISP_READ(isp, OUTMAILBOX1));
3730 break;
3731 case ASYNC_P2P_INIT_ERR:
3732 isp_prt(isp, ISP_LOGWARN, "P2P init error (reason 0x%x)",
3733 ISP_READ(isp, OUTMAILBOX1));
3734 break;
3735 case ASYNC_RCV_ERR:
3736 isp_prt(isp, ISP_LOGWARN, "Receive Error");
3737 break;
3738 case ASYNC_RJT_SENT: /* same as ASYNC_QFULL_SENT */
3739 isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
3740 break;
3741 case ASYNC_FW_RESTART_COMPLETE:
3742 isp_prt(isp, ISP_LOGDEBUG0, "FW restart complete");
3743 break;
3744 case ASYNC_TEMPERATURE_ALERT:
3745 isp_prt(isp, ISP_LOGERR, "Temperature alert (subcode 0x%x)",
3746 ISP_READ(isp, OUTMAILBOX1));
3747 break;
3748 case ASYNC_INTER_DRIVER_COMP:
3749 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication complete");
3750 break;
3751 case ASYNC_INTER_DRIVER_NOTIFY:
3752 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication notification");
3753 break;
3754 case ASYNC_INTER_DRIVER_TIME_EXT:
3755 isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication time extended");
3756 break;
3757 case ASYNC_TRANSCEIVER_INSERTION:
3758 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver insertion (0x%x)",
3759 ISP_READ(isp, OUTMAILBOX1));
3760 break;
3761 case ASYNC_TRANSCEIVER_REMOVAL:
3762 isp_prt(isp, ISP_LOGDEBUG0, "Transceiver removal");
3763 break;
3764 case ASYNC_NIC_FW_STATE_CHANGE:
3765 isp_prt(isp, ISP_LOGDEBUG0, "NIC Firmware State Change");
3766 break;
3767 case ASYNC_AUTOLOAD_FW_COMPLETE:
3768 isp_prt(isp, ISP_LOGDEBUG0, "Autoload FW init complete");
3769 break;
3770 case ASYNC_AUTOLOAD_FW_FAILURE:
3771 isp_prt(isp, ISP_LOGERR, "Autoload FW init failure");
3772 break;
3773 default:
3774 isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
3775 break;
3776 }
3777 }
3778
3779 /*
3780 * Handle completions with control handles by waking up waiting threads.
3781 */
3782 static int
isp_handle_control(ispsoftc_t * isp,isphdr_t * hp)3783 isp_handle_control(ispsoftc_t *isp, isphdr_t *hp)
3784 {
3785 uint32_t hdl;
3786 void *ptr;
3787
3788 switch (hp->rqs_entry_type) {
3789 case RQSTYPE_RESPONSE:
3790 case RQSTYPE_MARKER:
3791 case RQSTYPE_NOTIFY_ACK:
3792 case RQSTYPE_CTIO7:
3793 case RQSTYPE_TSK_MGMT:
3794 case RQSTYPE_CT_PASSTHRU:
3795 case RQSTYPE_VP_MODIFY:
3796 case RQSTYPE_VP_CTRL:
3797 case RQSTYPE_ABORT_IO:
3798 case RQSTYPE_MBOX:
3799 case RQSTYPE_LOGIN:
3800 case RQSTYPE_ELS_PASSTHRU:
3801 ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl);
3802 if (ISP_H2HT(hdl) != ISP_HANDLE_CTRL)
3803 break;
3804 ptr = isp_find_xs(isp, hdl);
3805 if (ptr != NULL) {
3806 isp_destroy_handle(isp, hdl);
3807 memcpy(ptr, hp, QENTRY_LEN);
3808 wakeup(ptr);
3809 }
3810 return (1);
3811 }
3812 return (0);
3813 }
3814
3815 static void
isp_handle_rpt_id_acq(ispsoftc_t * isp,isphdr_t * hp)3816 isp_handle_rpt_id_acq(ispsoftc_t *isp, isphdr_t *hp)
3817 {
3818 fcparam *fcp;
3819 isp_ridacq_t rid;
3820 int chan, c;
3821 uint32_t portid;
3822
3823 isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
3824 portid = (uint32_t)rid.ridacq_vp_port_hi << 16 |
3825 rid.ridacq_vp_port_lo;
3826 if (rid.ridacq_format == 0) {
3827 for (chan = 0; chan < isp->isp_nchan; chan++) {
3828 fcp = FCPARAM(isp, chan);
3829 if (fcp->role == ISP_ROLE_NONE)
3830 continue;
3831 c = (chan == 0) ? 127 : (chan - 1);
3832 if (rid.ridacq_map[c / 16] & (1 << (c % 16)) ||
3833 chan == 0) {
3834 fcp->isp_loopstate = LOOP_HAVE_LINK;
3835 isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3836 chan, ISPASYNC_CHANGE_OTHER);
3837 } else {
3838 fcp->isp_loopstate = LOOP_NIL;
3839 isp_async(isp, ISPASYNC_LOOP_DOWN,
3840 chan);
3841 }
3842 }
3843 } else {
3844 fcp = FCPARAM(isp, rid.ridacq_vp_index);
3845 if (rid.ridacq_vp_status == RIDACQ_STS_COMPLETE ||
3846 rid.ridacq_vp_status == RIDACQ_STS_CHANGED) {
3847 fcp->isp_topo = (rid.ridacq_map[0] >> 9) & 0x7;
3848 fcp->isp_portid = portid;
3849 fcp->isp_loopstate = LOOP_HAVE_ADDR;
3850 isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3851 rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER);
3852 } else {
3853 fcp->isp_loopstate = LOOP_NIL;
3854 isp_async(isp, ISPASYNC_LOOP_DOWN,
3855 rid.ridacq_vp_index);
3856 }
3857 }
3858 }
3859
3860 static void
isp_parse_status_24xx(ispsoftc_t * isp,isp24xx_statusreq_t * sp,XS_T * xs)3861 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs)
3862 {
3863 int ru_marked, sv_marked;
3864 int chan = XS_CHANNEL(xs);
3865
3866 switch (sp->req_completion_status) {
3867 case RQCS_COMPLETE:
3868 return;
3869
3870 case RQCS_DMA_ERROR:
3871 isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
3872 if (XS_NOERR(xs))
3873 XS_SETERR(xs, HBA_BOTCH);
3874 break;
3875
3876 case RQCS_TRANSPORT_ERROR:
3877 isp_xs_prt(isp, xs, ISP_LOGERR, "Transport Error");
3878 if (XS_NOERR(xs))
3879 XS_SETERR(xs, HBA_BOTCH);
3880 break;
3881
3882 case RQCS_RESET_OCCURRED:
3883 isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
3884 FCPARAM(isp, chan)->sendmarker = 1;
3885 if (XS_NOERR(xs))
3886 XS_SETERR(xs, HBA_BUSRESET);
3887 return;
3888
3889 case RQCS_ABORTED:
3890 isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
3891 FCPARAM(isp, chan)->sendmarker = 1;
3892 if (XS_NOERR(xs))
3893 XS_SETERR(xs, HBA_ABORTED);
3894 return;
3895
3896 case RQCS_TIMEOUT:
3897 isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
3898 if (XS_NOERR(xs))
3899 XS_SETERR(xs, HBA_CMDTIMEOUT);
3900 return;
3901
3902 case RQCS_DATA_OVERRUN:
3903 XS_SET_RESID(xs, sp->req_resid);
3904 isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
3905 if (XS_NOERR(xs))
3906 XS_SETERR(xs, HBA_DATAOVR);
3907 return;
3908
3909 case RQCS_DRE: /* data reassembly error */
3910 isp_prt(isp, ISP_LOGERR, "Chan %d data reassembly error for target %d", chan, XS_TGT(xs));
3911 if (XS_NOERR(xs))
3912 XS_SETERR(xs, HBA_BOTCH);
3913 return;
3914
3915 case RQCS_TABORT: /* aborted by target */
3916 isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS", chan, XS_TGT(xs));
3917 if (XS_NOERR(xs))
3918 XS_SETERR(xs, HBA_ABORTED);
3919 return;
3920
3921 case RQCS_DATA_UNDERRUN:
3922 ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
3923 /*
3924 * We can get an underrun w/o things being marked
3925 * if we got a non-zero status.
3926 */
3927 sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
3928 if ((ru_marked == 0 && sv_marked == 0) ||
3929 (sp->req_resid > XS_XFRLEN(xs))) {
3930 isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
3931 if (XS_NOERR(xs))
3932 XS_SETERR(xs, HBA_BOTCH);
3933 return;
3934 }
3935 XS_SET_RESID(xs, sp->req_resid);
3936 isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
3937 return;
3938
3939 case RQCS_PORT_UNAVAILABLE:
3940 /*
3941 * No such port on the loop. Moral equivalent of SELTIMEO
3942 */
3943 case RQCS_PORT_LOGGED_OUT:
3944 {
3945 const char *reason;
3946 uint8_t sts = sp->req_completion_status & 0xff;
3947 fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
3948 fcportdb_t *lp;
3949
3950 /*
3951 * It was there (maybe)- treat as a selection timeout.
3952 */
3953 if (sts == RQCS_PORT_UNAVAILABLE) {
3954 reason = "unavailable";
3955 } else {
3956 reason = "logout";
3957 }
3958
3959 isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
3960 chan, reason, XS_TGT(xs));
3961
3962 /* XXX: Should we trigger rescan or FW announce change? */
3963
3964 if (XS_NOERR(xs)) {
3965 lp = &fcp->portdb[XS_TGT(xs)];
3966 if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3967 *XS_STSP(xs) = SCSI_BUSY;
3968 XS_SETERR(xs, HBA_TGTBSY);
3969 } else
3970 XS_SETERR(xs, HBA_SELTIMEOUT);
3971 }
3972 return;
3973 }
3974 case RQCS_PORT_CHANGED:
3975 isp_prt(isp, ISP_LOGWARN, "port changed for target %d chan %d", XS_TGT(xs), chan);
3976 if (XS_NOERR(xs)) {
3977 *XS_STSP(xs) = SCSI_BUSY;
3978 XS_SETERR(xs, HBA_TGTBSY);
3979 }
3980 return;
3981
3982 case RQCS_ENOMEM: /* f/w resource unavailable */
3983 isp_prt(isp, ISP_LOGWARN, "f/w resource unavailable for target %d chan %d", XS_TGT(xs), chan);
3984 if (XS_NOERR(xs)) {
3985 *XS_STSP(xs) = SCSI_BUSY;
3986 XS_SETERR(xs, HBA_TGTBSY);
3987 }
3988 return;
3989
3990 case RQCS_TMO: /* task management overrun */
3991 isp_prt(isp, ISP_LOGWARN, "command for target %d overlapped task management for chan %d", XS_TGT(xs), chan);
3992 if (XS_NOERR(xs)) {
3993 *XS_STSP(xs) = SCSI_BUSY;
3994 XS_SETERR(xs, HBA_TGTBSY);
3995 }
3996 return;
3997
3998 default:
3999 isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x on chan %d", sp->req_completion_status, chan);
4000 break;
4001 }
4002 if (XS_NOERR(xs))
4003 XS_SETERR(xs, HBA_BOTCH);
4004 }
4005
4006 #define ISP_FC_IBITS(op) ((mbpfc[((op)<<3) + 0] << 24) | (mbpfc[((op)<<3) + 1] << 16) | (mbpfc[((op)<<3) + 2] << 8) | (mbpfc[((op)<<3) + 3]))
4007 #define ISP_FC_OBITS(op) ((mbpfc[((op)<<3) + 4] << 24) | (mbpfc[((op)<<3) + 5] << 16) | (mbpfc[((op)<<3) + 6] << 8) | (mbpfc[((op)<<3) + 7]))
4008
4009 #define ISP_FC_OPMAP(in0, out0) 0, 0, 0, in0, 0, 0, 0, out0
4010 #define ISP_FC_OPMAP_HALF(in1, in0, out1, out0) 0, 0, in1, in0, 0, 0, out1, out0
4011 #define ISP_FC_OPMAP_FULL(in3, in2, in1, in0, out3, out2, out1, out0) in3, in2, in1, in0, out3, out2, out1, out0
4012 static const uint32_t mbpfc[] = {
4013 ISP_FC_OPMAP(0x01, 0x01), /* 0x00: MBOX_NO_OP */
4014 ISP_FC_OPMAP(0x1f, 0x01), /* 0x01: MBOX_LOAD_RAM */
4015 ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x1f), /* 0x02: MBOX_EXEC_FIRMWARE */
4016 ISP_FC_OPMAP(0x01, 0x07), /* 0x03: MBOX_LOAD_FLASH_FIRMWARE */
4017 ISP_FC_OPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */
4018 ISP_FC_OPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */
4019 ISP_FC_OPMAP_FULL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */
4020 ISP_FC_OPMAP(0x07, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */
4021 ISP_FC_OPMAP_FULL(0x0, 0x0, 0x0, 0x01, 0x0, 0x3, 0x80, 0x7f), /* 0x08: MBOX_ABOUT_FIRMWARE */
4022 ISP_FC_OPMAP(0xdf, 0x01), /* 0x09: MBOX_LOAD_RISC_RAM_2100 */
4023 ISP_FC_OPMAP(0xdf, 0x01), /* 0x0a: MBOX_DUMP_RISC_RAM_2100 */
4024 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x01), /* 0x0b: MBOX_LOAD_RISC_RAM */
4025 ISP_FC_OPMAP(0x00, 0x00), /* 0x0c: */
4026 ISP_FC_OPMAP_HALF(0x1, 0x0f, 0x0, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
4027 ISP_FC_OPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */
4028 ISP_FC_OPMAP_HALF(0x1, 0x03, 0x0, 0x0d), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
4029 ISP_FC_OPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */
4030 ISP_FC_OPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */
4031 ISP_FC_OPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */
4032 ISP_FC_OPMAP(0x03, 0x03), /* 0x13: MBOX_WAKE_UP */
4033 ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x03), /* 0x14: MBOX_STOP_FIRMWARE */
4034 ISP_FC_OPMAP(0x4f, 0x01), /* 0x15: MBOX_ABORT */
4035 ISP_FC_OPMAP(0x07, 0x01), /* 0x16: MBOX_ABORT_DEVICE */
4036 ISP_FC_OPMAP(0x07, 0x01), /* 0x17: MBOX_ABORT_TARGET */
4037 ISP_FC_OPMAP(0x03, 0x03), /* 0x18: MBOX_BUS_RESET */
4038 ISP_FC_OPMAP(0x07, 0x05), /* 0x19: MBOX_STOP_QUEUE */
4039 ISP_FC_OPMAP(0x07, 0x05), /* 0x1a: MBOX_START_QUEUE */
4040 ISP_FC_OPMAP(0x07, 0x05), /* 0x1b: MBOX_SINGLE_STEP_QUEUE */
4041 ISP_FC_OPMAP(0x07, 0x05), /* 0x1c: MBOX_ABORT_QUEUE */
4042 ISP_FC_OPMAP(0x07, 0x03), /* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
4043 ISP_FC_OPMAP(0x00, 0x00), /* 0x1e: */
4044 ISP_FC_OPMAP(0x01, 0x07), /* 0x1f: MBOX_GET_FIRMWARE_STATUS */
4045 ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf), /* 0x20: MBOX_GET_LOOP_ID */
4046 ISP_FC_OPMAP(0x00, 0x00), /* 0x21: */
4047 ISP_FC_OPMAP(0x03, 0x4b), /* 0x22: MBOX_GET_TIMEOUT_PARAMS */
4048 ISP_FC_OPMAP(0x00, 0x00), /* 0x23: */
4049 ISP_FC_OPMAP(0x00, 0x00), /* 0x24: */
4050 ISP_FC_OPMAP(0x00, 0x00), /* 0x25: */
4051 ISP_FC_OPMAP(0x00, 0x00), /* 0x26: */
4052 ISP_FC_OPMAP(0x00, 0x00), /* 0x27: */
4053 ISP_FC_OPMAP(0x01, 0x03), /* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
4054 ISP_FC_OPMAP(0x03, 0x07), /* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
4055 ISP_FC_OPMAP(0x00, 0x00), /* 0x2a: */
4056 ISP_FC_OPMAP(0x00, 0x00), /* 0x2b: */
4057 ISP_FC_OPMAP(0x00, 0x00), /* 0x2c: */
4058 ISP_FC_OPMAP(0x00, 0x00), /* 0x2d: */
4059 ISP_FC_OPMAP(0x00, 0x00), /* 0x2e: */
4060 ISP_FC_OPMAP(0x00, 0x00), /* 0x2f: */
4061 ISP_FC_OPMAP(0x00, 0x00), /* 0x30: */
4062 ISP_FC_OPMAP(0x00, 0x00), /* 0x31: */
4063 ISP_FC_OPMAP(0x4b, 0x4b), /* 0x32: MBOX_SET_TIMEOUT_PARAMS */
4064 ISP_FC_OPMAP(0x00, 0x00), /* 0x33: */
4065 ISP_FC_OPMAP(0x00, 0x00), /* 0x34: */
4066 ISP_FC_OPMAP(0x00, 0x00), /* 0x35: */
4067 ISP_FC_OPMAP(0x00, 0x00), /* 0x36: */
4068 ISP_FC_OPMAP(0x00, 0x00), /* 0x37: */
4069 ISP_FC_OPMAP(0x0f, 0x01), /* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
4070 ISP_FC_OPMAP(0x0f, 0x07), /* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
4071 ISP_FC_OPMAP(0x00, 0x00), /* 0x3a: */
4072 ISP_FC_OPMAP(0x00, 0x00), /* 0x3b: */
4073 ISP_FC_OPMAP(0x00, 0x00), /* 0x3c: */
4074 ISP_FC_OPMAP(0x00, 0x00), /* 0x3d: */
4075 ISP_FC_OPMAP(0x00, 0x00), /* 0x3e: */
4076 ISP_FC_OPMAP(0x00, 0x00), /* 0x3f: */
4077 ISP_FC_OPMAP(0x03, 0x01), /* 0x40: MBOX_LOOP_PORT_BYPASS */
4078 ISP_FC_OPMAP(0x03, 0x01), /* 0x41: MBOX_LOOP_PORT_ENABLE */
4079 ISP_FC_OPMAP_HALF(0x0, 0x01, 0x1f, 0xcf), /* 0x42: MBOX_GET_RESOURCE_COUNT */
4080 ISP_FC_OPMAP(0x01, 0x01), /* 0x43: MBOX_REQUEST_OFFLINE_MODE */
4081 ISP_FC_OPMAP(0x00, 0x00), /* 0x44: */
4082 ISP_FC_OPMAP(0x00, 0x00), /* 0x45: */
4083 ISP_FC_OPMAP(0x00, 0x00), /* 0x46: */
4084 ISP_FC_OPMAP(0xcf, 0x03), /* 0x47: GET PORT_DATABASE ENHANCED */
4085 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
4086 ISP_FC_OPMAP(0xcd, 0x01), /* 0x49: MBOX_GET_VP_DATABASE */
4087 ISP_FC_OPMAP_HALF(0x2, 0xcd, 0x0, 0x01), /* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
4088 ISP_FC_OPMAP(0x00, 0x00), /* 0x4b: */
4089 ISP_FC_OPMAP(0x00, 0x00), /* 0x4c: */
4090 ISP_FC_OPMAP(0x00, 0x00), /* 0x4d: */
4091 ISP_FC_OPMAP(0x00, 0x00), /* 0x4e: */
4092 ISP_FC_OPMAP(0x00, 0x00), /* 0x4f: */
4093 ISP_FC_OPMAP(0x00, 0x00), /* 0x50: */
4094 ISP_FC_OPMAP(0x00, 0x00), /* 0x51: */
4095 ISP_FC_OPMAP(0x00, 0x00), /* 0x52: */
4096 ISP_FC_OPMAP(0x00, 0x00), /* 0x53: */
4097 ISP_FC_OPMAP(0xcf, 0x01), /* 0x54: EXECUTE IOCB A64 */
4098 ISP_FC_OPMAP(0x00, 0x00), /* 0x55: */
4099 ISP_FC_OPMAP(0x00, 0x00), /* 0x56: */
4100 ISP_FC_OPMAP(0x00, 0x00), /* 0x57: */
4101 ISP_FC_OPMAP(0x00, 0x00), /* 0x58: */
4102 ISP_FC_OPMAP(0x00, 0x00), /* 0x59: */
4103 ISP_FC_OPMAP(0x00, 0x00), /* 0x5a: */
4104 ISP_FC_OPMAP(0x03, 0x01), /* 0x5b: MBOX_DRIVER_HEARTBEAT */
4105 ISP_FC_OPMAP(0xcf, 0x01), /* 0x5c: MBOX_FW_HEARTBEAT */
4106 ISP_FC_OPMAP(0x07, 0x1f), /* 0x5d: MBOX_GET_SET_DATA_RATE */
4107 ISP_FC_OPMAP(0x00, 0x00), /* 0x5e: */
4108 ISP_FC_OPMAP(0x00, 0x00), /* 0x5f: */
4109 ISP_FC_OPMAP(0xcf, 0x0f), /* 0x60: MBOX_INIT_FIRMWARE */
4110 ISP_FC_OPMAP(0x00, 0x00), /* 0x61: */
4111 ISP_FC_OPMAP(0x01, 0x01), /* 0x62: MBOX_INIT_LIP */
4112 ISP_FC_OPMAP(0xcd, 0x03), /* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
4113 ISP_FC_OPMAP(0xcf, 0x01), /* 0x64: MBOX_GET_PORT_DB */
4114 ISP_FC_OPMAP(0x07, 0x01), /* 0x65: MBOX_CLEAR_ACA */
4115 ISP_FC_OPMAP(0x07, 0x01), /* 0x66: MBOX_TARGET_RESET */
4116 ISP_FC_OPMAP(0x07, 0x01), /* 0x67: MBOX_CLEAR_TASK_SET */
4117 ISP_FC_OPMAP(0x07, 0x01), /* 0x68: MBOX_ABORT_TASK_SET */
4118 ISP_FC_OPMAP_HALF(0x00, 0x01, 0x0f, 0x1f), /* 0x69: MBOX_GET_FW_STATE */
4119 ISP_FC_OPMAP_HALF(0x6, 0x03, 0x0, 0xcf), /* 0x6a: MBOX_GET_PORT_NAME */
4120 ISP_FC_OPMAP(0xcf, 0x01), /* 0x6b: MBOX_GET_LINK_STATUS */
4121 ISP_FC_OPMAP(0x0f, 0x01), /* 0x6c: MBOX_INIT_LIP_RESET */
4122 ISP_FC_OPMAP(0x00, 0x00), /* 0x6d: */
4123 ISP_FC_OPMAP(0xcf, 0x03), /* 0x6e: MBOX_SEND_SNS */
4124 ISP_FC_OPMAP(0x0f, 0x07), /* 0x6f: MBOX_FABRIC_LOGIN */
4125 ISP_FC_OPMAP_HALF(0x02, 0x03, 0x00, 0x03), /* 0x70: MBOX_SEND_CHANGE_REQUEST */
4126 ISP_FC_OPMAP(0x03, 0x03), /* 0x71: MBOX_FABRIC_LOGOUT */
4127 ISP_FC_OPMAP(0x0f, 0x0f), /* 0x72: MBOX_INIT_LIP_LOGIN */
4128 ISP_FC_OPMAP(0x00, 0x00), /* 0x73: */
4129 ISP_FC_OPMAP(0x07, 0x01), /* 0x74: LOGIN LOOP PORT */
4130 ISP_FC_OPMAP_HALF(0x03, 0xcf, 0x00, 0x07), /* 0x75: GET PORT/NODE NAME LIST */
4131 ISP_FC_OPMAP(0x4f, 0x01), /* 0x76: SET VENDOR ID */
4132 ISP_FC_OPMAP(0xcd, 0x01), /* 0x77: INITIALIZE IP MAILBOX */
4133 ISP_FC_OPMAP(0x00, 0x00), /* 0x78: */
4134 ISP_FC_OPMAP(0x00, 0x00), /* 0x79: */
4135 ISP_FC_OPMAP(0x00, 0x00), /* 0x7a: */
4136 ISP_FC_OPMAP(0x00, 0x00), /* 0x7b: */
4137 ISP_FC_OPMAP_HALF(0x03, 0x4f, 0x00, 0x07), /* 0x7c: Get ID List */
4138 ISP_FC_OPMAP(0xcf, 0x01), /* 0x7d: SEND LFA */
4139 ISP_FC_OPMAP(0x0f, 0x01) /* 0x7e: LUN RESET */
4140 };
4141 #define MAX_FC_OPCODE 0x7e
4142 /*
4143 * Footnotes
4144 *
4145 * (1): this sets bits 21..16 in mailbox register #8, which we nominally
4146 * do not access at this time in the core driver. The caller is
4147 * responsible for setting this register first (Gross!). The assumption
4148 * is that we won't overflow.
4149 */
4150
4151 static const char *fc_mbcmd_names[] = {
4152 "NO-OP", /* 00h */
4153 "LOAD RAM",
4154 "EXEC FIRMWARE",
4155 "LOAD FLASH FIRMWARE",
4156 "WRITE RAM WORD",
4157 "READ RAM WORD",
4158 "MAILBOX REG TEST",
4159 "VERIFY CHECKSUM",
4160 "ABOUT FIRMWARE",
4161 "LOAD RAM (2100)",
4162 "DUMP RAM (2100)",
4163 "LOAD RISC RAM",
4164 "DUMP RISC RAM",
4165 "WRITE RAM WORD EXTENDED",
4166 "CHECK FIRMWARE",
4167 "READ RAM WORD EXTENDED",
4168 "INIT REQUEST QUEUE", /* 10h */
4169 "INIT RESULT QUEUE",
4170 "EXECUTE IOCB",
4171 "WAKE UP",
4172 "STOP FIRMWARE",
4173 "ABORT",
4174 "ABORT DEVICE",
4175 "ABORT TARGET",
4176 "BUS RESET",
4177 "STOP QUEUE",
4178 "START QUEUE",
4179 "SINGLE STEP QUEUE",
4180 "ABORT QUEUE",
4181 "GET DEV QUEUE STATUS",
4182 NULL,
4183 "GET FIRMWARE STATUS",
4184 "GET LOOP ID", /* 20h */
4185 NULL,
4186 "GET TIMEOUT PARAMS",
4187 NULL,
4188 NULL,
4189 NULL,
4190 NULL,
4191 NULL,
4192 "GET FIRMWARE OPTIONS",
4193 "GET PORT QUEUE PARAMS",
4194 "GENERATE SYSTEM ERROR",
4195 NULL,
4196 NULL,
4197 NULL,
4198 NULL,
4199 NULL,
4200 "WRITE SFP", /* 30h */
4201 "READ SFP",
4202 "SET TIMEOUT PARAMS",
4203 NULL,
4204 NULL,
4205 NULL,
4206 NULL,
4207 NULL,
4208 "SET FIRMWARE OPTIONS",
4209 "SET PORT QUEUE PARAMS",
4210 NULL,
4211 "SET FC LED CONF",
4212 NULL,
4213 "RESTART NIC FIRMWARE",
4214 "ACCESS CONTROL",
4215 NULL,
4216 "LOOP PORT BYPASS", /* 40h */
4217 "LOOP PORT ENABLE",
4218 "GET RESOURCE COUNT",
4219 "REQUEST NON PARTICIPATING MODE",
4220 "DIAGNOSTIC ECHO TEST",
4221 "DIAGNOSTIC LOOPBACK",
4222 NULL,
4223 "GET PORT DATABASE ENHANCED",
4224 "INIT FIRMWARE MULTI ID",
4225 "GET VP DATABASE",
4226 "GET VP DATABASE ENTRY",
4227 NULL,
4228 NULL,
4229 NULL,
4230 NULL,
4231 NULL,
4232 "GET FCF LIST", /* 50h */
4233 "GET DCBX PARAMETERS",
4234 NULL,
4235 "HOST MEMORY COPY",
4236 "EXECUTE IOCB A64",
4237 NULL,
4238 NULL,
4239 "SEND RNID",
4240 NULL,
4241 "SET PARAMETERS",
4242 "GET PARAMETERS",
4243 "DRIVER HEARTBEAT",
4244 "FIRMWARE HEARTBEAT",
4245 "GET/SET DATA RATE",
4246 "SEND RNFT",
4247 NULL,
4248 "INIT FIRMWARE", /* 60h */
4249 "GET INIT CONTROL BLOCK",
4250 "INIT LIP",
4251 "GET FC-AL POSITION MAP",
4252 "GET PORT DATABASE",
4253 "CLEAR ACA",
4254 "TARGET RESET",
4255 "CLEAR TASK SET",
4256 "ABORT TASK SET",
4257 "GET FW STATE",
4258 "GET PORT NAME",
4259 "GET LINK STATUS",
4260 "INIT LIP RESET",
4261 "GET LINK STATS & PRIVATE DATA CNTS",
4262 "SEND SNS",
4263 "FABRIC LOGIN",
4264 "SEND CHANGE REQUEST", /* 70h */
4265 "FABRIC LOGOUT",
4266 "INIT LIP LOGIN",
4267 NULL,
4268 "LOGIN LOOP PORT",
4269 "GET PORT/NODE NAME LIST",
4270 "SET VENDOR ID",
4271 "INITIALIZE IP MAILBOX",
4272 NULL,
4273 NULL,
4274 "GET XGMAC STATS",
4275 NULL,
4276 "GET ID LIST",
4277 "SEND LFA",
4278 "LUN RESET"
4279 };
4280
4281 static void
isp_mboxcmd(ispsoftc_t * isp,mbreg_t * mbp)4282 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
4283 {
4284 const char *cname, *xname, *sname;
4285 char tname[16], mname[16];
4286 unsigned int ibits, obits, box, opcode, t, to;
4287
4288 opcode = mbp->param[0];
4289 if (opcode > MAX_FC_OPCODE) {
4290 mbp->param[0] = MBOX_INVALID_COMMAND;
4291 isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
4292 return;
4293 }
4294 cname = fc_mbcmd_names[opcode];
4295 ibits = ISP_FC_IBITS(opcode);
4296 obits = ISP_FC_OBITS(opcode);
4297 if (cname == NULL) {
4298 cname = tname;
4299 ISP_SNPRINTF(tname, sizeof(tname), "opcode %x", opcode);
4300 }
4301 isp_prt(isp, ISP_LOGDEBUG3, "Mailbox Command '%s'", cname);
4302
4303 /*
4304 * Pick up any additional bits that the caller might have set.
4305 */
4306 ibits |= mbp->ibits;
4307 obits |= mbp->obits;
4308
4309 /*
4310 * Mask any bits that the caller wants us to mask
4311 */
4312 ibits &= mbp->ibitm;
4313 obits &= mbp->obitm;
4314
4315
4316 if (ibits == 0 && obits == 0) {
4317 mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
4318 isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
4319 return;
4320 }
4321
4322 for (box = 0; box < ISP_NMBOX(isp); box++) {
4323 if (ibits & (1 << box)) {
4324 isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
4325 mbp->param[box]);
4326 ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
4327 }
4328 isp->isp_mboxtmp[box] = mbp->param[box] = 0;
4329 }
4330
4331 isp->isp_obits = obits;
4332 isp->isp_mboxbsy = 1;
4333
4334 /*
4335 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
4336 */
4337 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
4338
4339 /*
4340 * While we haven't finished the command, spin our wheels here.
4341 */
4342 to = (mbp->timeout == 0) ? MBCMD_DEFAULT_TIMEOUT : mbp->timeout;
4343 for (t = 0; t < to; t += 100) {
4344 if (!isp->isp_mboxbsy)
4345 break;
4346 ISP_RUN_ISR(isp);
4347 if (!isp->isp_mboxbsy)
4348 break;
4349 ISP_DELAY(100);
4350 }
4351
4352 /*
4353 * Did the command time out?
4354 */
4355 if (isp->isp_mboxbsy) {
4356 isp->isp_mboxbsy = 0;
4357 isp_prt(isp, ISP_LOGWARN, "Mailbox Command (0x%x) Timeout (%uus) (%s:%d)",
4358 opcode, to, mbp->func, mbp->lineno);
4359 mbp->param[0] = MBOX_TIMEOUT;
4360 goto out;
4361 }
4362
4363 /*
4364 * Copy back output registers.
4365 */
4366 for (box = 0; box < ISP_NMBOX(isp); box++) {
4367 if (obits & (1 << box)) {
4368 mbp->param[box] = isp->isp_mboxtmp[box];
4369 isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
4370 mbp->param[box]);
4371 }
4372 }
4373
4374 out:
4375 if (mbp->logval == 0 || mbp->param[0] == MBOX_COMMAND_COMPLETE)
4376 return;
4377
4378 if ((mbp->param[0] & 0xbfe0) == 0 &&
4379 (mbp->logval & MBLOGMASK(mbp->param[0])) == 0)
4380 return;
4381
4382 xname = NULL;
4383 sname = "";
4384 switch (mbp->param[0]) {
4385 case MBOX_INVALID_COMMAND:
4386 xname = "INVALID COMMAND";
4387 break;
4388 case MBOX_HOST_INTERFACE_ERROR:
4389 xname = "HOST INTERFACE ERROR";
4390 break;
4391 case MBOX_TEST_FAILED:
4392 xname = "TEST FAILED";
4393 break;
4394 case MBOX_COMMAND_ERROR:
4395 xname = "COMMAND ERROR";
4396 ISP_SNPRINTF(mname, sizeof(mname), " subcode 0x%x",
4397 mbp->param[1]);
4398 sname = mname;
4399 break;
4400 case MBOX_COMMAND_PARAM_ERROR:
4401 xname = "COMMAND PARAMETER ERROR";
4402 break;
4403 case MBOX_PORT_ID_USED:
4404 xname = "PORT ID ALREADY IN USE";
4405 break;
4406 case MBOX_LOOP_ID_USED:
4407 xname = "LOOP ID ALREADY IN USE";
4408 break;
4409 case MBOX_ALL_IDS_USED:
4410 xname = "ALL LOOP IDS IN USE";
4411 break;
4412 case MBOX_NOT_LOGGED_IN:
4413 xname = "NOT LOGGED IN";
4414 break;
4415 case MBOX_LINK_DOWN_ERROR:
4416 xname = "LINK DOWN ERROR";
4417 break;
4418 case MBOX_LOOPBACK_ERROR:
4419 xname = "LOOPBACK ERROR";
4420 break;
4421 case MBOX_CHECKSUM_ERROR:
4422 xname = "CHECKSUM ERROR";
4423 break;
4424 case MBOX_INVALID_PRODUCT_KEY:
4425 xname = "INVALID PRODUCT KEY";
4426 break;
4427 case MBOX_REGS_BUSY:
4428 xname = "REGISTERS BUSY";
4429 break;
4430 case MBOX_TIMEOUT:
4431 xname = "TIMEOUT";
4432 break;
4433 default:
4434 ISP_SNPRINTF(mname, sizeof(mname), "error 0x%x", mbp->param[0]);
4435 xname = mname;
4436 break;
4437 }
4438 if (xname) {
4439 isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s%s)",
4440 cname, xname, sname);
4441 }
4442 }
4443
4444 static int
isp_fw_state(ispsoftc_t * isp,int chan)4445 isp_fw_state(ispsoftc_t *isp, int chan)
4446 {
4447 mbreg_t mbs;
4448
4449 MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
4450 isp_mboxcmd(isp, &mbs);
4451 if (mbs.param[0] == MBOX_COMMAND_COMPLETE)
4452 return (mbs.param[1]);
4453 return (FW_ERROR);
4454 }
4455
4456 static void
isp_setdfltfcparm(ispsoftc_t * isp,int chan)4457 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
4458 {
4459 fcparam *fcp = FCPARAM(isp, chan);
4460
4461 /*
4462 * Establish some default parameters.
4463 */
4464 fcp->role = DEFAULT_ROLE(isp, chan);
4465 fcp->isp_retry_delay = ICB_DFLT_RDELAY;
4466 fcp->isp_retry_count = ICB_DFLT_RCOUNT;
4467 fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
4468 fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
4469 fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
4470 fcp->isp_fwoptions = 0;
4471 fcp->isp_xfwoptions = 0;
4472 fcp->isp_zfwoptions = 0;
4473 fcp->isp_lasthdl = NIL_HANDLE;
4474 fcp->isp_login_hdl = NIL_HANDLE;
4475
4476 fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
4477 fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
4478 if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
4479 fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
4480 fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
4481 fcp->isp_xfwoptions |= ICB2400_OPT2_LOOP_2_PTP;
4482 fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO;
4483
4484 /*
4485 * Now try and read NVRAM unless told to not do so.
4486 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
4487 */
4488 if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
4489 int i, j = 0;
4490 /*
4491 * Give a couple of tries at reading NVRAM.
4492 */
4493 for (i = 0; i < 2; i++) {
4494 j = isp_read_nvram(isp);
4495 if (j == 0) {
4496 break;
4497 }
4498 }
4499 if (j) {
4500 isp->isp_confopts |= ISP_CFG_NONVRAM;
4501 }
4502 }
4503
4504 fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
4505 fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
4506 isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
4507 chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
4508 (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
4509 isp_class3_roles[fcp->role]);
4510 }
4511
4512 /*
4513 * Re-initialize the ISP and complete all orphaned commands
4514 * with a 'botched' notice. The reset/init routines should
4515 * not disturb an already active list of commands.
4516 */
4517
4518 int
isp_reinit(ispsoftc_t * isp,int do_load_defaults)4519 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
4520 {
4521 int i, res = 0;
4522
4523 if (isp->isp_state > ISP_RESETSTATE)
4524 isp_stop(isp);
4525 if (isp->isp_state != ISP_RESETSTATE)
4526 isp_reset(isp, do_load_defaults);
4527 if (isp->isp_state != ISP_RESETSTATE) {
4528 res = EIO;
4529 isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
4530 goto cleanup;
4531 }
4532
4533 isp_init(isp);
4534 if (isp->isp_state > ISP_RESETSTATE &&
4535 isp->isp_state != ISP_RUNSTATE) {
4536 res = EIO;
4537 isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__);
4538 ISP_DISABLE_INTS(isp);
4539 }
4540
4541 cleanup:
4542 isp_clear_commands(isp);
4543 for (i = 0; i < isp->isp_nchan; i++)
4544 isp_clear_portdb(isp, i);
4545 return (res);
4546 }
4547
4548 /*
4549 * NVRAM Routines
4550 */
4551 static inline uint32_t
flash_data_addr(ispsoftc_t * isp,uint32_t faddr)4552 flash_data_addr(ispsoftc_t *isp, uint32_t faddr)
4553 {
4554 fcparam *fcp = FCPARAM(isp, 0);
4555
4556 return (fcp->flash_data_addr + faddr);
4557 }
4558
4559 static int
isp_read_flash_dword(ispsoftc_t * isp,uint32_t addr,uint32_t * data)4560 isp_read_flash_dword(ispsoftc_t *isp, uint32_t addr, uint32_t *data)
4561 {
4562 int loops = 0;
4563
4564 ISP_WRITE(isp, BIU2400_FLASH_ADDR, addr & ~0x80000000);
4565 for (loops = 0; loops < 30000; loops++) {
4566 if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) {
4567 *data = ISP_READ(isp, BIU2400_FLASH_DATA);
4568 return (ISP_SUCCESS);
4569 }
4570 ISP_DELAY(10);
4571 }
4572 isp_prt(isp, ISP_LOGERR,
4573 "Flash read dword at 0x%x timeout.", addr);
4574 *data = 0xffffffff;
4575 return (ISP_FUNCTION_TIMEOUT);
4576 }
4577
4578 static int
isp_read_flash_data(ispsoftc_t * isp,uint32_t * dwptr,uint32_t faddr,uint32_t dwords)4579 isp_read_flash_data(ispsoftc_t *isp, uint32_t *dwptr, uint32_t faddr, uint32_t dwords)
4580 {
4581 int loops = 0;
4582 int rval = ISP_SUCCESS;
4583
4584 /* Dword reads to flash. */
4585 faddr = flash_data_addr(isp, faddr);
4586 for (loops = 0; loops < dwords; loops++, faddr++, dwptr++) {
4587 rval = isp_read_flash_dword(isp, faddr, dwptr);
4588 if (rval != ISP_SUCCESS)
4589 break;
4590 *dwptr = htole32(*dwptr);
4591 }
4592
4593 return (rval);
4594 }
4595
4596 static void
isp_rd_2xxx_flash(ispsoftc_t * isp,uint32_t addr,uint32_t * rp)4597 isp_rd_2xxx_flash(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
4598 {
4599 fcparam *fcp = FCPARAM(isp, 0);
4600 int loops = 0;
4601 uint32_t base = fcp->flash_data_addr;
4602
4603 ISP_WRITE(isp, BIU2400_FLASH_ADDR, (base + addr) & ~0x80000000);
4604 for (loops = 0; loops < 30000; loops++) {
4605 ISP_DELAY(10);
4606 if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) {
4607 *rp = ISP_READ(isp, BIU2400_FLASH_DATA);
4608 ISP_SWIZZLE_NVRAM_LONG(isp, rp);
4609 return;
4610 }
4611 }
4612 isp_prt(isp, ISP_LOGERR,
4613 "Flash read dword at 0x%x timeout.", (base + addr));
4614 *rp = 0xffffffff;
4615 }
4616
4617 static int
isp_read_flthdr_2xxx(ispsoftc_t * isp)4618 isp_read_flthdr_2xxx(ispsoftc_t *isp)
4619 {
4620 fcparam *fcp = FCPARAM(isp, 0);
4621 int retval = 0;
4622 uint32_t addr, lwrds, *dptr;
4623 uint16_t csum;
4624 uint8_t flthdr_data[FLT_HEADER_SIZE];
4625
4626 addr = fcp->flt_region_flt;
4627 dptr = (uint32_t *) flthdr_data;
4628
4629 isp_prt(isp, ISP_LOGDEBUG0, "FLTL[DEF]: 0x%x", addr);
4630 for (lwrds = 0; lwrds < FLT_HEADER_SIZE >> 2; lwrds++) {
4631 isp_rd_2xxx_flash(isp, addr++, dptr++);
4632 }
4633 dptr = (uint32_t *) flthdr_data;
4634 for (csum = 0, lwrds = 0; lwrds < FLT_HEADER_SIZE >> 4; lwrds++) {
4635 uint16_t tmp;
4636 ISP_IOXGET_16(isp, &dptr[lwrds], tmp);
4637 csum += tmp;
4638 }
4639 if (csum != 0) {
4640 retval = -1;
4641 goto out;
4642 }
4643 isp_parse_flthdr_2xxx(isp, flthdr_data);
4644 out:
4645 return (retval);
4646 }
4647
4648 static void
isp_parse_flthdr_2xxx(ispsoftc_t * isp,uint8_t * flthdr_data)4649 isp_parse_flthdr_2xxx(ispsoftc_t *isp, uint8_t *flthdr_data)
4650 {
4651 fcparam *fcp = FCPARAM(isp, 0);
4652 uint16_t ver, csum;
4653
4654 ver = le16toh((uint16_t) (ISP2XXX_FLT_VERSION(flthdr_data)));
4655 fcp->flt_length = le16toh((uint16_t) (ISP2XXX_FLT_LENGTH(flthdr_data)));
4656 csum = le16toh((uint16_t) (ISP2XXX_FLT_CSUM(flthdr_data)));
4657
4658 if ((fcp->flt_length == 0) ||
4659 (fcp->flt_length > (FLT_HEADER_SIZE + FLT_REGIONS_SIZE))) {
4660 isp_prt(isp, ISP_LOGERR,
4661 "FLT[DEF]: Invalid length=0x%x(%d)",
4662 fcp->flt_length, fcp->flt_length);
4663 }
4664 isp_prt(isp, ISP_LOGDEBUG0,
4665 "FLT[DEF]: version=0x%x length=0x%x(%d) checksum=0x%x",
4666 ver, fcp->flt_length, fcp->flt_length, csum);
4667 }
4668
4669 static int
isp_read_flt_2xxx(ispsoftc_t * isp)4670 isp_read_flt_2xxx(ispsoftc_t *isp)
4671 {
4672 fcparam *fcp = FCPARAM(isp, 0);
4673 int retval = 0;
4674 int len = fcp->flt_length - FLT_HEADER_SIZE;
4675 uint32_t addr, lwrds, *dptr;
4676 uint8_t flt_data[len];
4677 fcp->flt_region_entries = len / FLT_REGION_SIZE;
4678
4679 addr = fcp->flt_region_flt + (FLT_HEADER_SIZE >> 2);
4680 dptr = (uint32_t *) flt_data;
4681 isp_prt(isp, ISP_LOGDEBUG0, "FLT[DEF]: regions=%d",
4682 fcp->flt_region_entries);
4683 for (lwrds = 0; lwrds < len >> 2; lwrds++) {
4684 isp_rd_2xxx_flash(isp, addr++, dptr++);
4685 }
4686 retval = isp_parse_flt_2xxx(isp, flt_data);
4687 return (retval);
4688 }
4689
4690 static int
isp_parse_flt_2xxx(ispsoftc_t * isp,uint8_t * flt_data)4691 isp_parse_flt_2xxx(ispsoftc_t *isp, uint8_t *flt_data)
4692 {
4693 fcparam *fcp = FCPARAM(isp, 0);
4694 int count;
4695 struct flt_region region[fcp->flt_region_entries];
4696
4697 for (count = 0; count < fcp->flt_region_entries; count++) {
4698 region[count].code =
4699 le16toh((uint16_t) (ISP2XXX_FLT_REG_CODE(flt_data, count)));
4700 region[count].attribute =
4701 (uint8_t) (ISP2XXX_FLT_REG_ATTR(flt_data, count));
4702 region[count].reserved =
4703 (uint8_t) (ISP2XXX_FLT_REG_RES(flt_data, count));
4704 region[count].size =
4705 le32toh((uint32_t) (ISP2XXX_FLT_REG_SIZE(flt_data, count)) >> 2);
4706 region[count].start =
4707 le32toh((uint32_t) (ISP2XXX_FLT_REG_START(flt_data, count)) >> 2);
4708 region[count].end =
4709 le32toh((uint32_t) (ISP2XXX_FLT_REG_END(flt_data, count)) >> 2);
4710
4711 isp_prt(isp, ISP_LOGDEBUG0,
4712 "FLT[0x%x]: start=0x%x end=0x%x size=0x%x attribute=0x%x",
4713 region[count].code, region[count].start, region[count].end,
4714 region[count].size, region[count].attribute);
4715
4716 switch (region[count].code) {
4717 case FLT_REG_FW:
4718 fcp->flt_region_fw = region[count].start;
4719 break;
4720 case FLT_REG_BOOT_CODE:
4721 fcp->flt_region_boot = region[count].start;
4722 break;
4723 case FLT_REG_VPD_0:
4724 fcp->flt_region_vpd_nvram = region[count].start;
4725 if (isp->isp_port == 0)
4726 fcp->flt_region_vpd = region[count].start;
4727 break;
4728 case FLT_REG_VPD_1:
4729 if (isp->isp_port == 1)
4730 fcp->flt_region_vpd = region[count].start;
4731 break;
4732 case FLT_REG_VPD_2:
4733 if (!IS_27XX(isp))
4734 break;
4735 if (isp->isp_port == 2)
4736 fcp->flt_region_vpd = region[count].start;
4737 break;
4738 case FLT_REG_VPD_3:
4739 if (!IS_27XX(isp))
4740 break;
4741 if (isp->isp_port == 3)
4742 fcp->flt_region_vpd = region[count].start;
4743 break;
4744 case FLT_REG_NVRAM_0:
4745 if (isp->isp_port == 0)
4746 fcp->flt_region_nvram = region[count].start;
4747 break;
4748 case FLT_REG_NVRAM_1:
4749 if (isp->isp_port == 1)
4750 fcp->flt_region_nvram = region[count].start;
4751 break;
4752 case FLT_REG_NVRAM_2:
4753 if (!IS_27XX(isp))
4754 break;
4755 if (isp->isp_port == 2)
4756 fcp->flt_region_nvram = region[count].start;
4757 break;
4758 case FLT_REG_NVRAM_3:
4759 if (!IS_27XX(isp))
4760 break;
4761 if (isp->isp_port == 3)
4762 fcp->flt_region_nvram = region[count].start;
4763 break;
4764 case FLT_REG_FDT:
4765 fcp->flt_region_fdt = region[count].start;
4766 break;
4767 case FLT_REG_FLT:
4768 fcp->flt_region_flt = region[count].start;
4769 break;
4770 case FLT_REG_NPIV_CONF_0:
4771 if (isp->isp_port == 0)
4772 fcp->flt_region_npiv_conf = region[count].start;
4773 break;
4774 case FLT_REG_NPIV_CONF_1:
4775 if (isp->isp_port == 1)
4776 fcp->flt_region_npiv_conf = region[count].start;
4777 break;
4778 case FLT_REG_GOLD_FW:
4779 fcp->flt_region_gold_fw = region[count].start;
4780 break;
4781 case FLT_REG_FCP_PRIO_0:
4782 if (isp->isp_port == 0)
4783 fcp->flt_region_fcp_prio = region[count].start;
4784 break;
4785 case FLT_REG_FCP_PRIO_1:
4786 if (isp->isp_port == 1)
4787 fcp->flt_region_fcp_prio = region[count].start;
4788 break;
4789 case FLT_REG_IMG_PRI_27XX:
4790 if (IS_27XX(isp))
4791 fcp->flt_region_img_status_pri = region[count].start;
4792 break;
4793 case FLT_REG_IMG_SEC_27XX:
4794 if (IS_27XX(isp))
4795 fcp->flt_region_img_status_sec = region[count].start;
4796 break;
4797 case FLT_REG_FW_SEC_27XX:
4798 if (IS_27XX(isp))
4799 fcp->flt_region_fw_sec = region[count].start;
4800 break;
4801 case FLT_REG_BOOTLOAD_SEC_27XX:
4802 if (IS_27XX(isp))
4803 fcp->flt_region_boot_sec = region[count].start;
4804 break;
4805 case FLT_REG_AUX_IMG_PRI_28XX:
4806 if (IS_27XX(isp))
4807 fcp->flt_region_aux_img_status_pri = region[count].start;
4808 break;
4809 case FLT_REG_AUX_IMG_SEC_28XX:
4810 if (IS_27XX(isp))
4811 fcp->flt_region_aux_img_status_sec = region[count].start;
4812 break;
4813 case FLT_REG_NVRAM_SEC_28XX_0:
4814 if (IS_27XX(isp))
4815 if (isp->isp_port == 0)
4816 fcp->flt_region_nvram_sec = region[count].start;
4817 break;
4818 case FLT_REG_NVRAM_SEC_28XX_1:
4819 if (IS_27XX(isp))
4820 if (isp->isp_port == 1)
4821 fcp->flt_region_nvram_sec = region[count].start;
4822 break;
4823 case FLT_REG_NVRAM_SEC_28XX_2:
4824 if (IS_27XX(isp))
4825 if (isp->isp_port == 2)
4826 fcp->flt_region_nvram_sec = region[count].start;
4827 break;
4828 case FLT_REG_NVRAM_SEC_28XX_3:
4829 if (IS_27XX(isp))
4830 if (isp->isp_port == 3)
4831 fcp->flt_region_nvram_sec = region[count].start;
4832 break;
4833 case FLT_REG_VPD_SEC_27XX_0:
4834 case FLT_REG_VPD_SEC_28XX_0:
4835 if (IS_27XX(isp)) {
4836 fcp->flt_region_vpd_nvram_sec = region[count].start;
4837 if (isp->isp_port == 0)
4838 fcp->flt_region_vpd_sec = region[count].start;
4839 }
4840 break;
4841 case FLT_REG_VPD_SEC_27XX_1:
4842 case FLT_REG_VPD_SEC_28XX_1:
4843 if (IS_27XX(isp))
4844 if (isp->isp_port == 1)
4845 fcp->flt_region_vpd_sec = region[count].start;
4846 break;
4847 case FLT_REG_VPD_SEC_27XX_2:
4848 case FLT_REG_VPD_SEC_28XX_2:
4849 if (IS_27XX(isp))
4850 if (isp->isp_port == 2)
4851 fcp->flt_region_vpd_sec = region[count].start;
4852 break;
4853 case FLT_REG_VPD_SEC_27XX_3:
4854 case FLT_REG_VPD_SEC_28XX_3:
4855 if (IS_27XX(isp))
4856 if (isp->isp_port == 3)
4857 fcp->flt_region_vpd_sec = region[count].start;
4858 break;
4859 }
4860 }
4861 isp_prt(isp, ISP_LOGCONFIG,
4862 "FLT[FLT]: boot=0x%x fw=0x%x vpd_nvram=0x%x vpd=0x%x nvram=0x%x "
4863 "fdt=0x%x flt=0x%x npiv=0x%x fcp_prif_cfg=0x%x",
4864 fcp->flt_region_boot, fcp->flt_region_fw, fcp->flt_region_vpd_nvram,
4865 fcp->flt_region_vpd, fcp->flt_region_nvram, fcp->flt_region_fdt,
4866 fcp->flt_region_flt, fcp->flt_region_npiv_conf,
4867 fcp->flt_region_fcp_prio);
4868
4869 return (0);
4870 }
4871
4872 static void
isp_print_image(ispsoftc_t * isp,char * name,struct isp_image_status * image_status)4873 isp_print_image(ispsoftc_t *isp, char *name, struct isp_image_status *image_status)
4874 {
4875 isp_prt(isp, ISP_LOGDEBUG0,
4876 "%s %s: mask=0x%02x gen=0x%04x ver=%u.%u map=0x%01x sum=0x%08x sig=0x%08x",
4877 name, "status",
4878 image_status->image_status_mask,
4879 le16toh(image_status->generation),
4880 image_status->ver_major,
4881 image_status->ver_minor,
4882 image_status->bitmap,
4883 le32toh(image_status->checksum),
4884 le32toh(image_status->signature));
4885 }
4886
4887 static bool
isp_check_aux_image_status_signature(struct isp_image_status * image_status)4888 isp_check_aux_image_status_signature(struct isp_image_status *image_status)
4889 {
4890 unsigned long signature = le32toh(image_status->signature);
4891
4892 return (signature != ISP28XX_AUX_IMG_STATUS_SIGN);
4893 }
4894
4895 static bool
isp_check_image_status_signature(struct isp_image_status * image_status)4896 isp_check_image_status_signature(struct isp_image_status *image_status)
4897 {
4898 unsigned long signature = le32toh(image_status->signature);
4899
4900 return ((signature != ISP27XX_IMG_STATUS_SIGN) &&
4901 (signature != ISP28XX_IMG_STATUS_SIGN));
4902 }
4903
4904 static unsigned long
isp_image_status_checksum(struct isp_image_status * image_status)4905 isp_image_status_checksum(struct isp_image_status *image_status)
4906 {
4907 uint32_t *p = (uint32_t *)image_status;
4908 unsigned int n = sizeof(*image_status) / sizeof(*p);
4909 uint32_t sum = 0;
4910
4911 for ( ; n--; p++)
4912 sum += le32toh(*((uint32_t *)(p)));
4913
4914 return (sum);
4915 }
4916
4917 static inline unsigned int
isp_component_bitmask(struct isp_image_status * aux,unsigned int bitmask)4918 isp_component_bitmask(struct isp_image_status *aux, unsigned int bitmask)
4919 {
4920 return (aux->bitmap & bitmask ?
4921 ISP27XX_SECONDARY_IMAGE : ISP27XX_PRIMARY_IMAGE);
4922 }
4923
4924 static void
isp_component_status(struct active_regions * active_regions,struct isp_image_status * aux)4925 isp_component_status(struct active_regions *active_regions, struct isp_image_status *aux)
4926 {
4927 active_regions->aux.board_config =
4928 isp_component_bitmask(aux, ISP28XX_AUX_IMG_BOARD_CONFIG);
4929
4930 active_regions->aux.vpd_nvram =
4931 isp_component_bitmask(aux, ISP28XX_AUX_IMG_VPD_NVRAM);
4932
4933 active_regions->aux.npiv_config_0_1 =
4934 isp_component_bitmask(aux, ISP28XX_AUX_IMG_NPIV_CONFIG_0_1);
4935
4936 active_regions->aux.npiv_config_2_3 =
4937 isp_component_bitmask(aux, ISP28XX_AUX_IMG_NPIV_CONFIG_2_3);
4938
4939 active_regions->aux.nvme_params =
4940 isp_component_bitmask(aux, ISP28XX_AUX_IMG_NVME_PARAMS);
4941 }
4942
4943 static int
isp_compare_image_generation(ispsoftc_t * isp,struct isp_image_status * pri_image_status,struct isp_image_status * sec_image_status)4944 isp_compare_image_generation(ispsoftc_t *isp,
4945 struct isp_image_status *pri_image_status,
4946 struct isp_image_status *sec_image_status)
4947 {
4948 /* calculate generation delta as uint16 (this accounts for wrap) */
4949 int16_t delta =
4950 le16toh(pri_image_status->generation) -
4951 le16toh(sec_image_status->generation);
4952
4953 isp_prt(isp, ISP_LOGDEBUG0, "generation delta = %d", delta);
4954
4955 return (delta);
4956 }
4957
4958 static void
isp_get_aux_images(ispsoftc_t * isp,struct active_regions * active_regions)4959 isp_get_aux_images(ispsoftc_t *isp, struct active_regions *active_regions)
4960 {
4961 fcparam *fcp = FCPARAM(isp, 0);
4962 struct isp_image_status pri_aux_image_status, sec_aux_image_status;
4963 bool valid_pri_image = false, valid_sec_image = false;
4964 bool active_pri_image = false, active_sec_image = false;
4965
4966 if (!fcp->flt_region_aux_img_status_pri) {
4967 isp_prt(isp, ISP_LOGWARN,
4968 "Primary aux image not addressed");
4969 goto check_sec_image;
4970 }
4971
4972 isp_read_flash_data(isp, (uint32_t *)&pri_aux_image_status,
4973 fcp->flt_region_aux_img_status_pri,
4974 sizeof(pri_aux_image_status) >> 2);
4975 isp_print_image(isp, "Primary aux image", &pri_aux_image_status);
4976
4977 if (isp_check_aux_image_status_signature(&pri_aux_image_status)) {
4978 isp_prt(isp, ISP_LOGERR,
4979 "Primary aux image signature (0x%x) not valid",
4980 le32toh(pri_aux_image_status.signature));
4981 goto check_sec_image;
4982 }
4983
4984 if (isp_image_status_checksum(&pri_aux_image_status)) {
4985 isp_prt(isp, ISP_LOGERR,
4986 "Primary aux image checksum failed");
4987 goto check_sec_image;
4988 }
4989
4990 valid_pri_image = true;
4991
4992 if (pri_aux_image_status.image_status_mask & 1) {
4993 isp_prt(isp, ISP_LOGCONFIG,
4994 "Primary aux image is active");
4995 active_pri_image = true;
4996 }
4997
4998 check_sec_image:
4999 if (!fcp->flt_region_aux_img_status_sec) {
5000 isp_prt(isp, ISP_LOGWARN,
5001 "Secondary aux image not addressed");
5002 goto check_valid_image;
5003 }
5004
5005 isp_read_flash_data(isp, (uint32_t *)&sec_aux_image_status,
5006 fcp->flt_region_aux_img_status_sec,
5007 sizeof(sec_aux_image_status) >> 2);
5008 isp_print_image(isp, "Secondary aux image", &sec_aux_image_status);
5009
5010 if (isp_check_aux_image_status_signature(&sec_aux_image_status)) {
5011 isp_prt(isp, ISP_LOGERR,
5012 "Secondary aux image signature (0x%x) not valid",
5013 le32toh(sec_aux_image_status.signature));
5014 goto check_valid_image;
5015 }
5016
5017 if (isp_image_status_checksum(&sec_aux_image_status)) {
5018 isp_prt(isp, ISP_LOGERR,
5019 "Secondary aux image checksum failed");
5020 goto check_valid_image;
5021 }
5022
5023 valid_sec_image = true;
5024
5025 if (sec_aux_image_status.image_status_mask & 1) {
5026 isp_prt(isp, ISP_LOGCONFIG,
5027 "Secondary aux image is active");
5028 active_sec_image = true;
5029 }
5030
5031 check_valid_image:
5032 if (valid_pri_image && active_pri_image &&
5033 valid_sec_image && active_sec_image) {
5034 if (isp_compare_image_generation(isp, &pri_aux_image_status,
5035 &sec_aux_image_status) >= 0) {
5036 isp_component_status(active_regions,
5037 &pri_aux_image_status);
5038 } else {
5039 isp_component_status(active_regions,
5040 &sec_aux_image_status);
5041 }
5042 } else if (valid_pri_image && active_pri_image) {
5043 isp_component_status(active_regions, &pri_aux_image_status);
5044 } else if (valid_sec_image && active_sec_image) {
5045 isp_component_status(active_regions, &sec_aux_image_status);
5046 }
5047
5048 isp_prt(isp, ISP_LOGDEBUG0,
5049 "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u, NVME=%u",
5050 active_regions->aux.board_config,
5051 active_regions->aux.vpd_nvram,
5052 active_regions->aux.npiv_config_0_1,
5053 active_regions->aux.npiv_config_2_3,
5054 active_regions->aux.nvme_params);
5055 }
5056
5057 static void
isp_get_active_image(ispsoftc_t * isp,struct active_regions * active_regions)5058 isp_get_active_image(ispsoftc_t *isp, struct active_regions * active_regions)
5059 {
5060 fcparam *fcp = FCPARAM(isp, 0);
5061 struct isp_image_status pri_image_status, sec_image_status;
5062 bool valid_pri_image = false, valid_sec_image = false;
5063 bool active_pri_image = false, active_sec_image = false;
5064
5065 if (!fcp->flt_region_img_status_pri) {
5066 isp_prt(isp, ISP_LOGWARN,
5067 "Primary image not addressed");
5068 goto check_sec_image;
5069 }
5070
5071 if (isp_read_flash_data(isp, (uint32_t *) &pri_image_status,
5072 fcp->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) !=
5073 ISP_SUCCESS)
5074 goto check_sec_image;
5075
5076 isp_print_image(isp, "Primary image", &pri_image_status);
5077
5078 if (isp_check_image_status_signature(&pri_image_status)) {
5079 isp_prt(isp, ISP_LOGERR,
5080 "Primary image signature (0x%x) not valid",
5081 le32toh(pri_image_status.signature));
5082 goto check_sec_image;
5083 }
5084
5085 if (isp_image_status_checksum(&pri_image_status)) {
5086 isp_prt(isp, ISP_LOGERR,
5087 "Primary image checksum failed");
5088 goto check_sec_image;
5089 }
5090
5091 valid_pri_image = true;
5092
5093 if (pri_image_status.image_status_mask & 1) {
5094 isp_prt(isp, ISP_LOGCONFIG,
5095 "Primary image is active");
5096 active_pri_image = true;
5097 }
5098
5099 check_sec_image:
5100 if (!fcp->flt_region_img_status_sec) {
5101 isp_prt(isp, ISP_LOGWARN,
5102 "Secondary image not addressed");
5103 return;
5104 }
5105
5106 if (isp_read_flash_data(isp, (uint32_t *) &sec_image_status,
5107 fcp->flt_region_img_status_sec, sizeof(sec_image_status) >> 2) !=
5108 ISP_SUCCESS)
5109 return;
5110
5111 isp_print_image(isp, "Secondary image", &sec_image_status);
5112
5113 if (isp_check_image_status_signature(&sec_image_status)) {
5114 isp_prt(isp, ISP_LOGERR,
5115 "Secondary image signature (0x%x) not valid",
5116 le32toh(sec_image_status.signature));
5117 }
5118
5119 if (isp_image_status_checksum(&sec_image_status)) {
5120 isp_prt(isp, ISP_LOGERR,
5121 "Secondary image checksum failed");
5122 goto check_valid_image;
5123 }
5124
5125 valid_sec_image = true;
5126
5127 if (sec_image_status.image_status_mask & 1) {
5128 isp_prt(isp, ISP_LOGCONFIG,
5129 "Secondary image is active");
5130 active_sec_image = true;
5131 }
5132
5133 check_valid_image:
5134 if (valid_pri_image && active_pri_image)
5135 active_regions->global = ISP27XX_PRIMARY_IMAGE;
5136
5137 if (valid_sec_image && active_sec_image) {
5138 if (!active_regions->global ||
5139 isp_compare_image_generation(isp,
5140 &pri_image_status, &sec_image_status) < 0) {
5141 active_regions->global = ISP27XX_SECONDARY_IMAGE;
5142 }
5143 }
5144
5145 isp_prt(isp, ISP_LOGDEBUG0, "active image %s (%u)",
5146 active_regions->global == ISP27XX_DEFAULT_IMAGE ?
5147 "default (boot/fw)" :
5148 active_regions->global == ISP27XX_PRIMARY_IMAGE ?
5149 "primary" :
5150 active_regions->global == ISP27XX_SECONDARY_IMAGE ?
5151 "secondary" : "invalid",
5152 active_regions->global);
5153 }
5154
isp_risc_firmware_invalid(ispsoftc_t * isp,uint32_t * dword)5155 static bool isp_risc_firmware_invalid(ispsoftc_t *isp, uint32_t *dword)
5156 {
5157 return ((dword[4] | dword[5] | dword[6] | dword[7]) == 0 ||
5158 (~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]) == 0);
5159 }
5160
5161 static int
isp_load_ram(ispsoftc_t * isp,uint32_t * data,uint32_t risc_addr,uint32_t risc_code_size)5162 isp_load_ram(ispsoftc_t *isp, uint32_t *data, uint32_t risc_addr,
5163 uint32_t risc_code_size)
5164 {
5165 mbreg_t mbs;
5166 int rval = ISP_SUCCESS;
5167
5168 MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
5169 MBSINIT(&mbs, MBOX_LOAD_RISC_RAM, MBLOGALL, 0);
5170 mbs.param[1] = risc_addr;
5171 mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
5172 mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
5173 mbs.param[4] = risc_code_size >> 16;
5174 mbs.param[5] = risc_code_size;
5175 mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
5176 mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
5177 mbs.param[8] = risc_addr >> 16;
5178 isp_prt(isp, ISP_LOGDEBUG0,
5179 "LOAD RISC RAM %u (0x%x) words at load address 0x%x",
5180 risc_code_size, risc_code_size, risc_addr);
5181 isp_mboxcmd(isp, &mbs);
5182 if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
5183 isp_prt(isp, ISP_LOGERR, "F/W download failed");
5184 rval = ISP_FUNCTION_FAILED;
5185 }
5186
5187 return (rval);
5188 }
5189
5190 static int
isp_load_risc_flash(ispsoftc_t * isp,uint32_t * srisc_addr,uint32_t faddr)5191 isp_load_risc_flash(ispsoftc_t *isp, uint32_t *srisc_addr, uint32_t faddr)
5192 {
5193 fcparam *fcp = FCPARAM(isp, 0);
5194 int rval = ISP_SUCCESS;
5195 unsigned int segments, fragment;
5196 unsigned long i;
5197 unsigned int j;
5198 unsigned long dlen;
5199 uint32_t *dcode;
5200 uint32_t risc_addr, risc_size = 0;
5201
5202 isp_prt(isp, ISP_LOGDEBUG0,
5203 "Accessing flash firmware at 0x%x.", faddr);
5204
5205 dcode = isp->isp_rquest;
5206 isp_read_flash_data(isp, dcode, faddr, 8);
5207 if (isp_risc_firmware_invalid(isp, dcode)) {
5208 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
5209 "invalid");
5210 isp_prt(isp, ISP_LOGERR,
5211 "Unable to verify the integrity of flash firmware image.");
5212 isp_prt(isp, ISP_LOGERR,
5213 "Firmware data: 0x%08x 0x%08x 0x%08x 0x%08x.",
5214 dcode[0], dcode[1], dcode[2], dcode[3]);
5215 return (ISP_FUNCTION_FAILED);
5216 } else {
5217 for (i = 0; i < 4; i++)
5218 fcp->fw_flashrev[i] = be32toh(dcode[4 + i]);
5219 snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
5220 "%u.%u.%u", fcp->fw_flashrev[0], fcp->fw_flashrev[1],
5221 fcp->fw_flashrev[2]);
5222 isp_prt(isp, ISP_LOGCONFIG,
5223 "Firmware revision (flash) %u.%u.%u (%x).",
5224 fcp->fw_flashrev[0], fcp->fw_flashrev[1],
5225 fcp->fw_flashrev[2], fcp->fw_flashrev[3]);
5226
5227 /* If ispfw(4) is loaded compare versions and use the newest */
5228 if (isp->isp_osinfo.ispfw != NULL) {
5229 int ispfw_newer = 0;
5230
5231 if (ISP_FW_NEWER_THANX(fcp->fw_ispfwrev, fcp->fw_flashrev)) {
5232 ispfw_newer = 1;
5233 }
5234
5235 if (isp->isp_confopts & ISP_CFG_FWLOAD_FORCE) {
5236 isp_prt(isp, ISP_LOGCONFIG,
5237 "Loading RISC with %s ispfw(4) firmware %s",
5238 (ispfw_newer == 0) ? "older" : "newer",
5239 "because fwload_force is set");
5240 return (ISP_ABORTED);
5241 }
5242 if (ispfw_newer != 0) {
5243 isp_prt(isp, ISP_LOGCONFIG,
5244 "Loading RISC with newer ispfw(4) firmware");
5245 return (ISP_ABORTED);
5246 }
5247 isp_prt(isp, ISP_LOGCONFIG,
5248 "Loading RISC with newer flash firmware");
5249 }
5250 }
5251
5252 dcode = isp->isp_rquest;
5253 segments = ISP_RISC_CODE_SEGMENTS;
5254 for (j = 0; j < segments; j++) {
5255 isp_prt(isp, ISP_LOGDEBUG0, "Loading segment %u", j);
5256 isp_read_flash_data(isp, dcode, faddr, 10);
5257 risc_addr = be32toh(dcode[2]);
5258 risc_size = be32toh(dcode[3]);
5259
5260 dlen = min(risc_size, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4);
5261 for (fragment = 0; risc_size; fragment++) {
5262 if (dlen > risc_size)
5263 dlen = risc_size;
5264
5265 isp_prt(isp, ISP_LOGDEBUG0,
5266 "Loading fragment %u: 0x%x <- 0x%x (0x%lx dwords)",
5267 fragment, risc_addr, faddr, dlen);
5268 isp_read_flash_data(isp, dcode, faddr, dlen);
5269 for (i = 0; i < dlen; i++) {
5270 dcode[i] = bswap32(dcode[i]);
5271 }
5272
5273 rval = isp_load_ram(isp, dcode, risc_addr, dlen);
5274 if (rval) {
5275 isp_prt(isp, ISP_LOGERR,
5276 "Failed to load firmware fragment %u.",
5277 fragment);
5278 return (ISP_FUNCTION_FAILED);
5279 }
5280
5281 faddr += dlen;
5282 risc_addr += dlen;
5283 risc_size -= dlen;
5284 }
5285 }
5286
5287 return (rval);
5288 }
5289
5290 static int
isp_load_risc(ispsoftc_t * isp,uint32_t * srisc_addr)5291 isp_load_risc(ispsoftc_t *isp, uint32_t *srisc_addr)
5292 {
5293 fcparam *fcp = FCPARAM(isp, 0);
5294 int rval = ISP_SUCCESS;
5295 struct active_regions active_regions = { };
5296
5297 /*
5298 * Starting with 27xx there is a primary and secondary firmware region
5299 * in flash. All older controllers just have one firmware region.
5300 */
5301 if (!IS_27XX(isp))
5302 goto try_primary_fw;
5303
5304 isp_get_active_image(isp, &active_regions);
5305
5306 if (active_regions.global != ISP27XX_SECONDARY_IMAGE)
5307 goto try_primary_fw;
5308
5309 isp_prt(isp, ISP_LOGCONFIG,
5310 "Loading secondary firmware image.");
5311 rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw_sec);
5312 return (rval);
5313
5314 try_primary_fw:
5315 isp_prt(isp, ISP_LOGCONFIG,
5316 "Loading primary firmware image.");
5317 rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw);
5318 return (rval);
5319 }
5320
5321 static int
isp_read_nvram(ispsoftc_t * isp)5322 isp_read_nvram(ispsoftc_t *isp)
5323 {
5324 fcparam *fcp = FCPARAM(isp, 0);
5325 int retval = 0;
5326 uint32_t addr, csum, lwrds, *dptr;
5327 uint8_t nvram_data[ISP2400_NVRAM_SIZE];
5328 struct active_regions active_regions = { };
5329
5330 if (IS_27XX(isp))
5331 isp_get_aux_images(isp, &active_regions);
5332
5333 addr = fcp->flt_region_nvram;
5334
5335 if (IS_28XX(isp)) {
5336 if (active_regions.aux.vpd_nvram == ISP27XX_SECONDARY_IMAGE)
5337 addr = fcp->flt_region_nvram_sec;
5338
5339 isp_prt(isp, ISP_LOGCONFIG, "Loading %s NVRAM image",
5340 active_regions.aux.vpd_nvram == ISP27XX_PRIMARY_IMAGE ?
5341 "primary" : "secondary");
5342 }
5343
5344 dptr = (uint32_t *) nvram_data;
5345 for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
5346 isp_rd_2xxx_flash(isp, addr++, dptr++);
5347 }
5348 if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
5349 nvram_data[2] != 'P') {
5350 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
5351 nvram_data[0], nvram_data[1], nvram_data[2]);
5352 retval = -1;
5353 goto out;
5354 }
5355 dptr = (uint32_t *) nvram_data;
5356 for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
5357 uint32_t tmp;
5358 ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
5359 csum += tmp;
5360 }
5361 if (csum != 0) {
5362 isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
5363 retval = -1;
5364 goto out;
5365 }
5366 isp_parse_nvram_2400(isp, nvram_data);
5367 out:
5368 return (retval);
5369 }
5370
5371 static void
isp_parse_nvram_2400(ispsoftc_t * isp,uint8_t * nvram_data)5372 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
5373 {
5374 fcparam *fcp = FCPARAM(isp, 0);
5375 uint64_t wwn;
5376
5377 isp_prt(isp, ISP_LOGDEBUG0,
5378 "NVRAM 0x%08x%08x 0x%08x%08x maxframelen %d",
5379 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
5380 (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
5381 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
5382 (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
5383 ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
5384 isp_prt(isp, ISP_LOGDEBUG0,
5385 "NVRAM loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
5386 ISP2400_NVRAM_HARDLOOPID(nvram_data),
5387 ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
5388 ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
5389 ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
5390
5391 wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
5392 fcp->isp_wwpn_nvram = wwn;
5393
5394 wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
5395 if (wwn) {
5396 if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
5397 wwn = 0;
5398 }
5399 }
5400 if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
5401 wwn = fcp->isp_wwpn_nvram;
5402 wwn &= ~((uint64_t) 0xfff << 48);
5403 }
5404 fcp->isp_wwnn_nvram = wwn;
5405
5406 if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
5407 DEFAULT_FRAMESIZE(isp) =
5408 ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
5409 }
5410 if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
5411 fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
5412 }
5413 fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
5414 fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
5415 fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
5416 }
5417