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