1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2010 QLogic Corporation. All rights reserved.
24  */
25 
26 #include <qlge.h>
27 
28 static uint32_t ql_dump_buf_8(uint8_t *, uint32_t, uint32_t);
29 static uint32_t ql_dump_buf_16(uint16_t *, uint32_t, uint32_t);
30 static uint32_t ql_dump_buf_32(uint32_t *, uint32_t, uint32_t);
31 static uint32_t ql_dump_buf_64(uint64_t *, uint32_t, uint32_t);
32 static int ql_binary_core_dump(qlge_t *, uint32_t, uint32_t *);
33 
34 static char ISP_8100_REGION[] = {
35 	"nic: nic_boot, nic_param, nic_vpd \n"
36 	"mpi: mpi_fw, mpi_config, edc_fw\n"
37 	"fc: fc_boot, fc_fw, fc_nvram, fc_vpd"};
38 static char ISP_8100_AVAILABLE_DUMPS[] = {"core,register,all"};
39 
40 /*
41  * Get byte from I/O port
42  */
43 uint8_t
44 ql_get8(qlge_t *qlge, uint32_t index)
45 {
46 	uint8_t ret;
47 
48 	ret = (uint8_t)ddi_get8(qlge->dev_handle,
49 	    (uint8_t *)(((caddr_t)qlge->iobase) + index));
50 	return (ret);
51 }
52 
53 /*
54  * Get word from I/O port
55  */
56 uint16_t
57 ql_get16(qlge_t *qlge, uint32_t index)
58 {
59 	uint16_t ret;
60 
61 	ret = (uint16_t)ddi_get16(qlge->dev_handle,
62 	    (uint16_t *)(void *)(((caddr_t)qlge->iobase) + index));
63 	return (ret);
64 }
65 
66 /*
67  * Get double word from I/O port
68  */
69 uint32_t
70 ql_get32(qlge_t *qlge, uint32_t index)
71 {
72 	uint32_t ret;
73 
74 	ret = ddi_get32(qlge->dev_handle,
75 	    (uint32_t *)(void *)(((caddr_t)qlge->iobase) + index));
76 	return (ret);
77 }
78 
79 /*
80  * Send byte to I/O port
81  */
82 void
83 ql_put8(qlge_t *qlge, uint32_t index, uint8_t data)
84 {
85 	ddi_put8(qlge->dev_handle,
86 	    (uint8_t *)(((caddr_t)qlge->iobase) + index), data);
87 }
88 
89 /*
90  * Send word to I/O port
91  */
92 void
93 ql_put16(qlge_t *qlge, uint32_t index, uint16_t data)
94 {
95 	ddi_put16(qlge->dev_handle,
96 	    (uint16_t *)(void *)(((caddr_t)qlge->iobase) + index), data);
97 }
98 
99 /*
100  * Send double word to I/O port
101  */
102 void
103 ql_put32(qlge_t *qlge, uint32_t index, uint32_t data)
104 {
105 	ddi_put32(qlge->dev_handle,
106 	    (uint32_t *)(void *)(((caddr_t)qlge->iobase) + index), data);
107 }
108 
109 /*
110  * Read from a register
111  */
112 uint32_t
113 ql_read_reg(qlge_t *qlge, uint32_t reg)
114 {
115 	uint32_t data = ql_get32(qlge, reg);
116 
117 	return (data);
118 }
119 
120 /*
121  * Write 32 bit data to a register
122  */
123 void
124 ql_write_reg(qlge_t *qlge, uint32_t reg, uint32_t data)
125 {
126 	ql_put32(qlge, reg, data);
127 }
128 
129 /*
130  * Set semaphore register bit to lock access to a shared register
131  */
132 int
133 ql_sem_lock(qlge_t *qlge, uint32_t sem_mask, uint32_t sem_bits)
134 {
135 	uint32_t value;
136 
137 	ql_put32(qlge, REG_SEMAPHORE, (sem_mask | sem_bits));
138 	value = ql_get32(qlge, REG_SEMAPHORE);
139 	return ((value & (sem_mask >> 16)) == sem_bits);
140 }
141 /*
142  * Wait up to "delay" seconds until the register "reg"'s
143  * "wait_bit" is set
144  * Default wait time is 5 seconds if "delay" time was not set.
145  */
146 int
147 ql_wait_reg_bit(qlge_t *qlge, uint32_t reg, uint32_t wait_bit, int set,
148     uint32_t delay)
149 {
150 	uint32_t reg_status;
151 	uint32_t timer = 5; /* 5 second */
152 	int rtn_val = DDI_SUCCESS;
153 	uint32_t delay_ticks;
154 
155 	if (delay != 0)
156 		timer = delay;
157 
158 	delay_ticks = timer * 100;
159 	/*
160 	 * wait for Configuration register test bit to be set,
161 	 * if not, then it is still busy.
162 	 */
163 	do {
164 		reg_status = ql_read_reg(qlge, reg);
165 		/* wait for bit set or reset? */
166 		if (set == BIT_SET) {
167 			if (reg_status & wait_bit)
168 				break;
169 			else
170 				qlge_delay(QL_ONE_SEC_DELAY / 100);
171 		} else {
172 			if (reg_status & wait_bit)
173 				qlge_delay(QL_ONE_SEC_DELAY / 100);
174 			else
175 				break;
176 		}
177 	} while (--delay_ticks);
178 
179 	if (delay_ticks == 0) {
180 		rtn_val = DDI_FAILURE;
181 		cmn_err(CE_WARN, "qlge(%d)wait reg %x, bit %x time out",
182 		    qlge->instance, reg, wait_bit);
183 		if (qlge->fm_enable) {
184 			ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
185 			atomic_or_32(&qlge->flags, ADAPTER_ERROR);
186 		}
187 	}
188 	return (rtn_val);
189 }
190 
191 /*
192  * Dump the value of control registers
193  */
194 void
195 ql_dump_all_contrl_regs(qlge_t *qlge)
196 {
197 	int i;
198 	uint32_t data;
199 
200 	for (i = 0; i < 0xff; i = i+4) {
201 		data = ql_read_reg(qlge, i);
202 		ql_printf("\tregister# 0x%x value: 0x%x\n", i, data);
203 	}
204 }
205 
206 /*
207  * Prints string plus buffer.
208  */
209 void
210 ql_dump_buf(char *string, uint8_t *buffer, uint8_t wd_size,
211     uint32_t count)
212 {
213 	uint32_t offset = 0;
214 
215 	if (strcmp(string, "") != 0)
216 		ql_printf(string);
217 
218 	if ((buffer == NULL) || (count == 0))
219 		return;
220 
221 	switch (wd_size) {
222 	case 8:
223 		while (count) {
224 			count = ql_dump_buf_8(buffer, count, offset);
225 			offset += 8;
226 			buffer += 8;
227 		}
228 		break;
229 
230 	case 16:
231 		while (count) {
232 			count = ql_dump_buf_16((uint16_t *)(void *)buffer,
233 			    count, offset);
234 			offset += 16;
235 			buffer += 16;
236 		}
237 		break;
238 	case 32:
239 		while (count) {
240 			count = ql_dump_buf_32((uint32_t *)(void *)buffer,
241 			    count, offset);
242 			offset += 16;
243 			buffer += 16;
244 		}
245 		break;
246 	case 64:
247 		while (count) {
248 			count = ql_dump_buf_64((uint64_t *)(void *)buffer,
249 			    count, offset);
250 			offset += 16;
251 			buffer += 16;
252 		}
253 		break;
254 	default:
255 		break;
256 	}
257 }
258 
259 /*
260  * Print as 8bit bytes
261  */
262 static uint32_t
263 ql_dump_buf_8(uint8_t *bp, uint32_t count, uint32_t offset)
264 {
265 	switch (count) {
266 	case 1:
267 		ql_printf("0x%016x : %02x\n",
268 		    offset,
269 		    *bp);
270 		break;
271 
272 	case 2:
273 		ql_printf("0x%016x : %02x %02x\n",
274 		    offset,
275 		    *bp, *(bp+1));
276 		break;
277 
278 	case 3:
279 		ql_printf("0x%016x : %02x %02x %02x\n",
280 		    offset,
281 		    *bp, *(bp+1), *(bp+2));
282 		break;
283 
284 	case 4:
285 		ql_printf("0x%016x : %02x %02x %02x %02x\n",
286 		    offset,
287 		    *bp, *(bp+1), *(bp+2), *(bp+3));
288 		break;
289 
290 	case 5:
291 		ql_printf("0x%016x : %02x %02x %02x %02x %02x\n",
292 		    offset,
293 		    *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4));
294 		break;
295 
296 	case 6:
297 		ql_printf("0x%016x : %02x %02x %02x %02x %02x %02x\n",
298 		    offset,
299 		    *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5));
300 		break;
301 
302 	case 7:
303 		ql_printf("0x%016x : %02x %02x %02x %02x %02x %02x %02x\n",
304 		    offset,
305 		    *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5), *(bp+6));
306 		break;
307 
308 	default:
309 		ql_printf("0x%016x : %02x %02x %02x %02x %02x %02x %02x %02x\n",
310 		    offset,
311 		    *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5), *(bp+6),
312 		    *(bp+7));
313 		break;
314 
315 	}
316 
317 	if (count < 8) {
318 		count = 0;
319 	} else {
320 		count -= 8;
321 	}
322 
323 	return (count);
324 }
325 
326 /*
327  * Print as 16bit
328  */
329 static uint32_t
330 ql_dump_buf_16(uint16_t *bp, uint32_t count, uint32_t offset)
331 {
332 
333 	switch (count) {
334 	case 1:
335 		ql_printf("0x%016x : %04x\n",
336 		    offset,
337 		    *bp);
338 		break;
339 
340 	case 2:
341 		ql_printf("0x%016x : %04x %04x\n",
342 		    offset,
343 		    *bp, *(bp+1));
344 		break;
345 
346 	case 3:
347 		ql_printf("0x%016x : %04x %04x %04x\n",
348 		    offset,
349 		    *bp, *(bp+1), *(bp+2));
350 		break;
351 
352 	case 4:
353 		ql_printf("0x%016x : %04x %04x %04x %04x\n",
354 		    offset,
355 		    *bp, *(bp+1), *(bp+2), *(bp+3));
356 		break;
357 
358 	case 5:
359 		ql_printf("0x%016x : %04x %04x %04x %04x %04x\n",
360 		    offset,
361 		    *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4));
362 		break;
363 
364 	case 6:
365 		ql_printf("0x%016x : %04x %04x %04x %04x %04x %04x\n",
366 		    offset,
367 		    *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5));
368 		break;
369 
370 	case 7:
371 		ql_printf("0x%016x : %04x %04x %04x %04x %04x %04x %04x\n",
372 		    offset,
373 		    *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5), *(bp+6));
374 		break;
375 
376 	default:
377 		ql_printf("0x%016x : %04x %04x %04x %04x %04x %04x %04x %04x\n",
378 		    offset,
379 		    *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5), *(bp+6),
380 		    *(bp+7));
381 		break;
382 	}
383 
384 	if (count < 8) {
385 		count = 0;
386 	} else {
387 		count -= 8;
388 	}
389 
390 	return (count);
391 }
392 
393 /*
394  * Print as 32bit
395  */
396 static uint32_t
397 ql_dump_buf_32(uint32_t *bp, uint32_t count, uint32_t offset)
398 {
399 
400 	switch (count) {
401 	case 1:
402 		ql_printf("0x%016x : %08x\n",
403 		    offset,
404 		    *bp);
405 		break;
406 
407 	case 2:
408 		ql_printf("0x%016x : %08x %08x\n",
409 		    offset,
410 		    *bp, *(bp+1));
411 		break;
412 
413 	case 3:
414 		ql_printf("0x%016x : %08x %08x %08x\n",
415 		    offset,
416 		    *bp, *(bp+1), *(bp+2));
417 		break;
418 
419 	default:
420 		ql_printf("0x%016x : %08x %08x %08x %08x\n",
421 		    offset,
422 		    *bp, *(bp+1), *(bp+2), *(bp+3));
423 		break;
424 	}
425 
426 	if (count < 4) {
427 		count = 0;
428 	} else {
429 		count -= 4;
430 	}
431 
432 	return (count);
433 }
434 
435 /*
436  * Print as 64bit
437  */
438 static uint32_t
439 ql_dump_buf_64(uint64_t *bp, uint32_t count, uint32_t offset)
440 {
441 
442 	switch (count) {
443 	case 1:
444 		ql_printf("0x%016x : %016x\n",
445 		    offset,
446 		    *bp);
447 		break;
448 
449 	default:
450 		ql_printf("0x%016x : %016x %016x\n",
451 		    offset,
452 		    *bp, *(bp+1));
453 		break;
454 
455 	}
456 
457 	if (count < 2) {
458 		count = 0;
459 	} else {
460 		count -= 2;
461 	}
462 
463 	return (count);
464 }
465 
466 /*
467  * Print CQICB control block information
468  */
469 /* ARGSUSED */
470 void
471 ql_dump_cqicb(qlge_t *qlge, struct cqicb_t *cqicb)
472 {
473 	_NOTE(ARGUNUSED(qlge));
474 	ASSERT(qlge != NULL);
475 	ASSERT(cqicb != NULL);
476 	ql_printf("ql_dump_cqicb:entered\n");
477 
478 	ql_printf("\t msix_vect   = 0x%x\n",
479 	    cqicb->msix_vect);
480 	ql_printf("\t reserved1  = 0x%x\n",
481 	    cqicb->reserved1);
482 	ql_printf("\t reserved2  = 0x%x\n",
483 	    cqicb->reserved2);
484 	ql_printf("\t flags  = 0x%x\n",
485 	    cqicb->flags);
486 	ql_printf("\t len  = 0x%x\n",
487 	    le16_to_cpu(cqicb->len));
488 	ql_printf("\t rid = 0x%x\n",
489 	    le16_to_cpu(cqicb->rid));
490 	ql_printf("\t cq_base_addr_lo = 0x%x\n",
491 	    le32_to_cpu(cqicb->cq_base_addr_lo));
492 	ql_printf("\t cq_base_addr_hi = 0x%x\n",
493 	    le32_to_cpu(cqicb->cq_base_addr_hi));
494 	ql_printf("\t prod_idx_addr_lo = %x\n",
495 	    le32_to_cpu(cqicb->prod_idx_addr_lo));
496 	ql_printf("\t prod_idx_addr_hi = %x\n",
497 	    le32_to_cpu(cqicb->prod_idx_addr_hi));
498 	ql_printf("\t pkt_delay = %d\n",
499 	    le16_to_cpu(cqicb->pkt_delay));
500 	ql_printf("\t irq_delay = 0x%x\n",
501 	    le16_to_cpu(cqicb->irq_delay));
502 	ql_printf("\t lbq_addr_lo = 0x%x\n",
503 	    le32_to_cpu(cqicb->lbq_addr_lo));
504 	ql_printf("\t lbq_addr_hi = 0x%x\n",
505 	    le32_to_cpu(cqicb->lbq_addr_hi));
506 	ql_printf("\t lbq_buf_size = 0x%x\n",
507 	    le16_to_cpu(cqicb->lbq_buf_size));
508 	ql_printf("\t lbq_len = 0x%x\n",
509 	    le16_to_cpu(cqicb->lbq_len));
510 	ql_printf("\t sbq_addr_lo = 0x%x\n",
511 	    le32_to_cpu(cqicb->sbq_addr_lo));
512 	ql_printf("\t sbq_addr_hi = 0x%x\n",
513 	    le32_to_cpu(cqicb->sbq_addr_hi));
514 	ql_printf("\t sbq_buf_size = 0x%x\n",
515 	    le16_to_cpu(cqicb->sbq_buf_size));
516 	ql_printf("\t sbq_len = 0x%x\n",
517 	    le16_to_cpu(cqicb->sbq_len));
518 
519 	ql_printf("ql_dump_cqicb:exiting\n");
520 }
521 
522 /*
523  * Print WQICB control block information
524  */
525 /* ARGSUSED */
526 void
527 ql_dump_wqicb(qlge_t *qlge, struct wqicb_t *wqicb)
528 {
529 	_NOTE(ARGUNUSED(qlge));
530 	ASSERT(qlge != NULL);
531 	ASSERT(wqicb != NULL);
532 
533 	ql_printf("ql_dump_wqicb:entered\n");
534 
535 	ql_printf("\t len = %x\n",
536 	    le16_to_cpu(wqicb->len));
537 	ql_printf("\t flags = %x\n",
538 	    le16_to_cpu(wqicb->flags));
539 	ql_printf("\t cq_id_rss = %x\n",
540 	    le16_to_cpu(wqicb->cq_id_rss));
541 	ql_printf("\t rid = 0x%x\n",
542 	    le16_to_cpu(wqicb->rid));
543 	ql_printf("\t wq_addr_lo = 0x%x\n",
544 	    le32_to_cpu(wqicb->wq_addr_lo));
545 	ql_printf("\t wq_addr_hi = 0x%x\n",
546 	    le32_to_cpu(wqicb->wq_addr_hi));
547 	ql_printf("\t cnsmr_idx_addr_lo = %x\n",
548 	    le32_to_cpu(wqicb->cnsmr_idx_addr_lo));
549 	ql_printf("\t cnsmr_idx_addr_hi = %x\n",
550 	    le32_to_cpu(wqicb->cnsmr_idx_addr_hi));
551 
552 	ql_printf("ql_dump_wqicb:exit\n");
553 }
554 
555 /*
556  * Print request descriptor information
557  */
558 void
559 ql_dump_req_pkt(qlge_t *qlge, struct ob_mac_iocb_req *pkt, void *oal,
560     int number)
561 {
562 	int i = 0;
563 	struct oal_entry *oal_entry;
564 
565 	ql_printf("ql_dump_req_pkt(%d):enter\n", qlge->instance);
566 
567 	ql_printf("\t opcode = 0x%x\n",
568 	    pkt->opcode);
569 	ql_printf("\t flag0  = 0x%x\n",
570 	    pkt->flag0);
571 	ql_printf("\t flag1  = 0x%x\n",
572 	    pkt->flag1);
573 	ql_printf("\t flag2  = 0x%x\n",
574 	    pkt->flag2);
575 	ql_printf("\t frame_len  = 0x%x\n",
576 	    le16_to_cpu(pkt->frame_len));
577 	ql_printf("\t transaction_id_low = 0x%x\n",
578 	    le16_to_cpu(pkt->tid));
579 	ql_printf("\t txq_idx = 0x%x\n",
580 	    le16_to_cpu(pkt->txq_idx));
581 	ql_printf("\t protocol_hdr_len = 0x%x\n",
582 	    le16_to_cpu(pkt->protocol_hdr_len));
583 	ql_printf("\t hdr_off = %d\n",
584 	    le16_to_cpu(pkt->hdr_off));
585 	ql_printf("\t vlan_tci = %d\n",
586 	    le16_to_cpu(pkt->vlan_tci));
587 	ql_printf("\t mss = %d\n",
588 	    le16_to_cpu(pkt->mss));
589 
590 	/* if OAL is needed */
591 	if (number > TX_DESC_PER_IOCB) {
592 		for (i = 0; i < TX_DESC_PER_IOCB; i++) {
593 			ql_printf("\t buf_addr%d_low = 0x%x\n",
594 			    i, pkt->oal_entry[i].buf_addr_low);
595 			ql_printf("\t buf_addr%d_high = 0x%x\n",
596 			    i, pkt->oal_entry[i].buf_addr_high);
597 			ql_printf("\t buf%d_len = 0x%x\n",
598 			    i, pkt->oal_entry[i].buf_len);
599 		}
600 		oal_entry = (struct oal_entry *)oal;
601 		ql_printf("\t additional %d tx descriptors in OAL\n",
602 		    (number - TX_DESC_PER_IOCB + 1));
603 		for (i = 0; i < (number-TX_DESC_PER_IOCB + 1); i++) {
604 			ql_printf("\t buf_addr%d_low = 0x%x\n",
605 			    i, oal_entry[i].buf_addr_low);
606 			ql_printf("\t buf_addr%d_high = 0x%x\n",
607 			    i, oal_entry[i].buf_addr_high);
608 			ql_printf("\t buf%d_len = 0x%x\n",
609 			    i, oal_entry[i].buf_len);
610 		}
611 	} else {
612 		for (i = 0; i < number; i++) {
613 			ql_printf("\t buf_addr%d_low = 0x%x\n",
614 			    i, pkt->oal_entry[i].buf_addr_low);
615 			ql_printf("\t buf_addr%d_high = 0x%x\n",
616 			    i, pkt->oal_entry[i].buf_addr_high);
617 			ql_printf("\t buf%d_len = 0x%x\n",
618 			    i, pkt->oal_entry[i].buf_len);
619 		}
620 	}
621 	ql_printf("ql_dump_req_pkt:exiting\n");
622 }
623 
624 /*
625  * Print PCI configuration
626  */
627 void
628 ql_dump_pci_config(qlge_t *qlge)
629 {
630 	qlge->pci_cfg.vendor_id = (uint16_t)
631 	    pci_config_get16(qlge->pci_handle, PCI_CONF_VENID);
632 
633 	qlge->pci_cfg.device_id = (uint16_t)
634 	    pci_config_get16(qlge->pci_handle, PCI_CONF_DEVID);
635 
636 	qlge->pci_cfg.command = (uint16_t)
637 	    pci_config_get16(qlge->pci_handle, PCI_CONF_COMM);
638 
639 	qlge->pci_cfg.status = (uint16_t)
640 	    pci_config_get16(qlge->pci_handle, PCI_CONF_STAT);
641 
642 	qlge->pci_cfg.revision = (uint8_t)
643 	    pci_config_get8(qlge->pci_handle, PCI_CONF_REVID);
644 
645 	qlge->pci_cfg.prog_class = (uint8_t)
646 	    pci_config_get8(qlge->pci_handle, PCI_CONF_PROGCLASS);
647 
648 	qlge->pci_cfg.sub_class = (uint8_t)
649 	    pci_config_get8(qlge->pci_handle, PCI_CONF_SUBCLASS);
650 
651 	qlge->pci_cfg.base_class = (uint8_t)
652 	    pci_config_get8(qlge->pci_handle, PCI_CONF_BASCLASS);
653 
654 	qlge->pci_cfg.cache_line_size = (uint8_t)
655 	    pci_config_get8(qlge->pci_handle, PCI_CONF_CACHE_LINESZ);
656 
657 	qlge->pci_cfg.latency_timer = (uint8_t)
658 	    pci_config_get8(qlge->pci_handle, PCI_CONF_LATENCY_TIMER);
659 
660 	qlge->pci_cfg.header_type = (uint8_t)
661 	    pci_config_get8(qlge->pci_handle, PCI_CONF_HEADER);
662 
663 	qlge->pci_cfg.io_base_address =
664 	    pci_config_get32(qlge->pci_handle, PCI_CONF_BASE0);
665 
666 	qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_lower =
667 	    pci_config_get32(qlge->pci_handle, PCI_CONF_BASE1);
668 
669 	qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_upper =
670 	    pci_config_get32(qlge->pci_handle, PCI_CONF_BASE2);
671 
672 	qlge->pci_cfg.pci_doorbell_mem_base_address_lower =
673 	    pci_config_get32(qlge->pci_handle, PCI_CONF_BASE3);
674 
675 	qlge->pci_cfg.pci_doorbell_mem_base_address_upper =
676 	    pci_config_get32(qlge->pci_handle, PCI_CONF_BASE4);
677 
678 	qlge->pci_cfg.sub_vendor_id = (uint16_t)
679 	    pci_config_get16(qlge->pci_handle, PCI_CONF_SUBVENID);
680 
681 	qlge->pci_cfg.sub_device_id = (uint16_t)
682 	    pci_config_get16(qlge->pci_handle, PCI_CONF_SUBSYSID);
683 
684 	qlge->pci_cfg.expansion_rom =
685 	    pci_config_get32(qlge->pci_handle, PCI_CONF_ROM);
686 
687 	qlge->pci_cfg.intr_line = (uint8_t)
688 	    pci_config_get8(qlge->pci_handle, PCI_CONF_ILINE);
689 
690 	qlge->pci_cfg.intr_pin = (uint8_t)
691 	    pci_config_get8(qlge->pci_handle, PCI_CONF_IPIN);
692 
693 	qlge->pci_cfg.min_grant = (uint8_t)
694 	    pci_config_get8(qlge->pci_handle, PCI_CONF_MIN_G);
695 
696 	qlge->pci_cfg.max_latency = (uint8_t)
697 	    pci_config_get8(qlge->pci_handle, PCI_CONF_MAX_L);
698 
699 	qlge->pci_cfg.pcie_device_control = (uint16_t)
700 	    pci_config_get16(qlge->pci_handle, 0x54);
701 
702 	qlge->pci_cfg.link_status = (uint16_t)
703 	    pci_config_get16(qlge->pci_handle, 0x5e);
704 
705 	qlge->pci_cfg.msi_msg_control = (uint16_t)
706 	    pci_config_get16(qlge->pci_handle, 0x8a);
707 
708 	qlge->pci_cfg.msi_x_msg_control = (uint16_t)
709 	    pci_config_get16(qlge->pci_handle, 0xa2);
710 
711 	if (qlge->ql_dbgprnt & DBG_GLD) {
712 		ql_printf("ql_dump_pci_config(%d): enter\n",
713 		    qlge->instance);
714 		ql_printf("\tvendorid =0x%x.\n",
715 		    qlge->pci_cfg.vendor_id);
716 		ql_printf("\tdeviceid =0x%x.\n",
717 		    qlge->pci_cfg.device_id);
718 		ql_printf("\tcommand =0x%x.\n",
719 		    qlge->pci_cfg.command);
720 		ql_printf("\tstatus =0x%x.\n",
721 		    qlge->pci_cfg.status);
722 		ql_printf("\trevision id =0x%x.\n",
723 		    qlge->pci_cfg.revision);
724 		ql_printf("\tprogram class =0x%x.\n",
725 		    qlge->pci_cfg.prog_class);
726 		ql_printf("\tsubclass code =0x%x.\n",
727 		    qlge->pci_cfg.sub_class);
728 		ql_printf("\tbase class code =0x%x.\n",
729 		    qlge->pci_cfg.base_class);
730 		ql_printf("\tcache line size =0x%x.\n",
731 		    qlge->pci_cfg.cache_line_size);
732 		ql_printf("\tlatency timer =0x%x.\n",
733 		    qlge->pci_cfg.latency_timer);
734 		ql_printf("\theader =0x%x.\n",
735 		    qlge->pci_cfg.header_type);
736 		ql_printf("\tI/O Base Register Address0 =0x%x.\n",
737 		    qlge->pci_cfg.io_base_address);
738 		ql_printf("\tpci_cntl_reg_set_mem_base_address_lower =0x%x.\n",
739 		    qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_lower);
740 		ql_printf("\tpci_cntl_reg_set_mem_base_address_upper =0x%x.\n",
741 		    qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_upper);
742 		ql_printf("\tpci_doorbell_mem_base_address_lower =0x%x.\n",
743 		    qlge->pci_cfg.pci_doorbell_mem_base_address_lower);
744 		ql_printf("\tpci_doorbell_mem_base_address_upper =0x%x.\n",
745 		    qlge->pci_cfg.pci_doorbell_mem_base_address_upper);
746 		ql_printf("\tSubsytem Vendor Id =0x%x.\n",
747 		    qlge->pci_cfg.sub_vendor_id);
748 		ql_printf("\tSubsytem Id =0x%x.\n",
749 		    qlge->pci_cfg.sub_device_id);
750 		ql_printf("\tExpansion ROM Base Register =0x%x.\n",
751 		    qlge->pci_cfg.expansion_rom);
752 		ql_printf("\tInterrupt Line =0x%x.\n",
753 		    qlge->pci_cfg.intr_line);
754 		ql_printf("\tInterrupt Pin =0x%x.\n",
755 		    qlge->pci_cfg.intr_pin);
756 		ql_printf("\tMin Grant =0x%x.\n",
757 		    qlge->pci_cfg.min_grant);
758 		ql_printf("\tMax Grant =0x%x.\n",
759 		    qlge->pci_cfg.max_latency);
760 		ql_printf("\tdevice_control =0x%x.\n",
761 		    qlge->pci_cfg.pcie_device_control);
762 		ql_printf("\tlink_status =0x%x.\n",
763 		    qlge->pci_cfg.link_status);
764 		ql_printf("\tmsi_msg_control =0x%x.\n",
765 		    qlge->pci_cfg.msi_msg_control);
766 		ql_printf("\tmsi_x_msg_control =0x%x.\n",
767 		    qlge->pci_cfg.msi_x_msg_control);
768 
769 		ql_printf("ql_dump_pci_config(%d): exit\n", qlge->instance);
770 	}
771 }
772 
773 /*
774  * Print a formated string
775  */
776 void
777 ql_printf(const char *fmt, ...)
778 {
779 	va_list ap;
780 
781 	va_start(ap, fmt);
782 	vcmn_err(CE_CONT, fmt, ap);
783 	va_end(ap);
784 
785 }
786 
787 /*
788  * Read all control registers value and save in a string
789  */
790 static uint32_t
791 read_ctrl_reg_set(qlge_t *qlge, caddr_t bufp)
792 {
793 	int i, j;
794 	uint32_t data;
795 	caddr_t bp = bufp;
796 	uint32_t cnt;
797 
798 	/* read Reg 0 -0xC4 */
799 	for (i = 0, j = 0; i <= 0xfc; i += 4) {
800 		data = ql_read_reg(qlge, i);
801 		(void) sprintf(bp, "Register[%x] = 0x%x\n", i, data);
802 		bp += strlen(bp);
803 		if (i == REG_INTERRUPT_ENABLE) {
804 			/* Read */
805 			data = INTR_EN_TYPE_READ;
806 			ql_write_reg(qlge, i, (data | (data << 16)));
807 			data = ql_read_reg(qlge, i);
808 			if (data & INTR_EN_EN) {
809 				(void) sprintf(bp, "Intr0 enabled: 0x%x\n",
810 				    data);
811 				bp += strlen(bp);
812 			} else {
813 				(void) sprintf(bp, "Intr0 disabled: 0x%x\n",
814 				    data);
815 				bp += strlen(bp);
816 			}
817 		}
818 		j++;
819 	}
820 	*bp = '\0';
821 	bp++;
822 	cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp);
823 	QL_PRINT(DBG_GLD, ("%s(%d) %x bytes to export\n",
824 	    __func__, qlge->instance, cnt));
825 	return (cnt);
826 }
827 
828 /*
829  * Get address and size of image tables in flash memory
830  */
831 static int
832 ql_get_flash_table_region_info(qlge_t *qlge, uint32_t region, uint32_t *addr,
833     uint32_t *size)
834 {
835 	int rval = DDI_SUCCESS;
836 
837 	switch (region) {
838 	case FLT_REGION_FDT:
839 		*addr = ISP_8100_FDT_ADDR;
840 		*size = ISP_8100_FDT_SIZE;
841 		break;
842 	case FLT_REGION_FLT:
843 		*addr = ISP_8100_FLT_ADDR;
844 		*size = ISP_8100_FLT_SIZE;
845 		break;
846 	case FLT_REGION_NIC_BOOT_CODE:
847 		*addr = ISP_8100_NIC_BOOT_CODE_ADDR;
848 		*size = ISP_8100_NIC_BOOT_CODE_SIZE;
849 		break;
850 	case FLT_REGION_MPI_FW_USE:
851 		*addr = ISP_8100_MPI_FW_USE_ADDR;
852 		*size = ISP_8100_MPI_FW_USE_SIZE;
853 		break;
854 	case FLT_REGION_MPI_RISC_FW:
855 		*addr = ISP_8100_MPI_RISC_FW_ADDR;
856 		*size = ISP_8100_MPI_RISC_FW_SIZE;
857 		break;
858 	case FLT_REGION_VPD0:
859 		*addr = ISP_8100_VPD0_ADDR;
860 		*size = ISP_8100_VPD0_SIZE;
861 		break;
862 	case FLT_REGION_NIC_PARAM0:
863 		*addr = ISP_8100_NIC_PARAM0_ADDR;
864 		*size = ISP_8100_NIC_PARAM0_SIZE;
865 		break;
866 	case FLT_REGION_VPD1:
867 		*addr = ISP_8100_VPD1_ADDR;
868 		*size = ISP_8100_VPD1_SIZE;
869 		break;
870 	case FLT_REGION_NIC_PARAM1:
871 		*addr = ISP_8100_NIC_PARAM1_ADDR;
872 		*size = ISP_8100_NIC_PARAM1_SIZE;
873 		break;
874 	case FLT_REGION_MPI_CFG:
875 		*addr = ISP_8100_MPI_CFG_ADDR;
876 		*size = ISP_8100_MPI_CFG_SIZE;
877 		break;
878 	case FLT_REGION_EDC_PHY_FW:
879 		*addr = ISP_8100_EDC_PHY_FW_ADDR;
880 		*size = ISP_8100_EDC_PHY_FW_SIZE;
881 		break;
882 	case FLT_REGION_FC_BOOT_CODE:
883 		*addr = ISP_8100_FC_BOOT_CODE_ADDR;
884 		*size = ISP_8100_FC_BOOT_CODE_SIZE;
885 		break;
886 	case FLT_REGION_FC_FW:
887 		*addr = ISP_8100_FC_FW_ADDR;
888 		*size = ISP_8100_FC_FW_SIZE;
889 		break;
890 	default:
891 		cmn_err(CE_WARN, "%s(%d): Unknown region code %x!",
892 		    __func__, qlge->instance, region);
893 		rval = DDI_FAILURE;
894 	}
895 	return (rval);
896 }
897 
898 /*
899  * Get PCI bus information
900  */
901 static int
902 ql_get_pci_bus_info(qlge_t *qlge, uint32_t *pci_bus_info_ptr)
903 {
904 	dev_info_t *dip;
905 	int *options;
906 	unsigned int noptions;
907 	int rval = DDI_FAILURE;
908 
909 	dip = qlge->dip;
910 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0,
911 	    "assigned-addresses", &options, &noptions) == DDI_PROP_SUCCESS) {
912 		QL_PRINT(DBG_GLD, ("%s(%d) %d options\n",
913 		    __func__, qlge->instance, noptions));
914 
915 		if (noptions != 0) {
916 			*pci_bus_info_ptr = options[0];
917 			rval = DDI_SUCCESS;
918 		}
919 
920 		ddi_prop_free(options);
921 	}
922 	return (rval);
923 }
924 
925 /*
926  * Build the first packet header in case that 1k+ data transfer is required
927  */
928 void
929 build_init_pkt_header(qlge_t *qlge, ioctl_header_info_t *pheader, uint32_t size)
930 {
931 	qlge->ioctl_total_length = size;
932 	QL_PRINT(DBG_GLD, ("%d bytes used in kernel buffer\n",
933 	    qlge->ioctl_total_length));
934 	qlge->expected_trans_times =
935 	    (uint16_t)(qlge->ioctl_total_length / IOCTL_MAX_DATA_LEN);
936 	if ((qlge->ioctl_total_length % IOCTL_MAX_DATA_LEN) != 0)
937 		qlge->expected_trans_times++;
938 	QL_PRINT(DBG_GLD, ("expected transer times %d \n",
939 	    qlge->expected_trans_times));
940 	qlge->ioctl_transferred_bytes = 0;
941 	/*
942 	 * tell user total bytes prepare to receive in the
943 	 * following transactions
944 	 */
945 	pheader->version = 0;
946 	pheader->total_length = qlge->ioctl_total_length;
947 	pheader->payload_length = 0;
948 	pheader->expected_trans_times = qlge->expected_trans_times;
949 }
950 
951 /*
952  * Do ioctl on hardware
953  */
954 /* ARGSUSED */
955 enum ioc_reply
956 ql_chip_ioctl(qlge_t *qlge, queue_t *q, mblk_t *mp)
957 {
958 	mblk_t *dmp;
959 	int cmd, i, rval;
960 	struct ql_device_reg *reg;
961 	struct ql_pci_reg *pci_reg;
962 	struct ql_flash_io_info *flash_io_info_ptr;
963 	pci_cfg_t *pci_cfg;
964 	uint32_t *pvalue;
965 	struct qlnic_prop_info *prop_ptr;
966 	ql_adapter_info_t *adapter_info_ptr;
967 	uint16_t payload_len;
968 	uint32_t remaining_bytes;
969 	ioctl_header_info_t *pheader;
970 	caddr_t bp, bdesc;
971 	uint32_t len;
972 	uint32_t addr, size, region;
973 	struct iocblk *iocp = (struct iocblk *)(void *)mp->b_rptr;
974 	uint16_t iltds_image_entry_regions[] = {
975 			FLT_REGION_NIC_BOOT_CODE, FLT_REGION_MPI_RISC_FW,
976 			FLT_REGION_EDC_PHY_FW, FLT_REGION_FC_BOOT_CODE,
977 			FLT_REGION_FC_FW};
978 	ql_iltds_description_header_t *iltds_ptr;
979 	ql_iltds_header_t *ql_iltds_header_ptr;
980 	uint32_t offset;
981 	uint16_t requested_dump;
982 
983 	/*
984 	 * There should be a M_DATA mblk following
985 	 * the initial M_IOCTL mblk
986 	 */
987 	if ((dmp = mp->b_cont) == NULL) {
988 		cmn_err(CE_WARN, "%s(%d) b_count NULL",
989 		    __func__, qlge->instance);
990 		return (IOC_INVAL);
991 	}
992 
993 	cmd = iocp->ioc_cmd;
994 
995 	reg = (struct ql_device_reg *)(void *)dmp->b_rptr;
996 	pci_reg = (struct ql_pci_reg *)(void *)dmp->b_rptr;
997 	pvalue = (uint32_t *)(void *)dmp->b_rptr;
998 	flash_io_info_ptr = (struct ql_flash_io_info *)(void *)dmp->b_rptr;
999 	adapter_info_ptr = (ql_adapter_info_t *)(void *)dmp->b_rptr;
1000 
1001 	switch (cmd) {
1002 		case QLA_GET_DBGLEAVEL:
1003 			if (iocp->ioc_count != sizeof (*pvalue)) {
1004 				return (IOC_INVAL);
1005 			}
1006 			*pvalue = qlge->ql_dbgprnt;
1007 			break;
1008 
1009 		case QLA_SET_DBGLEAVEL:
1010 			if (iocp->ioc_count != sizeof (*pvalue)) {
1011 				return (IOC_INVAL);
1012 			}
1013 			qlge->ql_dbgprnt = *pvalue;
1014 			break;
1015 
1016 		case QLA_WRITE_REG:
1017 			if (iocp->ioc_count != sizeof (*reg)) {
1018 				return (IOC_INVAL);
1019 			}
1020 			ql_write_reg(qlge, reg->addr, reg->value);
1021 			break;
1022 
1023 		case QLA_READ_PCI_REG:
1024 			if (iocp->ioc_count != sizeof (*pci_reg)) {
1025 				return (IOC_INVAL);
1026 			}
1027 			/* protect against bad addr values */
1028 			if (pci_reg->addr > 0xff)
1029 				return (IOC_INVAL);
1030 			pci_reg->value =
1031 			    (uint16_t)pci_config_get16(qlge->pci_handle,
1032 			    pci_reg->addr);
1033 			break;
1034 
1035 		case QLA_WRITE_PCI_REG:
1036 			if (iocp->ioc_count != sizeof (*pci_reg)) {
1037 				return (IOC_INVAL);
1038 			}
1039 			/* protect against bad addr values */
1040 			if (pci_reg->addr > 0xff)
1041 				return (IOC_INVAL);
1042 			pci_config_put16(qlge->pci_handle, pci_reg->addr,
1043 			    pci_reg->value);
1044 			break;
1045 
1046 		case QLA_PCI_STATUS:
1047 			len = (uint32_t)iocp->ioc_count;
1048 			if (len != sizeof (pci_cfg_t)) {
1049 				cmn_err(CE_WARN, "QLA_PCI_STATUS size error, "
1050 				    "driver size 0x%x not 0x%x ",
1051 				    (int)MBLKL(dmp),
1052 				    (int)sizeof (pci_cfg_t));
1053 				return (IOC_INVAL);
1054 			}
1055 			pci_cfg = (pci_cfg_t *)(void *)dmp->b_rptr;
1056 			/* get PCI configuration */
1057 			bcopy((const void *)(&qlge->pci_cfg),
1058 			    (void *)pci_cfg, len);
1059 			break;
1060 
1061 		case QLA_GET_PROP:
1062 			len = (uint32_t)iocp->ioc_count;
1063 			if (len != sizeof (struct qlnic_prop_info)) {
1064 				cmn_err(CE_WARN, "QLA_GET_PROP size error, "
1065 				    "driver size 0x%x not 0x%x ",
1066 				    (int)MBLKL(dmp),
1067 				    (int)sizeof (pci_cfg_t));
1068 				return (IOC_INVAL);
1069 			}
1070 			prop_ptr =
1071 			    (struct qlnic_prop_info *)(void *)dmp->b_rptr;
1072 			/* get various properties */
1073 			mutex_enter(&qlge->mbx_mutex);
1074 			(void) ql_get_firmware_version(qlge,
1075 			    &prop_ptr->mpi_version);
1076 			(void) ql_get_fw_state(qlge, &prop_ptr->fw_state);
1077 			(void) qlge_get_link_status(qlge,
1078 			    &prop_ptr->link_status);
1079 			mutex_exit(&qlge->mbx_mutex);
1080 			break;
1081 
1082 		case QLA_LIST_ADAPTER_INFO:
1083 			/* count must be exactly same */
1084 			if (iocp->ioc_count != sizeof (ql_adapter_info_t)) {
1085 				return (IOC_INVAL);
1086 			}
1087 			if (ql_get_pci_bus_info(qlge,
1088 			    &(adapter_info_ptr->pci_binding)) != DDI_SUCCESS) {
1089 				return (IOC_INVAL);
1090 			}
1091 			adapter_info_ptr->vendor_id =
1092 			    qlge->pci_cfg.vendor_id;
1093 			adapter_info_ptr->sub_vendor_id =
1094 			    qlge->pci_cfg.sub_vendor_id;
1095 			adapter_info_ptr->device_id =
1096 			    qlge->pci_cfg.device_id;
1097 			adapter_info_ptr->sub_device_id =
1098 			    qlge->pci_cfg.sub_device_id;
1099 
1100 			bcopy(qlge->unicst_addr[0].addr.ether_addr_octet,
1101 			    &(adapter_info_ptr->cur_addr), ETHERADDRL);
1102 			break;
1103 
1104 		case QLA_SHOW_REGION:
1105 			len = (uint32_t)iocp->ioc_count;
1106 			bdesc = (caddr_t)dmp->b_rptr;
1107 			if (CFG_IST(qlge, CFG_CHIP_8100))
1108 				(void) sprintf(bdesc, "ISP 8100 available "
1109 				    "regions %s", ISP_8100_REGION);
1110 			break;
1111 
1112 		case QLA_CONTINUE_COPY_OUT:
1113 			if (qlge->ioctl_buf_ptr == NULL)
1114 				return (IOC_INVAL);
1115 			len = (uint32_t)iocp->ioc_count;
1116 			bp = qlge->ioctl_buf_ptr;
1117 			bp += qlge->ioctl_transferred_bytes;
1118 			remaining_bytes =
1119 			    qlge->ioctl_total_length -
1120 			    qlge->ioctl_transferred_bytes;
1121 			/* how many data bytes sent this time */
1122 			payload_len =
1123 			    (uint16_t)min(IOCTL_MAX_DATA_LEN, remaining_bytes);
1124 			/* create packet header */
1125 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1126 			pheader->version = 0;
1127 			pheader->total_length = qlge->ioctl_total_length;
1128 			pheader->expected_trans_times =
1129 			    qlge->expected_trans_times;
1130 			pheader->payload_length = payload_len;
1131 			/* create packet payload */
1132 			bdesc = (caddr_t)dmp->b_rptr;
1133 			bdesc += IOCTL_HEADER_LEN;
1134 			bcopy(bp, bdesc, pheader->payload_length);
1135 			qlge->ioctl_transferred_bytes +=
1136 			    pheader->payload_length;
1137 			QL_PRINT(DBG_GLD, ("QLA_CONTINUE_COPY_OUT, %d bytes"
1138 			    " exported \n", payload_len));
1139 			if (qlge->ioctl_transferred_bytes >=
1140 			    qlge->ioctl_total_length) {
1141 				QL_PRINT(DBG_GLD, ("all data out,clean up \n"));
1142 				kmem_free(qlge->ioctl_buf_ptr,
1143 				    qlge->ioctl_buf_lenth);
1144 				qlge->ioctl_buf_ptr = NULL;
1145 				qlge->ioctl_buf_lenth = 0;
1146 			}
1147 			iocp->ioc_count = len;
1148 			break;
1149 
1150 		case QLA_CONTINUE_COPY_IN:
1151 			if (qlge->ioctl_buf_ptr == NULL)
1152 				return (IOC_INVAL);
1153 			len = (uint32_t)iocp->ioc_count;
1154 			bdesc = qlge->ioctl_buf_ptr;
1155 			bdesc += qlge->ioctl_transferred_bytes;
1156 			remaining_bytes = qlge->ioctl_total_length -
1157 			    qlge->ioctl_transferred_bytes;
1158 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1159 			payload_len = pheader->payload_length;
1160 			/* create packet header */
1161 			pheader->version = 0;
1162 			pheader->total_length = qlge->ioctl_total_length;
1163 			pheader->expected_trans_times =
1164 			    qlge->expected_trans_times;
1165 			/* get packet payload */
1166 			bp = (caddr_t)dmp->b_rptr;
1167 			bp += IOCTL_HEADER_LEN;
1168 			bcopy(bp, bdesc, pheader->payload_length);
1169 			qlge->ioctl_transferred_bytes +=
1170 			    pheader->payload_length;
1171 			QL_PRINT(DBG_GLD, ("QLA_CONTINUE_COPY_IN, %d bytes "
1172 			    "received \n", payload_len));
1173 			if (qlge->ioctl_transferred_bytes >=
1174 			    qlge->ioctl_total_length) {
1175 				region = pheader->option[0];
1176 				(void) ql_get_flash_table_region_info(qlge,
1177 				    region, &addr, &size);
1178 				QL_PRINT(DBG_GLD, ("write data to region 0x%x,"
1179 				    " addr 0x%x, max size %d bytes\n",
1180 				    region, addr, size));
1181 				(void) qlge_load_flash(qlge,
1182 				    (uint8_t *)qlge->ioctl_buf_ptr,
1183 				    qlge->ioctl_transferred_bytes /* size */,
1184 				    addr);
1185 				QL_PRINT(DBG_GLD, ("all %d data written, do "
1186 				    "clean up \n",
1187 				    qlge->ioctl_transferred_bytes));
1188 				kmem_free(qlge->ioctl_buf_ptr,
1189 				    qlge->ioctl_buf_lenth);
1190 				qlge->ioctl_buf_ptr = NULL;
1191 				qlge->ioctl_buf_lenth = 0;
1192 			}
1193 			iocp->ioc_count = len;
1194 			break;
1195 
1196 		case QLA_READ_CONTRL_REGISTERS:
1197 			if (qlge->ioctl_buf_ptr == NULL) {
1198 				qlge->ioctl_buf_lenth =
1199 				    IOCTL_MAX_BUF_SIZE; /* 512k */
1200 				qlge->ioctl_buf_ptr =
1201 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1202 				    KM_SLEEP);
1203 				if (qlge->ioctl_buf_ptr == NULL) {
1204 					cmn_err(CE_WARN, "%s(%d): Unable to "
1205 					    "allocate ioctl buffer",
1206 					    __func__, qlge->instance);
1207 					return (IOC_INVAL);
1208 				}
1209 			}
1210 			len = read_ctrl_reg_set(qlge, qlge->ioctl_buf_ptr);
1211 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1212 			/* build initial ioctl packet header */
1213 			build_init_pkt_header(qlge, pheader, len);
1214 			iocp->ioc_count = sizeof (*pheader);
1215 			break;
1216 
1217 		case QLA_SUPPORTED_DUMP_TYPES: /* show available regions */
1218 			len = (uint32_t)iocp->ioc_count;
1219 			bdesc = (caddr_t)dmp->b_rptr;
1220 			if (CFG_IST(qlge, CFG_CHIP_8100))
1221 				(void) sprintf(bdesc, "ISP 8100 supported dump"
1222 				    " types: %s", ISP_8100_AVAILABLE_DUMPS);
1223 			break;
1224 
1225 		case QLA_GET_BINARY_CORE_DUMP:
1226 			len = (uint32_t)iocp->ioc_count;
1227 			requested_dump = *((uint16_t *)(void *)dmp->b_rptr);
1228 			rval = ql_binary_core_dump(qlge, requested_dump, &len);
1229 			if (rval == DDI_SUCCESS) {
1230 				pheader =
1231 				    (ioctl_header_info_t *)(void *)dmp->b_rptr;
1232 				/* build initial ioctl packet header */
1233 				build_init_pkt_header(qlge, pheader, len);
1234 				iocp->ioc_count = sizeof (*pheader);
1235 			} else {
1236 				cmn_err(CE_WARN, "ql_binary_core_dump error");
1237 				return (IOC_INVAL);
1238 			}
1239 			break;
1240 
1241 		case QLA_TRIGGER_SYS_ERROR_EVENT:
1242 			(void) ql_trigger_system_error_event(qlge);
1243 			break;
1244 
1245 		case QLA_READ_VPD:
1246 			if (qlge->ioctl_buf_ptr == NULL) {
1247 				qlge->ioctl_buf_lenth =
1248 				    IOCTL_MAX_BUF_SIZE; /* 512k */
1249 				qlge->ioctl_buf_ptr =
1250 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1251 				    KM_SLEEP);
1252 				if (qlge->ioctl_buf_ptr == NULL) {
1253 					cmn_err(CE_WARN, "%s(%d): Unable to "
1254 					    "allocate ioctl buffer",
1255 					    __func__, qlge->instance);
1256 					return (IOC_INVAL);
1257 				}
1258 			}
1259 			len = (uint32_t)iocp->ioc_count;
1260 			QL_PRINT(DBG_GLD, (" 0x%x user buffer available \n",
1261 			    len));
1262 			(void) ql_flash_vpd(qlge,
1263 			    (uint8_t *)qlge->ioctl_buf_ptr);
1264 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1265 			/* build initial ioctl packet header */
1266 			build_init_pkt_header(qlge, pheader,
1267 			    ISP_8100_VPD0_SIZE);
1268 			iocp->ioc_count = sizeof (*pheader);
1269 			break;
1270 
1271 		case QLA_MANUAL_READ_FLASH:
1272 			if (qlge->ioctl_buf_ptr == NULL) {
1273 				qlge->ioctl_buf_lenth =
1274 				    IOCTL_MAX_BUF_SIZE; /* 512k */
1275 				qlge->ioctl_buf_ptr =
1276 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1277 				    KM_SLEEP);
1278 				if (qlge->ioctl_buf_ptr == NULL) {
1279 					cmn_err(CE_WARN, "%s(%d): Unable to "
1280 					    "allocate ioctl buffer",
1281 					    __func__, qlge->instance);
1282 					return (IOC_INVAL);
1283 				}
1284 			}
1285 			len = (uint32_t)iocp->ioc_count;
1286 			rval = qlge_dump_fcode(qlge,
1287 			    (uint8_t *)qlge->ioctl_buf_ptr,
1288 			    flash_io_info_ptr->size,
1289 			    flash_io_info_ptr->addr);
1290 			if (rval != DDI_SUCCESS) {
1291 				return (IOC_INVAL);
1292 			}
1293 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1294 			/* build initial ioctl packet header */
1295 			build_init_pkt_header(qlge, pheader,
1296 			    flash_io_info_ptr->size);
1297 			iocp->ioc_count = sizeof (*pheader);
1298 			break;
1299 
1300 		case QLA_READ_FLASH:
1301 			if (qlge->ioctl_buf_ptr == NULL) {
1302 				qlge->ioctl_buf_lenth = IOCTL_MAX_BUF_SIZE;
1303 				qlge->ioctl_buf_ptr =
1304 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1305 				    KM_SLEEP);
1306 				if (qlge->ioctl_buf_ptr == NULL) {
1307 					cmn_err(CE_WARN, "%s(%d): Unable to"
1308 					    "allocate ioctl buffer",
1309 					    __func__, qlge->instance);
1310 					return (IOC_INVAL);
1311 				}
1312 			}
1313 			len = (uint32_t)iocp->ioc_count;
1314 			region = *pvalue;
1315 			if (ql_get_flash_table_region_info(qlge, region, &addr,
1316 			    &size) != DDI_SUCCESS)
1317 				return (IOC_INVAL);
1318 			rval = qlge_dump_fcode(qlge,
1319 			    (uint8_t *)qlge->ioctl_buf_ptr,
1320 			    size, addr);
1321 			if (rval != DDI_SUCCESS) {
1322 				return (IOC_INVAL);
1323 			}
1324 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1325 			/* build initial ioctl packet header */
1326 			build_init_pkt_header(qlge, pheader, size);
1327 			iocp->ioc_count = sizeof (*pheader);
1328 			break;
1329 
1330 		case QLA_WRITE_FLASH:
1331 			len = (uint32_t)iocp->ioc_count;
1332 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1333 			region = pheader->option[0];
1334 			qlge->ioctl_buf_lenth = pheader->total_length;
1335 			qlge->ioctl_total_length = pheader->total_length;
1336 			qlge->expected_trans_times =
1337 			    pheader->expected_trans_times;
1338 			qlge->ioctl_transferred_bytes = 0;
1339 			if (qlge->ioctl_buf_ptr == NULL) {
1340 				qlge->ioctl_buf_ptr =
1341 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1342 				    KM_SLEEP);
1343 				if (qlge->ioctl_buf_ptr == NULL) {
1344 					cmn_err(CE_WARN, "%s(%d): Unable to "
1345 					    "allocate ioctl buffer",
1346 					    __func__, qlge->instance);
1347 					return (IOC_INVAL);
1348 				}
1349 			}
1350 			QL_PRINT(DBG_GLD, ("QLA_WRITE_FLASH write to region "
1351 			    "%x, total buffer size 0x%x bytes\n",
1352 			    region, qlge->ioctl_buf_lenth));
1353 			iocp->ioc_count = sizeof (*pheader);
1354 			break;
1355 
1356 		case QLA_READ_FW_IMAGE:
1357 			if (qlge->ioctl_buf_ptr != NULL) {
1358 				kmem_free(qlge->ioctl_buf_ptr,
1359 				    qlge->ioctl_buf_lenth);
1360 			}
1361 			qlge->ioctl_buf_lenth = IOCTL_MAX_BUF_SIZE * 4;
1362 			qlge->ioctl_buf_ptr = kmem_zalloc(qlge->ioctl_buf_lenth,
1363 			    KM_SLEEP);
1364 			if (qlge->ioctl_buf_ptr == NULL) {
1365 				cmn_err(CE_WARN, "%s(%d): Unable to "
1366 				    "allocate ioctl buffer",
1367 				    __func__, qlge->instance);
1368 				return (IOC_INVAL);
1369 			}
1370 			len = (uint32_t)iocp->ioc_count;
1371 			iltds_ptr = (ql_iltds_description_header_t *)
1372 			    (void *)qlge->ioctl_buf_ptr;
1373 			iltds_ptr->iltds_table_header.signature =
1374 			    FLASH_ILTDS_SIGNATURE;
1375 			iltds_ptr->iltds_table_header.table_version = 1;
1376 			iltds_ptr->iltds_table_header.length =
1377 			    ILTDS_DESCRIPTION_HEADERS_LEN;
1378 			iltds_ptr->iltds_table_header.number_entries =
1379 			    IMAGE_TABLE_IMAGE_DEFAULT_ENTRIES +
1380 			    1 /* timestamp */;
1381 			iltds_ptr->iltds_table_header.reserved = 0;
1382 			iltds_ptr->iltds_table_header.version = 1;
1383 			/* where is the flash data saved */
1384 			bdesc = qlge->ioctl_buf_ptr +
1385 			    ILTDS_DESCRIPTION_HEADERS_LEN;
1386 			offset = iltds_ptr->iltds_table_header.length;
1387 			for (i = 0; i < IMAGE_TABLE_IMAGE_DEFAULT_ENTRIES;
1388 			    i++) {
1389 				region = iltds_image_entry_regions[i];
1390 				if (ql_get_flash_table_region_info(qlge,
1391 				    region, &addr, &size) != DDI_SUCCESS)
1392 					return (IOC_INVAL);
1393 				QL_PRINT(DBG_GLD, ("region %x addr 0x%x, 0x%x "
1394 				    "bytes\n", region, addr, size));
1395 				/* Dump one image entry */
1396 				rval = qlge_dump_fcode(qlge, (uint8_t *)bdesc,
1397 				    size, addr);
1398 				if (rval != DDI_SUCCESS) {
1399 					return (IOC_INVAL);
1400 				}
1401 				bdesc += size;
1402 				iltds_ptr->img_entry[i].region_type =
1403 				    (uint16_t)region;
1404 				iltds_ptr->img_entry[i].region_version_len = 0;
1405 				iltds_ptr->img_entry[i].region_version[0] = 0;
1406 				iltds_ptr->img_entry[i].region_version[1] = 0;
1407 				iltds_ptr->img_entry[i].region_version[2] = 0;
1408 				iltds_ptr->img_entry[i].offset_lo = LSW(offset);
1409 				iltds_ptr->img_entry[i].offset_hi = MSW(offset);
1410 				iltds_ptr->img_entry[i].size_lo = LSW(size);
1411 				iltds_ptr->img_entry[i].size_hi = MSW(size);
1412 				iltds_ptr->img_entry[i].swap_mode = 0;
1413 				iltds_ptr->img_entry[i].card_type = 0;
1414 				QL_PRINT(DBG_GLD, ("image offset %x size %x "
1415 				    "bytes\n", offset, size));
1416 				QL_PRINT(DBG_GLD, ("offset %x lsw %x msw %x"
1417 				    " \n", offset, LSW(offset), MSW(offset)));
1418 				offset += size;
1419 			}
1420 			/* Last entry */
1421 			iltds_ptr->time_stamp.region_type =
1422 			    FLT_REGION_TIME_STAMP;
1423 			iltds_ptr->time_stamp.region_version_len = 0;
1424 			iltds_ptr->time_stamp.region_version[0] = 0;
1425 			iltds_ptr->time_stamp.region_version[1] = 0;
1426 			iltds_ptr->time_stamp.region_version[2] = 0;
1427 			iltds_ptr->time_stamp.year = 0x09;
1428 			iltds_ptr->time_stamp.month = 0x01;
1429 			iltds_ptr->time_stamp.day = 0x20;
1430 			iltds_ptr->time_stamp.hour = 0x14;
1431 			iltds_ptr->time_stamp.min = 0x20;
1432 			iltds_ptr->time_stamp.sec = 0x50;
1433 
1434 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1435 			/* build initial ioctl packet header */
1436 			build_init_pkt_header(qlge, pheader, offset);
1437 			iocp->ioc_count = sizeof (*pheader);
1438 			break;
1439 
1440 		case QLA_WRITE_FW_IMAGE_HEADERS:
1441 			len = (uint32_t)iocp->ioc_count;
1442 			if (len == 0)
1443 				return (IOC_INVAL);
1444 			ql_iltds_header_ptr =
1445 			    (ql_iltds_header_t *)(void *)dmp->b_rptr;
1446 			if (len != ql_iltds_header_ptr->length) {
1447 				cmn_err(CE_WARN, "QLA_WRITE_FW_IMAGE_HEADERS "
1448 				    "data length error!"
1449 				    " %x bytes expected, %x received",
1450 				    ql_iltds_header_ptr->length, len);
1451 				return (IOC_INVAL);
1452 			}
1453 			QL_PRINT(DBG_GLD, ("Fw Image header len 0x%x bytes, "
1454 			    "0x%x entries\n",
1455 			    len, ql_iltds_header_ptr->number_entries));
1456 			ql_dump_buf("all copy in data:\n",
1457 			    (uint8_t *)dmp->b_rptr, 8, len);
1458 			mp->b_cont = NULL;
1459 			break;
1460 
1461 		case QLA_SOFT_RESET:
1462 			iocp->ioc_count = 0;
1463 			ql_wake_asic_reset_soft_intr(qlge);
1464 			QL_PRINT(DBG_GLD, ("QLA_SOFT_RESET started \n"));
1465 			break;
1466 
1467 		default:
1468 			return (IOC_INVAL);
1469 	}
1470 
1471 	return (IOC_REPLY);
1472 }
1473 
1474 /*
1475  * Loopback ioctl code
1476  */
1477 static lb_property_t loopmodes[] = {
1478 	{ normal,	"normal",	QLGE_LOOP_NONE			},
1479 	{ internal,	"parallel",	QLGE_LOOP_INTERNAL_PARALLEL	},
1480 	{ internal,	"serial",	QLGE_LOOP_INTERNAL_SERIAL	},
1481 };
1482 
1483 /*
1484  * Set Loopback mode
1485  */
1486 static enum ioc_reply
1487 qlge_set_loop_mode(qlge_t *qlge, uint32_t mode)
1488 {
1489 	/*
1490 	 * If the mode is same as current mode ...
1491 	 */
1492 	if (mode == qlge->loop_back_mode)
1493 		return (IOC_ACK);
1494 
1495 	/*
1496 	 * Validate the requested mode
1497 	 */
1498 	switch (mode) {
1499 	default:
1500 		return (IOC_INVAL);
1501 
1502 	case QLGE_LOOP_NONE:
1503 	case QLGE_LOOP_INTERNAL_PARALLEL:
1504 	case QLGE_LOOP_INTERNAL_SERIAL:
1505 		break;
1506 	}
1507 
1508 	/*
1509 	 * All OK; reprogram for the new mode ...
1510 	 */
1511 	qlge->loop_back_mode = mode;
1512 	mutex_enter(&qlge->mbx_mutex);
1513 	(void) ql_set_loop_back_mode(qlge);
1514 	mutex_exit(&qlge->mbx_mutex);
1515 	return (IOC_REPLY);
1516 }
1517 /*
1518  * Loopback ioctl
1519  */
1520 /* ARGSUSED */
1521 enum ioc_reply
1522 ql_loop_ioctl(qlge_t *qlge, queue_t *wq, mblk_t *mp, struct iocblk *iocp)
1523 {
1524 	lb_info_sz_t *lbsp;
1525 	lb_property_t *lbpp;
1526 	uint32_t *lbmp;
1527 	int cmd;
1528 
1529 	_NOTE(ARGUNUSED(wq))
1530 	/*
1531 	 * Validate format of ioctl
1532 	 */
1533 	if (mp->b_cont == NULL)
1534 		return (IOC_INVAL);
1535 
1536 	cmd = iocp->ioc_cmd;
1537 	switch (cmd) {
1538 	default:
1539 		/* NOTREACHED */
1540 		QL_PRINT(DBG_GLD, ("%s(%d) invalid cmd 0x%x\n",
1541 		    __func__, qlge->instance, cmd));
1542 		return (IOC_INVAL);
1543 
1544 	case LB_GET_INFO_SIZE:
1545 		if (iocp->ioc_count != sizeof (lb_info_sz_t))
1546 			return (IOC_INVAL);
1547 		lbsp = (void *)mp->b_cont->b_rptr;
1548 		*lbsp = sizeof (loopmodes);
1549 		return (IOC_REPLY);
1550 
1551 	case LB_GET_INFO:
1552 		if (iocp->ioc_count != sizeof (loopmodes))
1553 			return (IOC_INVAL);
1554 		lbpp = (void *)mp->b_cont->b_rptr;
1555 		bcopy(loopmodes, lbpp, sizeof (loopmodes));
1556 		return (IOC_REPLY);
1557 
1558 	case LB_GET_MODE:
1559 		if (iocp->ioc_count != sizeof (uint32_t))
1560 			return (IOC_INVAL);
1561 		lbmp = (void *)mp->b_cont->b_rptr;
1562 		*lbmp = qlge->loop_back_mode;
1563 		return (IOC_REPLY);
1564 
1565 	case LB_SET_MODE:
1566 		if (iocp->ioc_count != sizeof (uint32_t))
1567 			return (IOC_INVAL);
1568 		lbmp = (void *)mp->b_cont->b_rptr;
1569 		return (qlge_set_loop_mode(qlge, *lbmp));
1570 	}
1571 }
1572 
1573 /*
1574  * Dumps binary data from firmware.
1575  */
1576 static int
1577 ql_8xxx_binary_core_dump_with_header(qlge_t *qlge, caddr_t buf,
1578     uint32_t *len_ptr)
1579 {
1580 	caddr_t bp = buf;
1581 	int rval = DDI_SUCCESS;
1582 	ql_dump_image_header_t *ql_dump_image_header_ptr =
1583 	    (ql_dump_image_header_t *)(void *)bp;
1584 
1585 	ql_dump_image_header_ptr->signature = DUMP_IMAGE_HEADER_SIGNATURE;
1586 	ql_dump_image_header_ptr->version = 1;
1587 	ql_dump_image_header_ptr->header_length = 16;
1588 	ql_dump_image_header_ptr->data_type = DUMP_TYPE_CORE_DUMP;
1589 	/* point to real dump data area */
1590 	bp += sizeof (ql_dump_image_header_t);
1591 	bcopy(&qlge->ql_mpi_coredump, bp, sizeof (ql_mpi_coredump_t));
1592 	ql_dump_image_header_ptr->data_length = sizeof (ql_mpi_coredump_t);
1593 	/* total length: header + data image */
1594 	ql_dump_image_header_ptr->checksum = (uint16_t)
1595 	    (ql_dump_image_header_ptr->signature
1596 	    +ql_dump_image_header_ptr->version
1597 	    +ql_dump_image_header_ptr->header_length
1598 	    +ql_dump_image_header_ptr->data_type
1599 	    +ql_dump_image_header_ptr->data_length);
1600 
1601 	*len_ptr = ql_dump_image_header_ptr->header_length +
1602 	    ql_dump_image_header_ptr->data_length;
1603 	QL_PRINT(DBG_GLD, ("%s done,core dump lenth %d bytes\n",
1604 	    __func__, *len_ptr));
1605 	return (rval);
1606 }
1607 
1608 /*
1609  * Dump registers value in binary format
1610  */
1611 static int
1612 ql_8xxx_binary_register_dump_with_header(qlge_t *qlge, caddr_t buf,
1613     uint32_t *len_ptr)
1614 {
1615 	caddr_t bp = buf;
1616 	int i;
1617 	uint32_t *data_ptr;
1618 	int rval = DDI_SUCCESS;
1619 
1620 	ql_dump_image_header_t *ql_dump_image_header_ptr =
1621 	    (ql_dump_image_header_t *)(void *)bp;
1622 	ql_dump_image_header_ptr->signature =
1623 	    DUMP_IMAGE_HEADER_SIGNATURE;
1624 	ql_dump_image_header_ptr->version = 1;
1625 	ql_dump_image_header_ptr->header_length = 16;
1626 	ql_dump_image_header_ptr->data_type = DUMP_TYPE_REGISTER_DUMP;
1627 	/* point to real dump data area */
1628 	bp += sizeof (ql_dump_image_header_t);
1629 	data_ptr = (uint32_t *)(void *)bp;
1630 
1631 	for (i = 0; i <= 0xfc; i += 4) {
1632 		*data_ptr = ql_read_reg(qlge, i);
1633 		data_ptr++;
1634 	}
1635 	ql_dump_image_header_ptr->data_length = 0x100; /* 0 ~ 0xFF */
1636 	/* total length: header + data image */
1637 	ql_dump_image_header_ptr->checksum = (uint16_t)
1638 	    (ql_dump_image_header_ptr->signature
1639 	    +ql_dump_image_header_ptr->version
1640 	    +ql_dump_image_header_ptr->header_length
1641 	    +ql_dump_image_header_ptr->data_type
1642 	    +ql_dump_image_header_ptr->data_length);
1643 
1644 	*len_ptr = ql_dump_image_header_ptr->header_length +
1645 	    ql_dump_image_header_ptr->data_length;
1646 
1647 	QL_PRINT(DBG_GLD, ("%s done, dump lenth %x bytes\n", __func__,
1648 	    *len_ptr));
1649 
1650 	return (rval);
1651 }
1652 
1653 /*
1654  * Core dump in binary format
1655  */
1656 static int
1657 ql_binary_core_dump(qlge_t *qlge, uint32_t requested_dumps, uint32_t *len_ptr)
1658 {
1659 	int rval = DDI_FAILURE;
1660 	uint32_t length, size = 0;
1661 	uint64_t timestamp;
1662 	caddr_t bp;
1663 	ql_dump_header_t *ql_dump_header_ptr;
1664 	ql_dump_footer_t *ql_dump_footer_ptr;
1665 
1666 	if (qlge->ioctl_buf_ptr == NULL) {
1667 		qlge->ioctl_buf_lenth = IOCTL_MAX_BUF_SIZE; /* 512k */
1668 		qlge->ioctl_buf_ptr =
1669 		    kmem_zalloc(qlge->ioctl_buf_lenth, KM_SLEEP);
1670 		if (qlge->ioctl_buf_ptr == NULL) {
1671 			cmn_err(CE_WARN,
1672 			    "%s(%d): Unable to allocate ioctl buffer",
1673 			    __func__, qlge->instance);
1674 			goto out;
1675 		}
1676 	}
1677 
1678 	/* description info header */
1679 	ql_dump_header_ptr = (ql_dump_header_t *)(void *)qlge->ioctl_buf_ptr;
1680 	/* add QTSB signature */
1681 	ql_dump_header_ptr->signature = DUMP_DESCRIPTION_HEADER_SIGNATURE;
1682 	ql_dump_header_ptr->version = 1;
1683 	ql_dump_header_ptr->length = 16;
1684 	ql_dump_header_ptr->reserved = 0;
1685 	/* get dump creation timestamp */
1686 	timestamp = ddi_get_time();
1687 	timestamp *= 1000000;
1688 	ql_dump_header_ptr->time_stamp_lo = LSW(timestamp);
1689 	ql_dump_header_ptr->time_stamp_hi = MSW(timestamp);
1690 	/* point to first image header area */
1691 	length = sizeof (ql_dump_header_t);
1692 	bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1693 
1694 	if (CFG_IST(qlge, CFG_CHIP_8100)) {
1695 		/* if dumping all */
1696 		if ((requested_dumps & DUMP_REQUEST_ALL) != 0) {
1697 			ql_dump_header_ptr->num_dumps = 2;
1698 			(void) ql_8xxx_binary_core_dump_with_header(qlge,
1699 			    bp, &size);
1700 			length += size;
1701 			bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1702 			(void) ql_8xxx_binary_register_dump_with_header(qlge,
1703 			    bp, &size);
1704 			length += size;
1705 			bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1706 		} else if ((requested_dumps & DUMP_REQUEST_CORE) != 0) {
1707 			ql_dump_header_ptr->num_dumps = 1;
1708 			(void) ql_8xxx_binary_core_dump_with_header(qlge,
1709 			    bp, &size);
1710 			length += size;
1711 			bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1712 		} else if ((requested_dumps & DUMP_REQUEST_REGISTER) != 0) {
1713 			ql_dump_header_ptr->num_dumps = 1;
1714 			(void) ql_8xxx_binary_register_dump_with_header(qlge,
1715 			    bp, &size);
1716 			length += size;
1717 			bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1718 		} else {
1719 			cmn_err(CE_WARN, "%s(%d): not supported dump type %d",
1720 			    __func__, qlge->instance, requested_dumps);
1721 			goto out;
1722 		}
1723 	}
1724 
1725 	ql_dump_footer_ptr = (ql_dump_footer_t *)(void *)bp;
1726 	ql_dump_footer_ptr->signature = DUMP_DESCRIPTION_FOOTER_SIGNATURE;
1727 	ql_dump_footer_ptr->version = 1;
1728 	ql_dump_footer_ptr->length = 16;
1729 	ql_dump_footer_ptr->reserved = 0;
1730 	timestamp = ddi_get_time();
1731 	timestamp *= 1000000;
1732 	ql_dump_footer_ptr->time_stamp_lo = LSW(timestamp);
1733 	ql_dump_footer_ptr->time_stamp_hi = MSW(timestamp);
1734 	length += ql_dump_footer_ptr->length;
1735 	rval = DDI_SUCCESS;
1736 	*len_ptr = length;
1737 	QL_PRINT(DBG_MBX, ("%s(%d): exiting,total %x bytes\n",
1738 	    __func__, qlge->instance, length));
1739 out:
1740 	return (rval);
1741 }
1742 
1743 /*
1744  * build core dump segment header
1745  */
1746 static void
1747 ql_build_coredump_seg_header(mpi_coredump_segment_header_t *seg_hdr,
1748     uint32_t seg_number, uint32_t seg_size, uint8_t *desc)
1749 {
1750 	(void) memset(seg_hdr, 0, sizeof (mpi_coredump_segment_header_t));
1751 	seg_hdr->cookie = MPI_COREDUMP_COOKIE;
1752 	seg_hdr->seg_number = seg_number;
1753 	seg_hdr->seg_size = seg_size;
1754 	(void) memcpy(seg_hdr->description, desc,
1755 	    (sizeof (seg_hdr->description))-1);
1756 }
1757 
1758 /*
1759  * Unpause MPI risc
1760  */
1761 static int
1762 ql_unpause_mpi_risc(qlge_t *qlge)
1763 {
1764 	uint32_t tmp;
1765 
1766 	/* Un-pause the RISC */
1767 	tmp = ql_read_reg(qlge, REG_HOST_CMD_STATUS);
1768 	if ((tmp & CSR_RP) == 0)
1769 		return (DDI_FAILURE);
1770 
1771 	ql_write_reg(qlge, REG_HOST_CMD_STATUS, CSR_CMD_CLR_PAUSE);
1772 	return (DDI_SUCCESS);
1773 }
1774 
1775 /*
1776  * Pause MPI risc
1777  */
1778 static int
1779 ql_pause_mpi_risc(qlge_t *qlge)
1780 {
1781 	uint32_t tmp;
1782 	int count = 10;
1783 
1784 	/* Pause the RISC */
1785 	ql_write_reg(qlge, REG_HOST_CMD_STATUS, CSR_CMD_SET_PAUSE);
1786 	do {
1787 		tmp = ql_read_reg(qlge, REG_HOST_CMD_STATUS);
1788 		if ((tmp & CSR_RP) != 0)
1789 			break;
1790 		qlge_delay(10);
1791 		count--;
1792 	} while (count);
1793 	return ((count == 0) ? DDI_FAILURE : DDI_SUCCESS);
1794 }
1795 
1796 /*
1797  * Get Interrupt Status registers value
1798  */
1799 static void
1800 ql_get_intr_states(qlge_t *qlge, uint32_t *buf)
1801 {
1802 	int i;
1803 
1804 	for (i = 0; i < MAX_RX_RINGS; i++, buf++) {
1805 		/* read the interrupt enable register for each rx ring */
1806 		ql_write_reg(qlge, REG_INTERRUPT_ENABLE, 0x037f0300 + i);
1807 		*buf = ql_read_reg(qlge, REG_INTERRUPT_ENABLE);
1808 	}
1809 }
1810 
1811 /*
1812  * Read serdes register
1813  */
1814 static int
1815 ql_read_serdes_reg(qlge_t *qlge, uint32_t reg, uint32_t *data)
1816 {
1817 	int rtn_val = DDI_FAILURE;
1818 
1819 	/* wait for reg to come ready */
1820 	if (ql_wait_reg_bit(qlge, REG_XG_SERDES_ADDR,
1821 	    XG_SERDES_ADDR_RDY, BIT_SET, 0) != DDI_SUCCESS)
1822 		goto exit;
1823 	/* set up for reg read */
1824 	ql_write_reg(qlge, REG_XG_SERDES_ADDR, reg | PROC_ADDR_R);
1825 	/* wait for reg to come ready */
1826 	if (ql_wait_reg_bit(qlge, REG_XG_SERDES_ADDR,
1827 	    XG_SERDES_ADDR_RDY, BIT_SET, 0) != DDI_SUCCESS)
1828 		goto exit;
1829 	/* get the data */
1830 	*data = ql_read_reg(qlge, REG_XG_SERDES_DATA);
1831 	rtn_val = DDI_SUCCESS;
1832 exit:
1833 	return (rtn_val);
1834 }
1835 
1836 /*
1837  * Read XGMAC register
1838  */
1839 static int
1840 ql_get_xgmac_regs(qlge_t *qlge, uint32_t *buf)
1841 {
1842 	int status;
1843 	int i;
1844 
1845 	for (i = 0; i < XGMAC_REGISTER_END; i += 4, buf ++) {
1846 		switch (i) {
1847 		case  PAUSE_SRC_LO		:
1848 		case  PAUSE_SRC_HI		:
1849 		case  GLOBAL_CFG		:
1850 		case  TX_CFG			:
1851 		case  RX_CFG			:
1852 		case  FLOW_CTL			:
1853 		case  PAUSE_OPCODE		:
1854 		case  PAUSE_TIMER		:
1855 		case  PAUSE_FRM_DEST_LO		:
1856 		case  PAUSE_FRM_DEST_HI		:
1857 		case  MAC_TX_PARAMS		:
1858 		case  MAC_RX_PARAMS		:
1859 		case  MAC_SYS_INT		:
1860 		case  MAC_SYS_INT_MASK		:
1861 		case  MAC_MGMT_INT		:
1862 		case  MAC_MGMT_IN_MASK		:
1863 		case  EXT_ARB_MODE		:
1864 		case  TX_PKTS		:
1865 		case  TX_PKTS_LO		:
1866 		case  TX_BYTES			:
1867 		case  TX_BYTES_LO		:
1868 		case  TX_MCAST_PKTS		:
1869 		case  TX_MCAST_PKTS_LO		:
1870 		case  TX_BCAST_PKTS		:
1871 		case  TX_BCAST_PKTS_LO		:
1872 		case  TX_UCAST_PKTS		:
1873 		case  TX_UCAST_PKTS_LO		:
1874 		case  TX_CTL_PKTS		:
1875 		case  TX_CTL_PKTS_LO		:
1876 		case  TX_PAUSE_PKTS		:
1877 		case  TX_PAUSE_PKTS_LO		:
1878 		case  TX_64_PKT			:
1879 		case  TX_64_PKT_LO		:
1880 		case  TX_65_TO_127_PKT		:
1881 		case  TX_65_TO_127_PKT_LO	:
1882 		case  TX_128_TO_255_PKT		:
1883 		case  TX_128_TO_255_PKT_LO	:
1884 		case  TX_256_511_PKT		:
1885 		case  TX_256_511_PKT_LO		:
1886 		case  TX_512_TO_1023_PKT	:
1887 		case  TX_512_TO_1023_PKT_LO	:
1888 		case  TX_1024_TO_1518_PKT	:
1889 		case  TX_1024_TO_1518_PKT_LO	:
1890 		case  TX_1519_TO_MAX_PKT	:
1891 		case  TX_1519_TO_MAX_PKT_LO	:
1892 		case  TX_UNDERSIZE_PKT		:
1893 		case  TX_UNDERSIZE_PKT_LO	:
1894 		case  TX_OVERSIZE_PKT		:
1895 		case  TX_OVERSIZE_PKT_LO	:
1896 		case  RX_HALF_FULL_DET		:
1897 		case  TX_HALF_FULL_DET_LO	:
1898 		case  RX_OVERFLOW_DET		:
1899 		case  TX_OVERFLOW_DET_LO	:
1900 		case  RX_HALF_FULL_MASK		:
1901 		case  TX_HALF_FULL_MASK_LO	:
1902 		case  RX_OVERFLOW_MASK		:
1903 		case  TX_OVERFLOW_MASK_LO	:
1904 		case  STAT_CNT_CTL		:
1905 		case  AUX_RX_HALF_FULL_DET	:
1906 		case  AUX_TX_HALF_FULL_DET	:
1907 		case  AUX_RX_OVERFLOW_DET	:
1908 		case  AUX_TX_OVERFLOW_DET	:
1909 		case  AUX_RX_HALF_FULL_MASK	:
1910 		case  AUX_TX_HALF_FULL_MASK	:
1911 		case  AUX_RX_OVERFLOW_MASK	:
1912 		case  AUX_TX_OVERFLOW_MASK	:
1913 		case  RX_BYTES			:
1914 		case  RX_BYTES_LO		:
1915 		case  RX_BYTES_OK		:
1916 		case  RX_BYTES_OK_LO		:
1917 		case  RX_PKTS			:
1918 		case  RX_PKTS_LO		:
1919 		case  RX_PKTS_OK		:
1920 		case  RX_PKTS_OK_LO		:
1921 		case  RX_BCAST_PKTS		:
1922 		case  RX_BCAST_PKTS_LO		:
1923 		case  RX_MCAST_PKTS		:
1924 		case  RX_MCAST_PKTS_LO		:
1925 		case  RX_UCAST_PKTS		:
1926 		case  RX_UCAST_PKTS_LO		:
1927 		case  RX_UNDERSIZE_PKTS		:
1928 		case  RX_UNDERSIZE_PKTS_LO	:
1929 		case  RX_OVERSIZE_PKTS		:
1930 		case  RX_OVERSIZE_PKTS_LO	:
1931 		case  RX_JABBER_PKTS		:
1932 		case  RX_JABBER_PKTS_LO		:
1933 		case  RX_UNDERSIZE_FCERR_PKTS	:
1934 		case  RX_UNDERSIZE_FCERR_PKTS_LO :
1935 		case  RX_DROP_EVENTS		:
1936 		case  RX_DROP_EVENTS_LO		:
1937 		case  RX_FCERR_PKTS		:
1938 		case  RX_FCERR_PKTS_LO		:
1939 		case  RX_ALIGN_ERR		:
1940 		case  RX_ALIGN_ERR_LO		:
1941 		case  RX_SYMBOL_ERR		:
1942 		case  RX_SYMBOL_ERR_LO		:
1943 		case  RX_MAC_ERR		:
1944 		case  RX_MAC_ERR_LO		:
1945 		case  RX_CTL_PKTS		:
1946 		case  RX_CTL_PKTS_LO		:
1947 		case  RX_PAUSE_PKTS		:
1948 		case  RX_PAUSE_PKTS_LO		:
1949 		case  RX_64_PKTS		:
1950 		case  RX_64_PKTS_LO		:
1951 		case  RX_65_TO_127_PKTS		:
1952 		case  RX_65_TO_127_PKTS_LO	:
1953 		case  RX_128_255_PKTS		:
1954 		case  RX_128_255_PKTS_LO	:
1955 		case  RX_256_511_PKTS		:
1956 		case  RX_256_511_PKTS_LO	:
1957 		case  RX_512_TO_1023_PKTS	:
1958 		case  RX_512_TO_1023_PKTS_LO	:
1959 		case  RX_1024_TO_1518_PKTS	:
1960 		case  RX_1024_TO_1518_PKTS_LO	:
1961 		case  RX_1519_TO_MAX_PKTS	:
1962 		case  RX_1519_TO_MAX_PKTS_LO	:
1963 		case  RX_LEN_ERR_PKTS		:
1964 		case  RX_LEN_ERR_PKTS_LO	:
1965 		case  MDIO_TX_DATA		:
1966 		case  MDIO_RX_DATA		:
1967 		case  MDIO_CMD			:
1968 		case  MDIO_PHY_ADDR		:
1969 		case  MDIO_PORT			:
1970 		case  MDIO_STATUS		:
1971 		case  TX_CBFC_PAUSE_FRAMES0	:
1972 		case  TX_CBFC_PAUSE_FRAMES0_LO	:
1973 		case  TX_CBFC_PAUSE_FRAMES1	:
1974 		case  TX_CBFC_PAUSE_FRAMES1_LO	:
1975 		case  TX_CBFC_PAUSE_FRAMES2	:
1976 		case  TX_CBFC_PAUSE_FRAMES2_LO	:
1977 		case  TX_CBFC_PAUSE_FRAMES3	:
1978 		case  TX_CBFC_PAUSE_FRAMES3_LO	:
1979 		case  TX_CBFC_PAUSE_FRAMES4	:
1980 		case  TX_CBFC_PAUSE_FRAMES4_LO	:
1981 		case  TX_CBFC_PAUSE_FRAMES5	:
1982 		case  TX_CBFC_PAUSE_FRAMES5_LO	:
1983 		case  TX_CBFC_PAUSE_FRAMES6	:
1984 		case  TX_CBFC_PAUSE_FRAMES6_LO	:
1985 		case  TX_CBFC_PAUSE_FRAMES7	:
1986 		case  TX_CBFC_PAUSE_FRAMES7_LO	:
1987 		case  TX_FCOE_PKTS		:
1988 		case  TX_FCOE_PKTS_LO		:
1989 		case  TX_MGMT_PKTS		:
1990 		case  TX_MGMT_PKTS_LO		:
1991 		case  RX_CBFC_PAUSE_FRAMES0	:
1992 		case  RX_CBFC_PAUSE_FRAMES0_LO	:
1993 		case  RX_CBFC_PAUSE_FRAMES1	:
1994 		case  RX_CBFC_PAUSE_FRAMES1_LO	:
1995 		case  RX_CBFC_PAUSE_FRAMES2	:
1996 		case  RX_CBFC_PAUSE_FRAMES2_LO	:
1997 		case  RX_CBFC_PAUSE_FRAMES3	:
1998 		case  RX_CBFC_PAUSE_FRAMES3_LO	:
1999 		case  RX_CBFC_PAUSE_FRAMES4	:
2000 		case  RX_CBFC_PAUSE_FRAMES4_LO	:
2001 		case  RX_CBFC_PAUSE_FRAMES5	:
2002 		case  RX_CBFC_PAUSE_FRAMES5_LO	:
2003 		case  RX_CBFC_PAUSE_FRAMES6	:
2004 		case  RX_CBFC_PAUSE_FRAMES6_LO	:
2005 		case  RX_CBFC_PAUSE_FRAMES7	:
2006 		case  RX_CBFC_PAUSE_FRAMES7_LO	:
2007 		case  RX_FCOE_PKTS		:
2008 		case  RX_FCOE_PKTS_LO		:
2009 		case  RX_MGMT_PKTS		:
2010 		case  RX_MGMT_PKTS_LO		:
2011 		case  RX_NIC_FIFO_DROP		:
2012 		case  RX_NIC_FIFO_DROP_LO	:
2013 		case  RX_FCOE_FIFO_DROP		:
2014 		case  RX_FCOE_FIFO_DROP_LO	:
2015 		case  RX_MGMT_FIFO_DROP		:
2016 		case  RX_MGMT_FIFO_DROP_LO	:
2017 		case  RX_PKTS_PRIORITY0		:
2018 		case  RX_PKTS_PRIORITY0_LO	:
2019 		case  RX_PKTS_PRIORITY1		:
2020 		case  RX_PKTS_PRIORITY1_LO	:
2021 		case  RX_PKTS_PRIORITY2		:
2022 		case  RX_PKTS_PRIORITY2_LO	:
2023 		case  RX_PKTS_PRIORITY3		:
2024 		case  RX_PKTS_PRIORITY3_LO	:
2025 		case  RX_PKTS_PRIORITY4		:
2026 		case  RX_PKTS_PRIORITY4_LO	:
2027 		case  RX_PKTS_PRIORITY5		:
2028 		case  RX_PKTS_PRIORITY5_LO	:
2029 		case  RX_PKTS_PRIORITY6		:
2030 		case  RX_PKTS_PRIORITY6_LO	:
2031 		case  RX_PKTS_PRIORITY7		:
2032 		case  RX_PKTS_PRIORITY7_LO	:
2033 		case  RX_OCTETS_PRIORITY0	:
2034 		case  RX_OCTETS_PRIORITY0_LO	:
2035 		case  RX_OCTETS_PRIORITY1	:
2036 		case  RX_OCTETS_PRIORITY1_LO	:
2037 		case  RX_OCTETS_PRIORITY2	:
2038 		case  RX_OCTETS_PRIORITY2_LO	:
2039 		case  RX_OCTETS_PRIORITY3	:
2040 		case  RX_OCTETS_PRIORITY3_LO	:
2041 		case  RX_OCTETS_PRIORITY4	:
2042 		case  RX_OCTETS_PRIORITY4_LO	:
2043 		case  RX_OCTETS_PRIORITY5	:
2044 		case  RX_OCTETS_PRIORITY5_LO	:
2045 		case  RX_OCTETS_PRIORITY6	:
2046 		case  RX_OCTETS_PRIORITY6_LO	:
2047 		case  RX_OCTETS_PRIORITY7	:
2048 		case  RX_OCTETS_PRIORITY7_LO	:
2049 		case  TX_PKTS_PRIORITY0		:
2050 		case  TX_PKTS_PRIORITY0_LO	:
2051 		case  TX_PKTS_PRIORITY1		:
2052 		case  TX_PKTS_PRIORITY1_LO	:
2053 		case  TX_PKTS_PRIORITY2		:
2054 		case  TX_PKTS_PRIORITY2_LO	:
2055 		case  TX_PKTS_PRIORITY3		:
2056 		case  TX_PKTS_PRIORITY3_LO	:
2057 		case  TX_PKTS_PRIORITY4		:
2058 		case  TX_PKTS_PRIORITY4_LO	:
2059 		case  TX_PKTS_PRIORITY5		:
2060 		case  TX_PKTS_PRIORITY5_LO	:
2061 		case  TX_PKTS_PRIORITY6		:
2062 		case  TX_PKTS_PRIORITY6_LO	:
2063 		case  TX_PKTS_PRIORITY7		:
2064 		case  TX_PKTS_PRIORITY7_LO	:
2065 		case  TX_OCTETS_PRIORITY0	:
2066 		case  TX_OCTETS_PRIORITY0_LO	:
2067 		case  TX_OCTETS_PRIORITY1	:
2068 		case  TX_OCTETS_PRIORITY1_LO	:
2069 		case  TX_OCTETS_PRIORITY2	:
2070 		case  TX_OCTETS_PRIORITY2_LO	:
2071 		case  TX_OCTETS_PRIORITY3	:
2072 		case  TX_OCTETS_PRIORITY3_LO	:
2073 		case  TX_OCTETS_PRIORITY4	:
2074 		case  TX_OCTETS_PRIORITY4_LO	:
2075 		case  TX_OCTETS_PRIORITY5	:
2076 		case  TX_OCTETS_PRIORITY5_LO	:
2077 		case  TX_OCTETS_PRIORITY6	:
2078 		case  TX_OCTETS_PRIORITY6_LO	:
2079 		case  TX_OCTETS_PRIORITY7	:
2080 		case  TX_OCTETS_PRIORITY7_LO	:
2081 		case  RX_DISCARD_PRIORITY0	:
2082 		case  RX_DISCARD_PRIORITY0_LO	:
2083 		case  RX_DISCARD_PRIORITY1	:
2084 		case  RX_DISCARD_PRIORITY1_LO	:
2085 		case  RX_DISCARD_PRIORITY2	:
2086 		case  RX_DISCARD_PRIORITY2_LO	:
2087 		case  RX_DISCARD_PRIORITY3	:
2088 		case  RX_DISCARD_PRIORITY3_LO	:
2089 		case  RX_DISCARD_PRIORITY4	:
2090 		case  RX_DISCARD_PRIORITY4_LO	:
2091 		case  RX_DISCARD_PRIORITY5	:
2092 		case  RX_DISCARD_PRIORITY5_LO	:
2093 		case  RX_DISCARD_PRIORITY6	:
2094 		case  RX_DISCARD_PRIORITY6_LO	:
2095 		case  RX_DISCARD_PRIORITY7	:
2096 		case  RX_DISCARD_PRIORITY7_LO	:
2097 			status = ql_read_xgmac_reg(qlge, i, buf);
2098 			if (status != DDI_SUCCESS)
2099 				goto err;
2100 			break;
2101 
2102 		default:
2103 			break;
2104 		}
2105 	}
2106 err:
2107 	return (status);
2108 }
2109 
2110 /*
2111  * Read MPI related registers
2112  */
2113 static int
2114 ql_get_mpi_regs(qlge_t *qlge, uint32_t *buf, uint32_t offset, uint32_t count)
2115 {
2116 	int i, rtn_val = DDI_FAILURE;
2117 
2118 	for (i = 0; i < count; i++, buf++) {
2119 		if (ql_read_processor_data(qlge, offset + i, buf)
2120 		    != DDI_SUCCESS) {
2121 			goto out;
2122 		}
2123 	}
2124 	rtn_val = DDI_SUCCESS;
2125 out:
2126 	return (rtn_val);
2127 }
2128 
2129 /*
2130  * Read processor "shadow" register "addr" value and save
2131  * in "data".Assume all the locks&semaphore have been acquired
2132  */
2133 static int
2134 ql_get_mpi_shadow_regs(qlge_t *qlge, uint32_t *buf)
2135 {
2136 	uint32_t i;
2137 	int rtn_val = DDI_FAILURE;
2138 
2139 #define	RISC_124	0x0003007c
2140 #define	RISC_127	0x0003007f
2141 #define	SHADOW_OFFSET	0xb0000000
2142 
2143 	for (i = 0; i < MPI_CORE_SH_REGS_CNT; i++, buf++) {
2144 		if (ql_write_processor_data(qlge, RISC_124,
2145 		    (SHADOW_OFFSET | i << 20)) != DDI_SUCCESS)
2146 			goto end;
2147 		if (ql_read_processor_data(qlge, RISC_127, buf) != DDI_SUCCESS)
2148 			goto end;
2149 	}
2150 	rtn_val = DDI_SUCCESS;
2151 
2152 end:
2153 	return (rtn_val);
2154 }
2155 
2156 #define	SYS_CLOCK		0x00
2157 #define	PCI_CLOCK		0x80
2158 #define	FC_CLOCK		0x140
2159 #define	XGM_CLOCK		0x180
2160 #define	ADDRESS_REGISTER_ENABLE	0x00010000
2161 #define	UP			0x00008000
2162 #define	MAX_MUX			0x40
2163 #define	MAX_MODULES		0x1F
2164 
2165 static uint32_t *
2166 ql_get_probe(qlge_t *qlge, uint32_t clock, uint8_t *valid, uint32_t *buf)
2167 {
2168 	uint32_t module, mux_sel, probe, lo_val, hi_val;
2169 
2170 	for (module = 0; module < MAX_MODULES; module ++) {
2171 		if (valid[module]) {
2172 			for (mux_sel = 0; mux_sel < MAX_MUX; mux_sel++) {
2173 				probe = clock | ADDRESS_REGISTER_ENABLE |
2174 				    mux_sel |(module << 9);
2175 
2176 				ql_write_reg(qlge, REG_PRB_MX_ADDR, probe);
2177 				lo_val = ql_read_reg(qlge, REG_PRB_MX_DATA);
2178 				if (mux_sel == 0) {
2179 					*buf = probe;
2180 					buf ++;
2181 				}
2182 				probe |= UP;
2183 				ql_write_reg(qlge, REG_PRB_MX_ADDR, probe);
2184 				hi_val = ql_read_reg(qlge, REG_PRB_MX_DATA);
2185 				*buf = lo_val;
2186 				buf++;
2187 				*buf = hi_val;
2188 				buf++;
2189 			}
2190 		}
2191 	}
2192 	return (buf);
2193 }
2194 
2195 static int
2196 ql_get_probe_dump(qlge_t *qlge, uint32_t *buf)
2197 {
2198 	uint8_t sys_clock_valid_modules[0x20] = {
2199 		1,	/* 0x00 */
2200 		1,	/* 0x01 */
2201 		1,	/* 0x02 */
2202 		0,	/* 0x03 */
2203 		1,	/* 0x04 */
2204 		1,	/* 0x05 */
2205 		1,	/* 0x06 */
2206 		1,	/* 0x07 */
2207 		1,	/* 0x08 */
2208 		1,	/* 0x09 */
2209 		1,	/* 0x0A */
2210 		1,	/* 0x0B */
2211 		1,	/* 0x0C */
2212 		1,	/* 0x0D */
2213 		1,	/* 0x0E */
2214 		0,	/* 0x0F */
2215 		1,	/* 0x10 */
2216 		1,	/* 0x11 */
2217 		1,	/* 0x12 */
2218 		1,	/* 0x13 */
2219 		0,	/* 0x14 */
2220 		0,	/* 0x15 */
2221 		0,	/* 0x16 */
2222 		0,	/* 0x17 */
2223 		0,	/* 0x18 */
2224 		0,	/* 0x19 */
2225 		0,	/* 0x1A */
2226 		0,	/* 0x1B */
2227 		0,	/* 0x1C */
2228 		0,	/* 0x1D */
2229 		0,	/* 0x1E */
2230 		0	/* 0x1F */
2231 	};
2232 
2233 	unsigned char pci_clock_valid_modules[0x20] = {
2234 		1,	/* 0x00 */
2235 		0,	/* 0x01 */
2236 		0,	/* 0x02 */
2237 		0,	/* 0x03 */
2238 		0,	/* 0x04 */
2239 		0,	/* 0x05 */
2240 		1,	/* 0x06 */
2241 		1,	/* 0x07 */
2242 		0,	/* 0x08 */
2243 		0,	/* 0x09 */
2244 		0,	/* 0x0A */
2245 		0,	/* 0x0B */
2246 		0,	/* 0x0C */
2247 		0,	/* 0x0D */
2248 		1,	/* 0x0E */
2249 		0,	/* 0x0F */
2250 		0,	/* 0x10 */
2251 		0,	/* 0x11 */
2252 		0,	/* 0x12 */
2253 		0,	/* 0x13 */
2254 		0,	/* 0x14 */
2255 		0,	/* 0x15 */
2256 		0,	/* 0x16 */
2257 		0,	/* 0x17 */
2258 		0,	/* 0x18 */
2259 		0,	/* 0x19 */
2260 		0,	/* 0x1A */
2261 		0,	/* 0x1B */
2262 		0,	/* 0x1C */
2263 		0,	/* 0x1D */
2264 		0,	/* 0x1E */
2265 		0	/* 0x1F */
2266 	};
2267 
2268 	unsigned char xgm_clock_valid_modules[0x20] = {
2269 		1,	/* 0x00 */
2270 		0,	/* 0x01 */
2271 		0,	/* 0x02 */
2272 		1,	/* 0x03 */
2273 		0,	/* 0x04 */
2274 		0,	/* 0x05 */
2275 		0,	/* 0x06 */
2276 		0,	/* 0x07 */
2277 		1,	/* 0x08 */
2278 		1,	/* 0x09 */
2279 		0,	/* 0x0A */
2280 		0,	/* 0x0B */
2281 		1,	/* 0x0C */
2282 		1,	/* 0x0D */
2283 		1,	/* 0x0E */
2284 		0,	/* 0x0F */
2285 		1,	/* 0x10 */
2286 		1,	/* 0x11 */
2287 		0,	/* 0x12 */
2288 		0,	/* 0x13 */
2289 		0,	/* 0x14 */
2290 		0,	/* 0x15 */
2291 		0,	/* 0x16 */
2292 		0,	/* 0x17 */
2293 		0,	/* 0x18 */
2294 		0,	/* 0x19 */
2295 		0,	/* 0x1A */
2296 		0,	/* 0x1B */
2297 		0,	/* 0x1C */
2298 		0,	/* 0x1D */
2299 		0,	/* 0x1E */
2300 		0	/* 0x1F */
2301 	};
2302 
2303 	unsigned char fc_clock_valid_modules[0x20] = {
2304 		1,	/* 0x00 */
2305 		0,	/* 0x01 */
2306 		0,	/* 0x02 */
2307 		0,	/* 0x03 */
2308 		0,	/* 0x04 */
2309 		0,	/* 0x05 */
2310 		0,	/* 0x06 */
2311 		0,	/* 0x07 */
2312 		0,	/* 0x08 */
2313 		0,	/* 0x09 */
2314 		0,	/* 0x0A */
2315 		0,	/* 0x0B */
2316 		1,	/* 0x0C */
2317 		1,	/* 0x0D */
2318 		0,	/* 0x0E */
2319 		0,	/* 0x0F */
2320 		0,	/* 0x10 */
2321 		0,	/* 0x11 */
2322 		0,	/* 0x12 */
2323 		0,	/* 0x13 */
2324 		0,	/* 0x14 */
2325 		0,	/* 0x15 */
2326 		0,	/* 0x16 */
2327 		0,	/* 0x17 */
2328 		0,	/* 0x18 */
2329 		0,	/* 0x19 */
2330 		0,	/* 0x1A */
2331 		0,	/* 0x1B */
2332 		0,	/* 0x1C */
2333 		0,	/* 0x1D */
2334 		0,	/* 0x1E */
2335 		0	/* 0x1F */
2336 	};
2337 
2338 	/*
2339 	 * First we have to enable the probe mux
2340 	 */
2341 	(void) ql_write_processor_data(qlge, 0x100e, 0x18a20000);
2342 
2343 	buf = ql_get_probe(qlge, SYS_CLOCK, sys_clock_valid_modules, buf);
2344 
2345 	buf = ql_get_probe(qlge, PCI_CLOCK, pci_clock_valid_modules, buf);
2346 
2347 	buf = ql_get_probe(qlge, XGM_CLOCK, xgm_clock_valid_modules, buf);
2348 
2349 	buf = ql_get_probe(qlge, FC_CLOCK, fc_clock_valid_modules, buf);
2350 
2351 	return (0);
2352 
2353 }
2354 
2355 /*
2356  * Dump rounting index registers
2357  */
2358 void
2359 ql_get_routing_index_registers(qlge_t *qlge, uint32_t *buf)
2360 {
2361 	uint32_t type, index, index_max;
2362 	uint32_t result_index;
2363 	uint32_t result_data;
2364 	uint32_t val;
2365 
2366 	for (type = 0; type < 4; type ++) {
2367 		if (type < 2) {
2368 			index_max = 8;
2369 		} else {
2370 			index_max = 16;
2371 		}
2372 		for (index = 0; index < index_max; index ++) {
2373 			val = 0x04000000 | (type << 16) | (index << 8);
2374 			ql_write_reg(qlge, REG_ROUTING_INDEX, val);
2375 			result_index = 0;
2376 			while ((result_index & 0x40000000) == 0) {
2377 				result_index =
2378 				    ql_read_reg(qlge, REG_ROUTING_INDEX);
2379 			}
2380 			result_data = ql_read_reg(qlge, REG_ROUTING_DATA);
2381 			*buf = type;
2382 			buf ++;
2383 			*buf = index;
2384 			buf ++;
2385 			*buf = result_index;
2386 			buf ++;
2387 			*buf = result_data;
2388 			buf ++;
2389 		}
2390 	}
2391 }
2392 
2393 /*
2394  * Dump mac protocol registers
2395  */
2396 void
2397 ql_get_mac_protocol_registers(qlge_t *qlge, uint32_t *buf)
2398 {
2399 #define	RS_AND_ADR	0x06000000
2400 #define	RS_ONLY		0x04000000
2401 #define	NUM_TYPES	10
2402 	uint32_t result_index, result_data;
2403 	uint32_t type;
2404 	uint32_t index;
2405 	uint32_t offset;
2406 	uint32_t val;
2407 	uint32_t initial_val;
2408 	uint32_t max_index;
2409 	uint32_t max_offset;
2410 
2411 	for (type = 0; type < NUM_TYPES; type ++) {
2412 		switch (type) {
2413 
2414 		case 0: /* CAM */
2415 			initial_val = RS_AND_ADR;
2416 			max_index = 512;
2417 			max_offset = 3;
2418 			break;
2419 
2420 		case 1: /* Multicast MAC Address */
2421 			initial_val = RS_ONLY;
2422 			max_index = 32;
2423 			max_offset = 2;
2424 			break;
2425 
2426 		case 2: /* VLAN filter mask */
2427 		case 3: /* MC filter mask */
2428 			initial_val = RS_ONLY;
2429 			max_index = 4096;
2430 			max_offset = 1;
2431 			break;
2432 
2433 		case 4: /* FC MAC addresses */
2434 			initial_val = RS_ONLY;
2435 			max_index = 4;
2436 			max_offset = 2;
2437 			break;
2438 
2439 		case 5: /* Mgmt MAC addresses */
2440 			initial_val = RS_ONLY;
2441 			max_index = 8;
2442 			max_offset = 2;
2443 			break;
2444 
2445 		case 6: /* Mgmt VLAN addresses */
2446 			initial_val = RS_ONLY;
2447 			max_index = 16;
2448 			max_offset = 1;
2449 			break;
2450 
2451 		case 7: /* Mgmt IPv4 address */
2452 			initial_val = RS_ONLY;
2453 			max_index = 4;
2454 			max_offset = 1;
2455 			break;
2456 
2457 		case 8: /* Mgmt IPv6 address */
2458 			initial_val = RS_ONLY;
2459 			max_index = 4;
2460 			max_offset = 4;
2461 			break;
2462 
2463 		case 9: /* Mgmt TCP/UDP Dest port */
2464 			initial_val = RS_ONLY;
2465 			max_index = 4;
2466 			max_offset = 1;
2467 			break;
2468 
2469 		default:
2470 			cmn_err(CE_WARN, "Bad type!!! 0x%08x", type);
2471 			max_index = 0;
2472 			max_offset = 0;
2473 			break;
2474 		}
2475 		for (index = 0; index < max_index; index ++) {
2476 			for (offset = 0; offset < max_offset; offset ++) {
2477 				val = initial_val | (type << 16) | (index << 4)
2478 				    | (offset);
2479 				ql_write_reg(qlge,
2480 				    REG_MAC_PROTOCOL_ADDRESS_INDEX, val);
2481 				result_index = 0;
2482 				while ((result_index & 0x40000000) == 0) {
2483 					result_index = ql_read_reg(qlge,
2484 					    REG_MAC_PROTOCOL_ADDRESS_INDEX);
2485 				}
2486 				result_data =
2487 				    ql_read_reg(qlge, REG_MAC_PROTOCOL_DATA);
2488 				*buf = result_index;
2489 				buf ++;
2490 				*buf = result_data;
2491 				buf ++;
2492 			}
2493 		}
2494 	}
2495 }
2496 
2497 /*
2498  * Dump serdes registers
2499  */
2500 static int
2501 ql_get_serdes_regs(qlge_t *qlge, struct ql_mpi_coredump *mpi_coredump)
2502 {
2503 	uint32_t i, j;
2504 	int status;
2505 
2506 	for (i = 0, j = 0; i <= 0x000000034; i += 4) {
2507 		status = ql_read_serdes_reg(qlge, i,
2508 		    &mpi_coredump->serdes_xaui_an[j++]);
2509 		if (status != DDI_SUCCESS) {
2510 			goto err;
2511 		}
2512 	}
2513 
2514 	for (i = 0x800, j = 0; i <= 0x880; i += 4) {
2515 		status = ql_read_serdes_reg(qlge, i,
2516 		    &mpi_coredump->serdes_xaui_hss_pcs[j++]);
2517 		if (status != DDI_SUCCESS) {
2518 			goto err;
2519 		}
2520 	}
2521 
2522 	for (i = 0x1000, j = 0; i <= 0x1034; i += 4) {
2523 		status = ql_read_serdes_reg(qlge, i,
2524 		    &mpi_coredump->serdes_xfi_an[j++]);
2525 		if (status != DDI_SUCCESS) {
2526 			goto err;
2527 		}
2528 	}
2529 
2530 	for (i = 0x1050, j = 0; i <= 0x107c; i += 4) {
2531 		status = ql_read_serdes_reg(qlge, i,
2532 		    &mpi_coredump->serdes_xfi_train[j++]);
2533 		if (status != DDI_SUCCESS) {
2534 			goto err;
2535 		}
2536 	}
2537 
2538 	for (i = 0x1800, j = 0; i <= 0x1838; i += 4) {
2539 		status = ql_read_serdes_reg(qlge, i,
2540 		    &mpi_coredump->serdes_xfi_hss_pcs[j++]);
2541 		if (status != DDI_SUCCESS) {
2542 			goto err;
2543 		}
2544 	}
2545 
2546 	for (i = 0x1c00; i <= 0x1c1f; i++) {
2547 		status = ql_read_serdes_reg(qlge, i,
2548 		    &mpi_coredump->serdes_xfi_hss_tx[i]);
2549 		if (status != DDI_SUCCESS) {
2550 			goto err;
2551 		}
2552 	}
2553 
2554 	for (i = 0x1c40; i <= 0x1c5f; i++) {
2555 		status = ql_read_serdes_reg(qlge, i,
2556 		    &mpi_coredump->serdes_xfi_hss_rx[i]);
2557 		if (status != DDI_SUCCESS) {
2558 			goto err;
2559 		}
2560 	}
2561 
2562 	for (i = 0x1e00; i <= 0x1e1f; i++) {
2563 		status = ql_read_serdes_reg(qlge, i,
2564 		    &mpi_coredump->serdes_xfi_hss_pll[i]);
2565 		if (status != DDI_SUCCESS) {
2566 			goto err;
2567 		}
2568 	}
2569 
2570 err:
2571 	if (status != DDI_SUCCESS) {
2572 		cmn_err(CE_WARN, "Serdes register 0x%x access error", i);
2573 	}
2574 
2575 	return (status);
2576 }
2577 
2578 /*
2579  * Dump ets registers
2580  */
2581 static int
2582 ql_get_ets_regs(qlge_t *qlge, uint32_t *buf)
2583 {
2584 	int i;
2585 
2586 	/*
2587 	 * First read out the NIC ETS
2588 	 */
2589 	for (i = 0; i < 8; i++, buf++) {
2590 		ql_write_reg(qlge, REG_NIC_ENHANCED_TX_SCHEDULE,
2591 		    i << 29 | 0x08000000);
2592 		/* wait for reg to come ready */
2593 		/* get the data */
2594 		*buf = ql_read_reg(qlge, REG_NIC_ENHANCED_TX_SCHEDULE);
2595 	}
2596 	/*
2597 	 * Now read out the CNA ETS
2598 	 */
2599 	for (i = 0; i < 2; i ++, buf ++) {
2600 		ql_write_reg(qlge, REG_CNA_ENHANCED_TX_SCHEDULE,
2601 		    i << 29 | 0x08000000);
2602 		/* wait for reg to come ready */
2603 		*buf = ql_read_reg(qlge, REG_CNA_ENHANCED_TX_SCHEDULE);
2604 	}
2605 
2606 	return (0);
2607 }
2608 
2609 /*
2610  * Core dump in binary format
2611  */
2612 int
2613 ql_8xxx_binary_core_dump(qlge_t *qlge, ql_mpi_coredump_t *mpi_coredump)
2614 {
2615 	int		rtn_val = DDI_FAILURE;
2616 	uint64_t	timestamp, phy_addr;
2617 	uint32_t	addr;
2618 	int		i;
2619 
2620 	if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) {
2621 		return (rtn_val);
2622 	}
2623 
2624 	/* pause the risc */
2625 	if (ql_pause_mpi_risc(qlge) != DDI_SUCCESS) {
2626 		cmn_err(CE_WARN,
2627 		    "%s(%d) Wait for RISC paused timeout.",
2628 		    __func__, qlge->instance);
2629 		goto out;
2630 	}
2631 
2632 	/* 0:make core dump header */
2633 	bzero(&(mpi_coredump->mpi_global_header),
2634 	    sizeof (mpi_coredump_global_header_t));
2635 	mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
2636 	(void) strcpy(mpi_coredump->mpi_global_header.id_string,
2637 	    "MPI Coredump");
2638 	timestamp = ddi_get_time();
2639 	timestamp *= 1000000;
2640 	mpi_coredump->mpi_global_header.time_lo = LSW(timestamp);
2641 	mpi_coredump->mpi_global_header.time_hi = MSW(timestamp);
2642 	mpi_coredump->mpi_global_header.total_image_size =
2643 	    (uint32_t)(sizeof (ql_mpi_coredump_t));
2644 	mpi_coredump->mpi_global_header.global_header_size =
2645 	    sizeof (mpi_coredump_global_header_t);
2646 	(void) strcpy(mpi_coredump->mpi_global_header.driver_info,
2647 	    "driver version is "VERSIONSTR);
2648 
2649 	/* 1:MPI Core Registers */
2650 	ql_build_coredump_seg_header(&mpi_coredump->core_regs_seg_hdr,
2651 	    CORE_SEG_NUM, sizeof (mpi_coredump->core_regs_seg_hdr) +
2652 	    sizeof (mpi_coredump->mpi_core_regs) +
2653 	    sizeof (mpi_coredump->mpi_core_sh_regs),
2654 	    (uint8_t *)"Core Registers");
2655 
2656 	/* first, read 127 core registers */
2657 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->mpi_core_regs[0],
2658 	    MPI_CORE_REGS_ADDR, MPI_CORE_REGS_CNT);
2659 	/* read the next 16 shadow registers */
2660 	(void) ql_get_mpi_shadow_regs(qlge,
2661 	    &mpi_coredump->mpi_core_sh_regs[0]);
2662 
2663 	/* 2:MPI Test Logic Registers */
2664 	ql_build_coredump_seg_header(&mpi_coredump->test_logic_regs_seg_hdr,
2665 	    TEST_LOGIC_SEG_NUM,
2666 	    sizeof (mpi_coredump_segment_header_t) +
2667 	    sizeof (mpi_coredump->test_logic_regs),
2668 	    (uint8_t *)"Test Logic Regs");
2669 
2670 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->test_logic_regs[0],
2671 	    TEST_REGS_ADDR, TEST_REGS_CNT);
2672 
2673 	/* 3:RMII Registers */
2674 	ql_build_coredump_seg_header(&mpi_coredump->rmii_regs_seg_hdr,
2675 	    RMII_SEG_NUM,
2676 	    sizeof (mpi_coredump_segment_header_t) +
2677 	    sizeof (mpi_coredump->rmii_regs),
2678 	    (uint8_t *)"RMII Registers");
2679 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->rmii_regs[0],
2680 	    RMII_REGS_ADDR, RMII_REGS_CNT);
2681 
2682 	/* 4:FCMAC1 Registers */
2683 	ql_build_coredump_seg_header(&mpi_coredump->fcmac1_regs_seg_hdr,
2684 	    FCMAC1_SEG_NUM,
2685 	    sizeof (mpi_coredump_segment_header_t) +
2686 	    sizeof (mpi_coredump->fcmac1_regs),
2687 	    (uint8_t *)"FCMAC1 Registers");
2688 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->fcmac1_regs[0],
2689 	    FCMAC1_REGS_ADDR, FCMAC_REGS_CNT);
2690 
2691 	/* 5:FCMAC2 Registers */
2692 	ql_build_coredump_seg_header(&mpi_coredump->fcmac2_regs_seg_hdr,
2693 	    FCMAC2_SEG_NUM,
2694 	    sizeof (mpi_coredump_segment_header_t) +
2695 	    sizeof (mpi_coredump->fcmac2_regs),
2696 	    (uint8_t *)"FCMAC2 Registers");
2697 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->fcmac2_regs[0],
2698 	    FCMAC2_REGS_ADDR, FCMAC_REGS_CNT);
2699 
2700 	/* 6:FC1 Mailbox Registers */
2701 	ql_build_coredump_seg_header(&mpi_coredump->fc1_mbx_regs_seg_hdr,
2702 	    FC1_MBOX_SEG_NUM,
2703 	    sizeof (mpi_coredump_segment_header_t) +
2704 	    sizeof (mpi_coredump->fc1_mbx_regs),
2705 	    (uint8_t *)"FC1 MBox Regs");
2706 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->fc1_mbx_regs[0],
2707 	    FC1_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
2708 
2709 	/* 7:IDE Registers */
2710 	ql_build_coredump_seg_header(&mpi_coredump->ide_regs_seg_hdr,
2711 	    IDE_SEG_NUM,
2712 	    sizeof (mpi_coredump_segment_header_t) +
2713 	    sizeof (mpi_coredump->ide_regs),
2714 	    (uint8_t *)"IDE Registers");
2715 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->ide_regs[0],
2716 	    IDE_REGS_ADDR, IDE_REGS_CNT);
2717 
2718 	/* 8:Host1 Mailbox Registers */
2719 	ql_build_coredump_seg_header(&mpi_coredump->nic1_mbx_regs_seg_hdr,
2720 	    NIC1_MBOX_SEG_NUM,
2721 	    sizeof (mpi_coredump_segment_header_t) +
2722 	    sizeof (mpi_coredump->nic1_mbx_regs),
2723 	    (uint8_t *)"NIC1 MBox Regs");
2724 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->nic1_mbx_regs[0],
2725 	    NIC1_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
2726 
2727 	/* 9:SMBus Registers */
2728 	ql_build_coredump_seg_header(&mpi_coredump->smbus_regs_seg_hdr,
2729 	    SMBUS_SEG_NUM,
2730 	    sizeof (mpi_coredump_segment_header_t) +
2731 	    sizeof (mpi_coredump->smbus_regs),
2732 	    (uint8_t *)"SMBus Registers");
2733 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->smbus_regs[0],
2734 	    SMBUS_REGS_ADDR, SMBUS_REGS_CNT);
2735 
2736 	/* 10:FC2 Mailbox Registers */
2737 	ql_build_coredump_seg_header(&mpi_coredump->fc2_mbx_regs_seg_hdr,
2738 	    FC2_MBOX_SEG_NUM,
2739 	    sizeof (mpi_coredump_segment_header_t) +
2740 	    sizeof (mpi_coredump->fc2_mbx_regs),
2741 	    (uint8_t *)"FC2 MBox Regs");
2742 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->fc2_mbx_regs[0],
2743 	    FC2_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
2744 
2745 	/* 11:Host2 Mailbox Registers */
2746 	ql_build_coredump_seg_header(&mpi_coredump->nic2_mbx_regs_seg_hdr,
2747 	    NIC2_MBOX_SEG_NUM,
2748 	    sizeof (mpi_coredump_segment_header_t) +
2749 	    sizeof (mpi_coredump->nic2_mbx_regs),
2750 	    (uint8_t *)"NIC2 MBox Regs");
2751 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->nic2_mbx_regs[0],
2752 	    NIC2_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
2753 
2754 	/* 12:i2C Registers */
2755 	ql_build_coredump_seg_header(&mpi_coredump->i2c_regs_seg_hdr,
2756 	    I2C_SEG_NUM,
2757 	    sizeof (mpi_coredump_segment_header_t) +
2758 	    sizeof (mpi_coredump->i2c_regs),
2759 	    (uint8_t *)"I2C Registers");
2760 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->i2c_regs[0],
2761 	    I2C_REGS_ADDR, I2C_REGS_CNT);
2762 
2763 	/* 13:MEMC Registers */
2764 	ql_build_coredump_seg_header(&mpi_coredump->memc_regs_seg_hdr,
2765 	    MEMC_SEG_NUM,
2766 	    sizeof (mpi_coredump_segment_header_t) +
2767 	    sizeof (mpi_coredump->memc_regs),
2768 	    (uint8_t *)"MEMC Registers");
2769 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->memc_regs[0],
2770 	    MEMC_REGS_ADDR, MEMC_REGS_CNT);
2771 
2772 	/* 14:PBus Registers */
2773 	ql_build_coredump_seg_header(&mpi_coredump->pbus_regs_seg_hdr,
2774 	    PBUS_SEG_NUM,
2775 	    sizeof (mpi_coredump_segment_header_t) +
2776 	    sizeof (mpi_coredump->pbus_regs),
2777 	    (uint8_t *)"PBUS Registers");
2778 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->pbus_regs[0],
2779 	    PBUS_REGS_ADDR, PBUS_REGS_CNT);
2780 
2781 	/* 15:MDE Registers */
2782 	ql_build_coredump_seg_header(&mpi_coredump->mde_regs_seg_hdr,
2783 	    MDE_SEG_NUM,
2784 	    sizeof (mpi_coredump_segment_header_t) +
2785 	    sizeof (mpi_coredump->mde_regs),
2786 	    (uint8_t *)"MDE Registers");
2787 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->mde_regs[0],
2788 	    MDE_REGS_ADDR, MDE_REGS_CNT);
2789 
2790 	ql_build_coredump_seg_header(&mpi_coredump->xaui_an_hdr,
2791 	    XAUI_AN_SEG_NUM,
2792 	    sizeof (mpi_coredump_segment_header_t) +
2793 	    sizeof (mpi_coredump->serdes_xaui_an),
2794 	    (uint8_t *)"XAUI AN Registers");
2795 
2796 	ql_build_coredump_seg_header(&mpi_coredump->xaui_hss_pcs_hdr,
2797 	    XAUI_HSS_PCS_SEG_NUM,
2798 	    sizeof (mpi_coredump_segment_header_t) +
2799 	    sizeof (mpi_coredump->serdes_xaui_hss_pcs),
2800 	    (uint8_t *)"XAUI HSS PCS Registers");
2801 
2802 	ql_build_coredump_seg_header(&mpi_coredump->xfi_an_hdr,
2803 	    XFI_AN_SEG_NUM,
2804 	    sizeof (mpi_coredump_segment_header_t) +
2805 	    sizeof (mpi_coredump->serdes_xfi_an),
2806 	    (uint8_t *)"XFI AN Registers");
2807 
2808 	ql_build_coredump_seg_header(&mpi_coredump->xfi_train_hdr,
2809 	    XFI_TRAIN_SEG_NUM,
2810 	    sizeof (mpi_coredump_segment_header_t) +
2811 	    sizeof (mpi_coredump->serdes_xfi_train),
2812 	    (uint8_t *)"XFI TRAIN Registers");
2813 
2814 	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_pcs_hdr,
2815 	    XFI_HSS_PCS_SEG_NUM,
2816 	    sizeof (mpi_coredump_segment_header_t) +
2817 	    sizeof (mpi_coredump->serdes_xfi_hss_pcs),
2818 	    (uint8_t *)"XFI HSS PCS Registers");
2819 
2820 	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_tx_hdr,
2821 	    XFI_HSS_TX_SEG_NUM,
2822 	    sizeof (mpi_coredump_segment_header_t) +
2823 	    sizeof (mpi_coredump->serdes_xfi_hss_tx),
2824 	    (uint8_t *)"XFI HSS TX Registers");
2825 
2826 	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_rx_hdr,
2827 	    XFI_HSS_RX_SEG_NUM,
2828 	    sizeof (mpi_coredump_segment_header_t) +
2829 	    sizeof (mpi_coredump->serdes_xfi_hss_rx),
2830 	    (uint8_t *)"XFI HSS RX Registers");
2831 
2832 	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_pll_hdr,
2833 	    XFI_HSS_PLL_SEG_NUM,
2834 	    sizeof (mpi_coredump_segment_header_t) +
2835 	    sizeof (mpi_coredump->serdes_xfi_hss_pll),
2836 	    (uint8_t *)"XFI HSS PLL Registers");
2837 
2838 	(void) ql_get_serdes_regs(qlge, mpi_coredump);
2839 
2840 	/* 16:NIC Ctrl Registers Port1 */
2841 	ql_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
2842 	    NIC1_CONTROL_SEG_NUM,
2843 	    sizeof (mpi_coredump_segment_header_t) +
2844 	    sizeof (mpi_coredump->nic_regs),
2845 	    (uint8_t *)"NIC Registers");
2846 	i = 0;
2847 	for (addr = 0; addr <= 0xFC; i++) {
2848 		mpi_coredump->nic_regs[i] = ql_read_reg(qlge, addr);
2849 		addr += 4;
2850 	}
2851 
2852 	ql_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr,
2853 	    INTR_STATES_SEG_NUM,
2854 	    sizeof (mpi_coredump_segment_header_t) +
2855 	    sizeof (mpi_coredump->intr_states),
2856 	    (uint8_t *)"INTR States");
2857 	ql_get_intr_states(qlge, &mpi_coredump->intr_states[0]);
2858 
2859 	ql_build_coredump_seg_header(&mpi_coredump->xgmac_seg_hdr,
2860 	    NIC1_XGMAC_SEG_NUM,
2861 	    sizeof (mpi_coredump_segment_header_t) +
2862 	    sizeof (mpi_coredump->xgmac),
2863 	    (uint8_t *)"NIC XGMac Registers");
2864 	(void) ql_get_xgmac_regs(qlge, &mpi_coredump->xgmac[0]);
2865 
2866 	ql_build_coredump_seg_header(&mpi_coredump->probe_dump_seg_hdr,
2867 	    PROBE_DUMP_SEG_NUM,
2868 	    sizeof (mpi_coredump_segment_header_t) +
2869 	    sizeof (mpi_coredump->probe_dump),
2870 	    (uint8_t *)"Probe Dump");
2871 	(void) ql_get_probe_dump(qlge, &mpi_coredump->probe_dump[0]);
2872 
2873 	ql_build_coredump_seg_header(&mpi_coredump->routing_reg_seg_hdr,
2874 	    ROUTING_INDEX_SEG_NUM,
2875 	    sizeof (mpi_coredump_segment_header_t) +
2876 	    sizeof (mpi_coredump->routing_regs),
2877 	    (uint8_t *)"Routing Regs");
2878 
2879 	ql_get_routing_index_registers(qlge, &mpi_coredump->routing_regs[0]);
2880 
2881 	ql_build_coredump_seg_header(&mpi_coredump->mac_prot_reg_seg_hdr,
2882 	    MAC_PROTOCOL_SEG_NUM,
2883 	    sizeof (mpi_coredump_segment_header_t) +
2884 	    sizeof (mpi_coredump->mac_prot_regs),
2885 	    (uint8_t *)"MAC Prot Regs");
2886 
2887 	ql_get_mac_protocol_registers(qlge, &mpi_coredump->mac_prot_regs[0]);
2888 
2889 	ql_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr,
2890 	    ETS_SEG_NUM,
2891 	    sizeof (mpi_coredump_segment_header_t) +
2892 	    sizeof (mpi_coredump->ets),
2893 	    (uint8_t *)"ETS Registers");
2894 
2895 	(void) ql_get_ets_regs(qlge, &mpi_coredump->ets[0]);
2896 
2897 	/* clear the pause */
2898 	if (ql_unpause_mpi_risc(qlge) != DDI_SUCCESS) {
2899 		cmn_err(CE_WARN,
2900 		    "Failed RISC unpause.");
2901 		goto out;
2902 	}
2903 
2904 	/* Reset the MPI Processor */
2905 	if (ql_reset_mpi_risc(qlge) != DDI_SUCCESS) {
2906 		goto out;
2907 	}
2908 
2909 	/* 22:WCS MPI Ram ?? */
2910 	ql_build_coredump_seg_header(&mpi_coredump->code_ram_seg_hdr,
2911 	    WCS_RAM_SEG_NUM,
2912 	    sizeof (mpi_coredump_segment_header_t) +
2913 	    sizeof (mpi_coredump->code_ram),
2914 	    (uint8_t *)"WCS RAM");
2915 	phy_addr = qlge->ioctl_buf_dma_attr.dma_addr;
2916 	if (ql_read_risc_ram(qlge, CODE_RAM_ADDR, phy_addr, CODE_RAM_CNT)
2917 	    == DDI_SUCCESS) {
2918 		(void) ddi_dma_sync(qlge->ioctl_buf_dma_attr.dma_handle, 0,
2919 		    sizeof (mpi_coredump->code_ram), DDI_DMA_SYNC_FORKERNEL);
2920 		bcopy(qlge->ioctl_buf_dma_attr.vaddr,
2921 		    mpi_coredump->code_ram,
2922 		    sizeof (mpi_coredump->code_ram));
2923 	} else {
2924 		mutex_exit(&qlge->mbx_mutex);
2925 		goto out;
2926 	}
2927 
2928 	/* 23:MEMC Ram ?? */
2929 	ql_build_coredump_seg_header(&mpi_coredump->memc_ram_seg_hdr,
2930 	    MEMC_RAM_SEG_NUM,
2931 	    sizeof (mpi_coredump_segment_header_t) +
2932 	    sizeof (mpi_coredump->memc_ram),
2933 	    (uint8_t *)"MEMC RAM");
2934 	phy_addr = qlge->ioctl_buf_dma_attr.dma_addr;
2935 	if (ql_read_risc_ram(qlge, MEMC_RAM_ADDR, phy_addr, MEMC_RAM_CNT)
2936 	    == DDI_SUCCESS) {
2937 		(void) ddi_dma_sync(qlge->ioctl_buf_dma_attr.dma_handle, 0,
2938 		    sizeof (mpi_coredump->memc_ram), DDI_DMA_SYNC_FORKERNEL);
2939 		bcopy(qlge->ioctl_buf_dma_attr.vaddr, mpi_coredump->memc_ram,
2940 		    sizeof (mpi_coredump->memc_ram));
2941 	} else {
2942 		mutex_exit(&qlge->mbx_mutex);
2943 		goto out;
2944 	}
2945 	/*
2946 	 * 24. Restart MPI
2947 	 */
2948 	if (ql_write_processor_data(qlge, 0x1010, 1) != DDI_SUCCESS) {
2949 		cmn_err(CE_WARN, "MPI restart failure.");
2950 	}
2951 
2952 	rtn_val = DDI_SUCCESS;
2953 out:
2954 	ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK);
2955 	return (rtn_val);
2956 }
2957