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 			(void) ql_get_firmware_version(qlge,
1068 			    &prop_ptr->mpi_version);
1069 			(void) ql_get_fw_state(qlge, &prop_ptr->fw_state);
1070 			(void) qlge_get_link_status(qlge,
1071 			    &prop_ptr->link_status);
1072 			break;
1073 
1074 		case QLA_LIST_ADAPTER_INFO:
1075 			/* count must be exactly same */
1076 			if (iocp->ioc_count != sizeof (ql_adapter_info_t)) {
1077 				return (IOC_INVAL);
1078 			}
1079 			if (ql_get_pci_bus_info(qlge,
1080 			    &(adapter_info_ptr->pci_binding)) != DDI_SUCCESS) {
1081 				return (IOC_INVAL);
1082 			}
1083 			adapter_info_ptr->vendor_id =
1084 			    qlge->pci_cfg.vendor_id;
1085 			adapter_info_ptr->sub_vendor_id =
1086 			    qlge->pci_cfg.sub_vendor_id;
1087 			adapter_info_ptr->device_id =
1088 			    qlge->pci_cfg.device_id;
1089 			adapter_info_ptr->sub_device_id =
1090 			    qlge->pci_cfg.sub_device_id;
1091 
1092 			bcopy(qlge->unicst_addr[0].addr.ether_addr_octet,
1093 			    &(adapter_info_ptr->cur_addr), ETHERADDRL);
1094 			break;
1095 
1096 		case QLA_SHOW_REGION:
1097 			len = (uint32_t)iocp->ioc_count;
1098 			bdesc = (caddr_t)dmp->b_rptr;
1099 			if (CFG_IST(qlge, CFG_CHIP_8100))
1100 				(void) sprintf(bdesc, "ISP 8100 available "
1101 				    "regions %s", ISP_8100_REGION);
1102 			break;
1103 
1104 		case QLA_CONTINUE_COPY_OUT:
1105 			if (qlge->ioctl_buf_ptr == NULL)
1106 				return (IOC_INVAL);
1107 			len = (uint32_t)iocp->ioc_count;
1108 			bp = qlge->ioctl_buf_ptr;
1109 			bp += qlge->ioctl_transferred_bytes;
1110 			remaining_bytes =
1111 			    qlge->ioctl_total_length -
1112 			    qlge->ioctl_transferred_bytes;
1113 			/* how many data bytes sent this time */
1114 			payload_len =
1115 			    (uint16_t)min(IOCTL_MAX_DATA_LEN, remaining_bytes);
1116 			/* create packet header */
1117 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1118 			pheader->version = 0;
1119 			pheader->total_length = qlge->ioctl_total_length;
1120 			pheader->expected_trans_times =
1121 			    qlge->expected_trans_times;
1122 			pheader->payload_length = payload_len;
1123 			/* create packet payload */
1124 			bdesc = (caddr_t)dmp->b_rptr;
1125 			bdesc += IOCTL_HEADER_LEN;
1126 			bcopy(bp, bdesc, pheader->payload_length);
1127 			qlge->ioctl_transferred_bytes +=
1128 			    pheader->payload_length;
1129 			QL_PRINT(DBG_GLD, ("QLA_CONTINUE_COPY_OUT, %d bytes"
1130 			    " exported \n", payload_len));
1131 			if (qlge->ioctl_transferred_bytes >=
1132 			    qlge->ioctl_total_length) {
1133 				QL_PRINT(DBG_GLD, ("all data out,clean up \n"));
1134 				kmem_free(qlge->ioctl_buf_ptr,
1135 				    qlge->ioctl_buf_lenth);
1136 				qlge->ioctl_buf_ptr = NULL;
1137 				qlge->ioctl_buf_lenth = 0;
1138 			}
1139 			iocp->ioc_count = len;
1140 			break;
1141 
1142 		case QLA_CONTINUE_COPY_IN:
1143 			if (qlge->ioctl_buf_ptr == NULL)
1144 				return (IOC_INVAL);
1145 			len = (uint32_t)iocp->ioc_count;
1146 			bdesc = qlge->ioctl_buf_ptr;
1147 			bdesc += qlge->ioctl_transferred_bytes;
1148 			remaining_bytes = qlge->ioctl_total_length -
1149 			    qlge->ioctl_transferred_bytes;
1150 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1151 			payload_len = pheader->payload_length;
1152 			/* create packet header */
1153 			pheader->version = 0;
1154 			pheader->total_length = qlge->ioctl_total_length;
1155 			pheader->expected_trans_times =
1156 			    qlge->expected_trans_times;
1157 			/* get packet payload */
1158 			bp = (caddr_t)dmp->b_rptr;
1159 			bp += IOCTL_HEADER_LEN;
1160 			bcopy(bp, bdesc, pheader->payload_length);
1161 			qlge->ioctl_transferred_bytes +=
1162 			    pheader->payload_length;
1163 			QL_PRINT(DBG_GLD, ("QLA_CONTINUE_COPY_IN, %d bytes "
1164 			    "received \n", payload_len));
1165 			if (qlge->ioctl_transferred_bytes >=
1166 			    qlge->ioctl_total_length) {
1167 				region = pheader->option[0];
1168 				(void) ql_get_flash_table_region_info(qlge,
1169 				    region, &addr, &size);
1170 				QL_PRINT(DBG_GLD, ("write data to region 0x%x,"
1171 				    " addr 0x%x, max size %d bytes\n",
1172 				    region, addr, size));
1173 				(void) qlge_load_flash(qlge,
1174 				    (uint8_t *)qlge->ioctl_buf_ptr,
1175 				    qlge->ioctl_transferred_bytes /* size */,
1176 				    addr);
1177 				QL_PRINT(DBG_GLD, ("all %d data written, do "
1178 				    "clean up \n",
1179 				    qlge->ioctl_transferred_bytes));
1180 				kmem_free(qlge->ioctl_buf_ptr,
1181 				    qlge->ioctl_buf_lenth);
1182 				qlge->ioctl_buf_ptr = NULL;
1183 				qlge->ioctl_buf_lenth = 0;
1184 			}
1185 			iocp->ioc_count = len;
1186 			break;
1187 
1188 		case QLA_READ_CONTRL_REGISTERS:
1189 			if (qlge->ioctl_buf_ptr == NULL) {
1190 				qlge->ioctl_buf_lenth =
1191 				    IOCTL_MAX_BUF_SIZE; /* 512k */
1192 				qlge->ioctl_buf_ptr =
1193 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1194 				    KM_SLEEP);
1195 				if (qlge->ioctl_buf_ptr == NULL) {
1196 					cmn_err(CE_WARN, "%s(%d): Unable to "
1197 					    "allocate ioctl buffer",
1198 					    __func__, qlge->instance);
1199 					return (IOC_INVAL);
1200 				}
1201 			}
1202 			len = read_ctrl_reg_set(qlge, qlge->ioctl_buf_ptr);
1203 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1204 			/* build initial ioctl packet header */
1205 			build_init_pkt_header(qlge, pheader, len);
1206 			iocp->ioc_count = sizeof (*pheader);
1207 			break;
1208 
1209 		case QLA_SUPPORTED_DUMP_TYPES: /* show available regions */
1210 			len = (uint32_t)iocp->ioc_count;
1211 			bdesc = (caddr_t)dmp->b_rptr;
1212 			if (CFG_IST(qlge, CFG_CHIP_8100))
1213 				(void) sprintf(bdesc, "ISP 8100 supported dump"
1214 				    " types: %s", ISP_8100_AVAILABLE_DUMPS);
1215 			break;
1216 
1217 		case QLA_GET_BINARY_CORE_DUMP:
1218 			len = (uint32_t)iocp->ioc_count;
1219 			requested_dump = *((uint16_t *)(void *)dmp->b_rptr);
1220 			rval = ql_binary_core_dump(qlge, requested_dump, &len);
1221 			if (rval == DDI_SUCCESS) {
1222 				pheader =
1223 				    (ioctl_header_info_t *)(void *)dmp->b_rptr;
1224 				/* build initial ioctl packet header */
1225 				build_init_pkt_header(qlge, pheader, len);
1226 				iocp->ioc_count = sizeof (*pheader);
1227 			} else {
1228 				cmn_err(CE_WARN, "ql_binary_core_dump error");
1229 				return (IOC_INVAL);
1230 			}
1231 			break;
1232 
1233 		case QLA_TRIGGER_SYS_ERROR_EVENT:
1234 			(void) ql_trigger_system_error_event(qlge);
1235 			break;
1236 
1237 		case QLA_READ_VPD:
1238 			if (qlge->ioctl_buf_ptr == NULL) {
1239 				qlge->ioctl_buf_lenth =
1240 				    IOCTL_MAX_BUF_SIZE; /* 512k */
1241 				qlge->ioctl_buf_ptr =
1242 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1243 				    KM_SLEEP);
1244 				if (qlge->ioctl_buf_ptr == NULL) {
1245 					cmn_err(CE_WARN, "%s(%d): Unable to "
1246 					    "allocate ioctl buffer",
1247 					    __func__, qlge->instance);
1248 					return (IOC_INVAL);
1249 				}
1250 			}
1251 			len = (uint32_t)iocp->ioc_count;
1252 			QL_PRINT(DBG_GLD, (" 0x%x user buffer available \n",
1253 			    len));
1254 			(void) ql_flash_vpd(qlge,
1255 			    (uint8_t *)qlge->ioctl_buf_ptr);
1256 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1257 			/* build initial ioctl packet header */
1258 			build_init_pkt_header(qlge, pheader,
1259 			    ISP_8100_VPD0_SIZE);
1260 			iocp->ioc_count = sizeof (*pheader);
1261 			break;
1262 
1263 		case QLA_MANUAL_READ_FLASH:
1264 			if (qlge->ioctl_buf_ptr == NULL) {
1265 				qlge->ioctl_buf_lenth =
1266 				    IOCTL_MAX_BUF_SIZE; /* 512k */
1267 				qlge->ioctl_buf_ptr =
1268 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1269 				    KM_SLEEP);
1270 				if (qlge->ioctl_buf_ptr == NULL) {
1271 					cmn_err(CE_WARN, "%s(%d): Unable to "
1272 					    "allocate ioctl buffer",
1273 					    __func__, qlge->instance);
1274 					return (IOC_INVAL);
1275 				}
1276 			}
1277 			len = (uint32_t)iocp->ioc_count;
1278 			rval = qlge_dump_fcode(qlge,
1279 			    (uint8_t *)qlge->ioctl_buf_ptr,
1280 			    flash_io_info_ptr->size,
1281 			    flash_io_info_ptr->addr);
1282 			if (rval != DDI_SUCCESS) {
1283 				return (IOC_INVAL);
1284 			}
1285 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1286 			/* build initial ioctl packet header */
1287 			build_init_pkt_header(qlge, pheader,
1288 			    flash_io_info_ptr->size);
1289 			iocp->ioc_count = sizeof (*pheader);
1290 			break;
1291 
1292 		case QLA_READ_FLASH:
1293 			if (qlge->ioctl_buf_ptr == NULL) {
1294 				qlge->ioctl_buf_lenth = IOCTL_MAX_BUF_SIZE;
1295 				qlge->ioctl_buf_ptr =
1296 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1297 				    KM_SLEEP);
1298 				if (qlge->ioctl_buf_ptr == NULL) {
1299 					cmn_err(CE_WARN, "%s(%d): Unable to"
1300 					    "allocate ioctl buffer",
1301 					    __func__, qlge->instance);
1302 					return (IOC_INVAL);
1303 				}
1304 			}
1305 			len = (uint32_t)iocp->ioc_count;
1306 			region = *pvalue;
1307 			if (ql_get_flash_table_region_info(qlge, region, &addr,
1308 			    &size) != DDI_SUCCESS)
1309 				return (IOC_INVAL);
1310 			rval = qlge_dump_fcode(qlge,
1311 			    (uint8_t *)qlge->ioctl_buf_ptr,
1312 			    size, addr);
1313 			if (rval != DDI_SUCCESS) {
1314 				return (IOC_INVAL);
1315 			}
1316 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1317 			/* build initial ioctl packet header */
1318 			build_init_pkt_header(qlge, pheader, size);
1319 			iocp->ioc_count = sizeof (*pheader);
1320 			break;
1321 
1322 		case QLA_WRITE_FLASH:
1323 			len = (uint32_t)iocp->ioc_count;
1324 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1325 			region = pheader->option[0];
1326 			qlge->ioctl_buf_lenth = pheader->total_length;
1327 			qlge->ioctl_total_length = pheader->total_length;
1328 			qlge->expected_trans_times =
1329 			    pheader->expected_trans_times;
1330 			qlge->ioctl_transferred_bytes = 0;
1331 			if (qlge->ioctl_buf_ptr == NULL) {
1332 				qlge->ioctl_buf_ptr =
1333 				    kmem_zalloc(qlge->ioctl_buf_lenth,
1334 				    KM_SLEEP);
1335 				if (qlge->ioctl_buf_ptr == NULL) {
1336 					cmn_err(CE_WARN, "%s(%d): Unable to "
1337 					    "allocate ioctl buffer",
1338 					    __func__, qlge->instance);
1339 					return (IOC_INVAL);
1340 				}
1341 			}
1342 			QL_PRINT(DBG_GLD, ("QLA_WRITE_FLASH write to region "
1343 			    "%x, total buffer size 0x%x bytes\n",
1344 			    region, qlge->ioctl_buf_lenth));
1345 			iocp->ioc_count = sizeof (*pheader);
1346 			break;
1347 
1348 		case QLA_READ_FW_IMAGE:
1349 			if (qlge->ioctl_buf_ptr != NULL) {
1350 				kmem_free(qlge->ioctl_buf_ptr,
1351 				    qlge->ioctl_buf_lenth);
1352 			}
1353 			qlge->ioctl_buf_lenth = IOCTL_MAX_BUF_SIZE * 4;
1354 			qlge->ioctl_buf_ptr = kmem_zalloc(qlge->ioctl_buf_lenth,
1355 			    KM_SLEEP);
1356 			if (qlge->ioctl_buf_ptr == NULL) {
1357 				cmn_err(CE_WARN, "%s(%d): Unable to "
1358 				    "allocate ioctl buffer",
1359 				    __func__, qlge->instance);
1360 				return (IOC_INVAL);
1361 			}
1362 			len = (uint32_t)iocp->ioc_count;
1363 			iltds_ptr = (ql_iltds_description_header_t *)
1364 			    (void *)qlge->ioctl_buf_ptr;
1365 			iltds_ptr->iltds_table_header.signature =
1366 			    FLASH_ILTDS_SIGNATURE;
1367 			iltds_ptr->iltds_table_header.table_version = 1;
1368 			iltds_ptr->iltds_table_header.length =
1369 			    ILTDS_DESCRIPTION_HEADERS_LEN;
1370 			iltds_ptr->iltds_table_header.number_entries =
1371 			    IMAGE_TABLE_IMAGE_DEFAULT_ENTRIES +
1372 			    1 /* timestamp */;
1373 			iltds_ptr->iltds_table_header.reserved = 0;
1374 			iltds_ptr->iltds_table_header.version = 1;
1375 			/* where is the flash data saved */
1376 			bdesc = qlge->ioctl_buf_ptr +
1377 			    ILTDS_DESCRIPTION_HEADERS_LEN;
1378 			offset = iltds_ptr->iltds_table_header.length;
1379 			for (i = 0; i < IMAGE_TABLE_IMAGE_DEFAULT_ENTRIES;
1380 			    i++) {
1381 				region = iltds_image_entry_regions[i];
1382 				if (ql_get_flash_table_region_info(qlge,
1383 				    region, &addr, &size) != DDI_SUCCESS)
1384 					return (IOC_INVAL);
1385 				QL_PRINT(DBG_GLD, ("region %x addr 0x%x, 0x%x "
1386 				    "bytes\n", region, addr, size));
1387 				/* Dump one image entry */
1388 				rval = qlge_dump_fcode(qlge, (uint8_t *)bdesc,
1389 				    size, addr);
1390 				if (rval != DDI_SUCCESS) {
1391 					return (IOC_INVAL);
1392 				}
1393 				bdesc += size;
1394 				iltds_ptr->img_entry[i].region_type =
1395 				    (uint16_t)region;
1396 				iltds_ptr->img_entry[i].region_version_len = 0;
1397 				iltds_ptr->img_entry[i].region_version[0] = 0;
1398 				iltds_ptr->img_entry[i].region_version[1] = 0;
1399 				iltds_ptr->img_entry[i].region_version[2] = 0;
1400 				iltds_ptr->img_entry[i].offset_lo = LSW(offset);
1401 				iltds_ptr->img_entry[i].offset_hi = MSW(offset);
1402 				iltds_ptr->img_entry[i].size_lo = LSW(size);
1403 				iltds_ptr->img_entry[i].size_hi = MSW(size);
1404 				iltds_ptr->img_entry[i].swap_mode = 0;
1405 				iltds_ptr->img_entry[i].card_type = 0;
1406 				QL_PRINT(DBG_GLD, ("image offset %x size %x "
1407 				    "bytes\n", offset, size));
1408 				QL_PRINT(DBG_GLD, ("offset %x lsw %x msw %x"
1409 				    " \n", offset, LSW(offset), MSW(offset)));
1410 				offset += size;
1411 			}
1412 			/* Last entry */
1413 			iltds_ptr->time_stamp.region_type =
1414 			    FLT_REGION_TIME_STAMP;
1415 			iltds_ptr->time_stamp.region_version_len = 0;
1416 			iltds_ptr->time_stamp.region_version[0] = 0;
1417 			iltds_ptr->time_stamp.region_version[1] = 0;
1418 			iltds_ptr->time_stamp.region_version[2] = 0;
1419 			iltds_ptr->time_stamp.year = 0x09;
1420 			iltds_ptr->time_stamp.month = 0x01;
1421 			iltds_ptr->time_stamp.day = 0x20;
1422 			iltds_ptr->time_stamp.hour = 0x14;
1423 			iltds_ptr->time_stamp.min = 0x20;
1424 			iltds_ptr->time_stamp.sec = 0x50;
1425 
1426 			pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr;
1427 			/* build initial ioctl packet header */
1428 			build_init_pkt_header(qlge, pheader, offset);
1429 			iocp->ioc_count = sizeof (*pheader);
1430 			break;
1431 
1432 		case QLA_WRITE_FW_IMAGE_HEADERS:
1433 			len = (uint32_t)iocp->ioc_count;
1434 			if (len == 0)
1435 				return (IOC_INVAL);
1436 			ql_iltds_header_ptr =
1437 			    (ql_iltds_header_t *)(void *)dmp->b_rptr;
1438 			if (len != ql_iltds_header_ptr->length) {
1439 				cmn_err(CE_WARN, "QLA_WRITE_FW_IMAGE_HEADERS "
1440 				    "data length error!"
1441 				    " %x bytes expected, %x received",
1442 				    ql_iltds_header_ptr->length, len);
1443 				return (IOC_INVAL);
1444 			}
1445 			QL_PRINT(DBG_GLD, ("Fw Image header len 0x%x bytes, "
1446 			    "0x%x entries\n",
1447 			    len, ql_iltds_header_ptr->number_entries));
1448 			ql_dump_buf("all copy in data:\n",
1449 			    (uint8_t *)dmp->b_rptr, 8, len);
1450 			mp->b_cont = NULL;
1451 			break;
1452 
1453 		case QLA_SOFT_RESET:
1454 			iocp->ioc_count = 0;
1455 			ql_wake_asic_reset_soft_intr(qlge);
1456 			QL_PRINT(DBG_GLD, ("QLA_SOFT_RESET started \n"));
1457 			break;
1458 
1459 		default:
1460 			return (IOC_INVAL);
1461 	}
1462 
1463 	return (IOC_REPLY);
1464 }
1465 
1466 /*
1467  * Loopback ioctl code
1468  */
1469 static lb_property_t loopmodes[] = {
1470 	{ normal,	"normal",	QLGE_LOOP_NONE			},
1471 	{ internal,	"parallel",	QLGE_LOOP_INTERNAL_PARALLEL	},
1472 	{ internal,	"serial",	QLGE_LOOP_INTERNAL_SERIAL	},
1473 };
1474 
1475 /*
1476  * Set Loopback mode
1477  */
1478 static enum ioc_reply
1479 qlge_set_loop_mode(qlge_t *qlge, uint32_t mode)
1480 {
1481 	/*
1482 	 * If the mode is same as current mode ...
1483 	 */
1484 	if (mode == qlge->loop_back_mode)
1485 		return (IOC_ACK);
1486 
1487 	/*
1488 	 * Validate the requested mode
1489 	 */
1490 	switch (mode) {
1491 	default:
1492 		return (IOC_INVAL);
1493 
1494 	case QLGE_LOOP_NONE:
1495 	case QLGE_LOOP_INTERNAL_PARALLEL:
1496 	case QLGE_LOOP_INTERNAL_SERIAL:
1497 		break;
1498 	}
1499 
1500 	/*
1501 	 * All OK; reprogram for the new mode ...
1502 	 */
1503 	qlge->loop_back_mode = mode;
1504 	mutex_enter(&qlge->mbx_mutex);
1505 	(void) ql_set_port_cfg(qlge);
1506 	mutex_exit(&qlge->mbx_mutex);
1507 	return (IOC_REPLY);
1508 }
1509 /*
1510  * Loopback ioctl
1511  */
1512 /* ARGSUSED */
1513 enum ioc_reply
1514 ql_loop_ioctl(qlge_t *qlge, queue_t *wq, mblk_t *mp, struct iocblk *iocp)
1515 {
1516 	lb_info_sz_t *lbsp;
1517 	lb_property_t *lbpp;
1518 	uint32_t *lbmp;
1519 	int cmd;
1520 
1521 	_NOTE(ARGUNUSED(wq))
1522 	/*
1523 	 * Validate format of ioctl
1524 	 */
1525 	if (mp->b_cont == NULL)
1526 		return (IOC_INVAL);
1527 
1528 	cmd = iocp->ioc_cmd;
1529 	switch (cmd) {
1530 	default:
1531 		/* NOTREACHED */
1532 		QL_PRINT(DBG_GLD, ("%s(%d) invalid cmd 0x%x\n",
1533 		    __func__, qlge->instance, cmd));
1534 		return (IOC_INVAL);
1535 
1536 	case LB_GET_INFO_SIZE:
1537 		if (iocp->ioc_count != sizeof (lb_info_sz_t))
1538 			return (IOC_INVAL);
1539 		lbsp = (void *)mp->b_cont->b_rptr;
1540 		*lbsp = sizeof (loopmodes);
1541 		return (IOC_REPLY);
1542 
1543 	case LB_GET_INFO:
1544 		if (iocp->ioc_count != sizeof (loopmodes))
1545 			return (IOC_INVAL);
1546 		lbpp = (void *)mp->b_cont->b_rptr;
1547 		bcopy(loopmodes, lbpp, sizeof (loopmodes));
1548 		return (IOC_REPLY);
1549 
1550 	case LB_GET_MODE:
1551 		if (iocp->ioc_count != sizeof (uint32_t))
1552 			return (IOC_INVAL);
1553 		lbmp = (void *)mp->b_cont->b_rptr;
1554 		*lbmp = qlge->loop_back_mode;
1555 		return (IOC_REPLY);
1556 
1557 	case LB_SET_MODE:
1558 		if (iocp->ioc_count != sizeof (uint32_t))
1559 			return (IOC_INVAL);
1560 		lbmp = (void *)mp->b_cont->b_rptr;
1561 		return (qlge_set_loop_mode(qlge, *lbmp));
1562 	}
1563 }
1564 
1565 /*
1566  * Dumps binary data from firmware.
1567  */
1568 static int
1569 ql_8xxx_binary_core_dump_with_header(qlge_t *qlge, caddr_t buf,
1570     uint32_t *len_ptr)
1571 {
1572 	caddr_t bp = buf;
1573 	int rval = DDI_SUCCESS;
1574 	ql_dump_image_header_t *ql_dump_image_header_ptr =
1575 	    (ql_dump_image_header_t *)(void *)bp;
1576 
1577 	ql_dump_image_header_ptr->signature = DUMP_IMAGE_HEADER_SIGNATURE;
1578 	ql_dump_image_header_ptr->version = 1;
1579 	ql_dump_image_header_ptr->header_length = 16;
1580 	ql_dump_image_header_ptr->data_type = DUMP_TYPE_CORE_DUMP;
1581 	/* point to real dump data area */
1582 	bp += sizeof (ql_dump_image_header_t);
1583 	bcopy(&qlge->ql_mpi_coredump, bp, sizeof (ql_mpi_coredump_t));
1584 	ql_dump_image_header_ptr->data_length = sizeof (ql_mpi_coredump_t);
1585 	/* total length: header + data image */
1586 	ql_dump_image_header_ptr->checksum = (uint16_t)
1587 	    (ql_dump_image_header_ptr->signature
1588 	    +ql_dump_image_header_ptr->version
1589 	    +ql_dump_image_header_ptr->header_length
1590 	    +ql_dump_image_header_ptr->data_type
1591 	    +ql_dump_image_header_ptr->data_length);
1592 
1593 	*len_ptr = ql_dump_image_header_ptr->header_length +
1594 	    ql_dump_image_header_ptr->data_length;
1595 	QL_PRINT(DBG_GLD, ("%s done,core dump lenth %d bytes\n",
1596 	    __func__, *len_ptr));
1597 	return (rval);
1598 }
1599 
1600 /*
1601  * Dump registers value in binary format
1602  */
1603 static int
1604 ql_8xxx_binary_register_dump_with_header(qlge_t *qlge, caddr_t buf,
1605     uint32_t *len_ptr)
1606 {
1607 	caddr_t bp = buf;
1608 	int i;
1609 	uint32_t *data_ptr;
1610 	int rval = DDI_SUCCESS;
1611 
1612 	ql_dump_image_header_t *ql_dump_image_header_ptr =
1613 	    (ql_dump_image_header_t *)(void *)bp;
1614 	ql_dump_image_header_ptr->signature =
1615 	    DUMP_IMAGE_HEADER_SIGNATURE;
1616 	ql_dump_image_header_ptr->version = 1;
1617 	ql_dump_image_header_ptr->header_length = 16;
1618 	ql_dump_image_header_ptr->data_type = DUMP_TYPE_REGISTER_DUMP;
1619 	/* point to real dump data area */
1620 	bp += sizeof (ql_dump_image_header_t);
1621 	data_ptr = (uint32_t *)(void *)bp;
1622 
1623 	for (i = 0; i <= 0xfc; i += 4) {
1624 		*data_ptr = ql_read_reg(qlge, i);
1625 		data_ptr++;
1626 	}
1627 	ql_dump_image_header_ptr->data_length = 0x100; /* 0 ~ 0xFF */
1628 	/* total length: header + data image */
1629 	ql_dump_image_header_ptr->checksum = (uint16_t)
1630 	    (ql_dump_image_header_ptr->signature
1631 	    +ql_dump_image_header_ptr->version
1632 	    +ql_dump_image_header_ptr->header_length
1633 	    +ql_dump_image_header_ptr->data_type
1634 	    +ql_dump_image_header_ptr->data_length);
1635 
1636 	*len_ptr = ql_dump_image_header_ptr->header_length +
1637 	    ql_dump_image_header_ptr->data_length;
1638 
1639 	QL_PRINT(DBG_GLD, ("%s done, dump lenth %x bytes\n", __func__,
1640 	    *len_ptr));
1641 
1642 	return (rval);
1643 }
1644 
1645 /*
1646  * Core dump in binary format
1647  */
1648 static int
1649 ql_binary_core_dump(qlge_t *qlge, uint32_t requested_dumps, uint32_t *len_ptr)
1650 {
1651 	int rval = DDI_FAILURE;
1652 	uint32_t length, size = 0;
1653 	uint64_t timestamp;
1654 	caddr_t bp;
1655 	ql_dump_header_t *ql_dump_header_ptr;
1656 	ql_dump_footer_t *ql_dump_footer_ptr;
1657 
1658 	if (qlge->ioctl_buf_ptr == NULL) {
1659 		qlge->ioctl_buf_lenth = IOCTL_MAX_BUF_SIZE; /* 512k */
1660 		qlge->ioctl_buf_ptr =
1661 		    kmem_zalloc(qlge->ioctl_buf_lenth, KM_SLEEP);
1662 		if (qlge->ioctl_buf_ptr == NULL) {
1663 			cmn_err(CE_WARN,
1664 			    "%s(%d): Unable to allocate ioctl buffer",
1665 			    __func__, qlge->instance);
1666 			goto out;
1667 		}
1668 	}
1669 
1670 	/* description info header */
1671 	ql_dump_header_ptr = (ql_dump_header_t *)(void *)qlge->ioctl_buf_ptr;
1672 	/* add QTSB signature */
1673 	ql_dump_header_ptr->signature = DUMP_DESCRIPTION_HEADER_SIGNATURE;
1674 	ql_dump_header_ptr->version = 1;
1675 	ql_dump_header_ptr->length = 16;
1676 	ql_dump_header_ptr->reserved = 0;
1677 	/* get dump creation timestamp */
1678 	timestamp = ddi_get_time();
1679 	timestamp *= 1000000;
1680 	ql_dump_header_ptr->time_stamp_lo = LSW(timestamp);
1681 	ql_dump_header_ptr->time_stamp_hi = MSW(timestamp);
1682 	/* point to first image header area */
1683 	length = sizeof (ql_dump_header_t);
1684 	bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1685 
1686 	if (CFG_IST(qlge, CFG_CHIP_8100)) {
1687 		/* if dumping all */
1688 		if ((requested_dumps & DUMP_REQUEST_ALL) != 0) {
1689 			ql_dump_header_ptr->num_dumps = 2;
1690 			(void) ql_8xxx_binary_core_dump_with_header(qlge,
1691 			    bp, &size);
1692 			length += size;
1693 			bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1694 			(void) ql_8xxx_binary_register_dump_with_header(qlge,
1695 			    bp, &size);
1696 			length += size;
1697 			bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1698 		} else if ((requested_dumps & DUMP_REQUEST_CORE) != 0) {
1699 			ql_dump_header_ptr->num_dumps = 1;
1700 			(void) ql_8xxx_binary_core_dump_with_header(qlge,
1701 			    bp, &size);
1702 			length += size;
1703 			bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1704 		} else if ((requested_dumps & DUMP_REQUEST_REGISTER) != 0) {
1705 			ql_dump_header_ptr->num_dumps = 1;
1706 			(void) ql_8xxx_binary_register_dump_with_header(qlge,
1707 			    bp, &size);
1708 			length += size;
1709 			bp = (caddr_t)qlge->ioctl_buf_ptr + length;
1710 		} else {
1711 			cmn_err(CE_WARN, "%s(%d): not supported dump type %d",
1712 			    __func__, qlge->instance, requested_dumps);
1713 			goto out;
1714 		}
1715 	}
1716 
1717 	ql_dump_footer_ptr = (ql_dump_footer_t *)(void *)bp;
1718 	ql_dump_footer_ptr->signature = DUMP_DESCRIPTION_FOOTER_SIGNATURE;
1719 	ql_dump_footer_ptr->version = 1;
1720 	ql_dump_footer_ptr->length = 16;
1721 	ql_dump_footer_ptr->reserved = 0;
1722 	timestamp = ddi_get_time();
1723 	timestamp *= 1000000;
1724 	ql_dump_footer_ptr->time_stamp_lo = LSW(timestamp);
1725 	ql_dump_footer_ptr->time_stamp_hi = MSW(timestamp);
1726 	length += ql_dump_footer_ptr->length;
1727 	rval = DDI_SUCCESS;
1728 	*len_ptr = length;
1729 	QL_PRINT(DBG_MBX, ("%s(%d): exiting,total %x bytes\n",
1730 	    __func__, qlge->instance, length));
1731 out:
1732 	return (rval);
1733 }
1734 
1735 /*
1736  * build core dump segment header
1737  */
1738 static void
1739 ql_build_coredump_seg_header(mpi_coredump_segment_header_t *seg_hdr,
1740     uint32_t seg_number, uint32_t seg_size, uint8_t *desc)
1741 {
1742 	(void) memset(seg_hdr, 0, sizeof (mpi_coredump_segment_header_t));
1743 	seg_hdr->cookie = MPI_COREDUMP_COOKIE;
1744 	seg_hdr->seg_number = seg_number;
1745 	seg_hdr->seg_size = seg_size;
1746 	(void) memcpy(seg_hdr->description, desc,
1747 	    (sizeof (seg_hdr->description))-1);
1748 }
1749 
1750 /*
1751  * Unpause MPI risc
1752  */
1753 static int
1754 ql_unpause_mpi_risc(qlge_t *qlge)
1755 {
1756 	uint32_t tmp;
1757 
1758 	/* Un-pause the RISC */
1759 	tmp = ql_read_reg(qlge, REG_HOST_CMD_STATUS);
1760 	if ((tmp & CSR_RP) == 0)
1761 		return (DDI_FAILURE);
1762 
1763 	ql_write_reg(qlge, REG_HOST_CMD_STATUS, CSR_CMD_CLR_PAUSE);
1764 	return (DDI_SUCCESS);
1765 }
1766 
1767 /*
1768  * Pause MPI risc
1769  */
1770 static int
1771 ql_pause_mpi_risc(qlge_t *qlge)
1772 {
1773 	uint32_t tmp;
1774 	int count = 10;
1775 
1776 	/* Pause the RISC */
1777 	ql_write_reg(qlge, REG_HOST_CMD_STATUS, CSR_CMD_SET_PAUSE);
1778 	do {
1779 		tmp = ql_read_reg(qlge, REG_HOST_CMD_STATUS);
1780 		if ((tmp & CSR_RP) != 0)
1781 			break;
1782 		qlge_delay(10);
1783 		count--;
1784 	} while (count);
1785 	return ((count == 0) ? DDI_FAILURE : DDI_SUCCESS);
1786 }
1787 
1788 /*
1789  * Get Interrupt Status registers value
1790  */
1791 static void
1792 ql_get_intr_states(qlge_t *qlge, uint32_t *buf)
1793 {
1794 	int i;
1795 
1796 	for (i = 0; i < MAX_RX_RINGS; i++, buf++) {
1797 		/* read the interrupt enable register for each rx ring */
1798 		ql_write_reg(qlge, REG_INTERRUPT_ENABLE, 0x037f0300 + i);
1799 		*buf = ql_read_reg(qlge, REG_INTERRUPT_ENABLE);
1800 	}
1801 }
1802 
1803 /*
1804  * Read serdes register
1805  */
1806 static int
1807 ql_read_serdes_reg(qlge_t *qlge, uint32_t reg, uint32_t *data)
1808 {
1809 	int rtn_val = DDI_FAILURE;
1810 
1811 	/* wait for reg to come ready */
1812 	if (ql_wait_reg_bit(qlge, REG_XG_SERDES_ADDR,
1813 	    XG_SERDES_ADDR_RDY, BIT_SET, 0) != DDI_SUCCESS)
1814 		goto exit;
1815 	/* set up for reg read */
1816 	ql_write_reg(qlge, REG_XG_SERDES_ADDR, reg | PROC_ADDR_R);
1817 	/* wait for reg to come ready */
1818 	if (ql_wait_reg_bit(qlge, REG_XG_SERDES_ADDR,
1819 	    XG_SERDES_ADDR_RDY, BIT_SET, 0) != DDI_SUCCESS)
1820 		goto exit;
1821 	/* get the data */
1822 	*data = ql_read_reg(qlge, REG_XG_SERDES_DATA);
1823 	rtn_val = DDI_SUCCESS;
1824 exit:
1825 	return (rtn_val);
1826 }
1827 
1828 /*
1829  * Read XGMAC register
1830  */
1831 static int
1832 ql_get_xgmac_regs(qlge_t *qlge, uint32_t *buf)
1833 {
1834 	int status;
1835 	int i;
1836 
1837 	for (i = 0; i < XGMAC_REGISTER_END; i += 4, buf ++) {
1838 		switch (i) {
1839 		case  PAUSE_SRC_LO		:
1840 		case  PAUSE_SRC_HI		:
1841 		case  GLOBAL_CFG		:
1842 		case  TX_CFG			:
1843 		case  RX_CFG			:
1844 		case  FLOW_CTL			:
1845 		case  PAUSE_OPCODE		:
1846 		case  PAUSE_TIMER		:
1847 		case  PAUSE_FRM_DEST_LO		:
1848 		case  PAUSE_FRM_DEST_HI		:
1849 		case  MAC_TX_PARAMS		:
1850 		case  MAC_RX_PARAMS		:
1851 		case  MAC_SYS_INT		:
1852 		case  MAC_SYS_INT_MASK		:
1853 		case  MAC_MGMT_INT		:
1854 		case  MAC_MGMT_IN_MASK		:
1855 		case  EXT_ARB_MODE		:
1856 		case  TX_PKTS		:
1857 		case  TX_PKTS_LO		:
1858 		case  TX_BYTES			:
1859 		case  TX_BYTES_LO		:
1860 		case  TX_MCAST_PKTS		:
1861 		case  TX_MCAST_PKTS_LO		:
1862 		case  TX_BCAST_PKTS		:
1863 		case  TX_BCAST_PKTS_LO		:
1864 		case  TX_UCAST_PKTS		:
1865 		case  TX_UCAST_PKTS_LO		:
1866 		case  TX_CTL_PKTS		:
1867 		case  TX_CTL_PKTS_LO		:
1868 		case  TX_PAUSE_PKTS		:
1869 		case  TX_PAUSE_PKTS_LO		:
1870 		case  TX_64_PKT			:
1871 		case  TX_64_PKT_LO		:
1872 		case  TX_65_TO_127_PKT		:
1873 		case  TX_65_TO_127_PKT_LO	:
1874 		case  TX_128_TO_255_PKT		:
1875 		case  TX_128_TO_255_PKT_LO	:
1876 		case  TX_256_511_PKT		:
1877 		case  TX_256_511_PKT_LO		:
1878 		case  TX_512_TO_1023_PKT	:
1879 		case  TX_512_TO_1023_PKT_LO	:
1880 		case  TX_1024_TO_1518_PKT	:
1881 		case  TX_1024_TO_1518_PKT_LO	:
1882 		case  TX_1519_TO_MAX_PKT	:
1883 		case  TX_1519_TO_MAX_PKT_LO	:
1884 		case  TX_UNDERSIZE_PKT		:
1885 		case  TX_UNDERSIZE_PKT_LO	:
1886 		case  TX_OVERSIZE_PKT		:
1887 		case  TX_OVERSIZE_PKT_LO	:
1888 		case  RX_HALF_FULL_DET		:
1889 		case  TX_HALF_FULL_DET_LO	:
1890 		case  RX_OVERFLOW_DET		:
1891 		case  TX_OVERFLOW_DET_LO	:
1892 		case  RX_HALF_FULL_MASK		:
1893 		case  TX_HALF_FULL_MASK_LO	:
1894 		case  RX_OVERFLOW_MASK		:
1895 		case  TX_OVERFLOW_MASK_LO	:
1896 		case  STAT_CNT_CTL		:
1897 		case  AUX_RX_HALF_FULL_DET	:
1898 		case  AUX_TX_HALF_FULL_DET	:
1899 		case  AUX_RX_OVERFLOW_DET	:
1900 		case  AUX_TX_OVERFLOW_DET	:
1901 		case  AUX_RX_HALF_FULL_MASK	:
1902 		case  AUX_TX_HALF_FULL_MASK	:
1903 		case  AUX_RX_OVERFLOW_MASK	:
1904 		case  AUX_TX_OVERFLOW_MASK	:
1905 		case  RX_BYTES			:
1906 		case  RX_BYTES_LO		:
1907 		case  RX_BYTES_OK		:
1908 		case  RX_BYTES_OK_LO		:
1909 		case  RX_PKTS			:
1910 		case  RX_PKTS_LO		:
1911 		case  RX_PKTS_OK		:
1912 		case  RX_PKTS_OK_LO		:
1913 		case  RX_BCAST_PKTS		:
1914 		case  RX_BCAST_PKTS_LO		:
1915 		case  RX_MCAST_PKTS		:
1916 		case  RX_MCAST_PKTS_LO		:
1917 		case  RX_UCAST_PKTS		:
1918 		case  RX_UCAST_PKTS_LO		:
1919 		case  RX_UNDERSIZE_PKTS		:
1920 		case  RX_UNDERSIZE_PKTS_LO	:
1921 		case  RX_OVERSIZE_PKTS		:
1922 		case  RX_OVERSIZE_PKTS_LO	:
1923 		case  RX_JABBER_PKTS		:
1924 		case  RX_JABBER_PKTS_LO		:
1925 		case  RX_UNDERSIZE_FCERR_PKTS	:
1926 		case  RX_UNDERSIZE_FCERR_PKTS_LO :
1927 		case  RX_DROP_EVENTS		:
1928 		case  RX_DROP_EVENTS_LO		:
1929 		case  RX_FCERR_PKTS		:
1930 		case  RX_FCERR_PKTS_LO		:
1931 		case  RX_ALIGN_ERR		:
1932 		case  RX_ALIGN_ERR_LO		:
1933 		case  RX_SYMBOL_ERR		:
1934 		case  RX_SYMBOL_ERR_LO		:
1935 		case  RX_MAC_ERR		:
1936 		case  RX_MAC_ERR_LO		:
1937 		case  RX_CTL_PKTS		:
1938 		case  RX_CTL_PKTS_LO		:
1939 		case  RX_PAUSE_PKTS		:
1940 		case  RX_PAUSE_PKTS_LO		:
1941 		case  RX_64_PKTS		:
1942 		case  RX_64_PKTS_LO		:
1943 		case  RX_65_TO_127_PKTS		:
1944 		case  RX_65_TO_127_PKTS_LO	:
1945 		case  RX_128_255_PKTS		:
1946 		case  RX_128_255_PKTS_LO	:
1947 		case  RX_256_511_PKTS		:
1948 		case  RX_256_511_PKTS_LO	:
1949 		case  RX_512_TO_1023_PKTS	:
1950 		case  RX_512_TO_1023_PKTS_LO	:
1951 		case  RX_1024_TO_1518_PKTS	:
1952 		case  RX_1024_TO_1518_PKTS_LO	:
1953 		case  RX_1519_TO_MAX_PKTS	:
1954 		case  RX_1519_TO_MAX_PKTS_LO	:
1955 		case  RX_LEN_ERR_PKTS		:
1956 		case  RX_LEN_ERR_PKTS_LO	:
1957 		case  MDIO_TX_DATA		:
1958 		case  MDIO_RX_DATA		:
1959 		case  MDIO_CMD			:
1960 		case  MDIO_PHY_ADDR		:
1961 		case  MDIO_PORT			:
1962 		case  MDIO_STATUS		:
1963 		case  TX_CBFC_PAUSE_FRAMES0	:
1964 		case  TX_CBFC_PAUSE_FRAMES0_LO	:
1965 		case  TX_CBFC_PAUSE_FRAMES1	:
1966 		case  TX_CBFC_PAUSE_FRAMES1_LO	:
1967 		case  TX_CBFC_PAUSE_FRAMES2	:
1968 		case  TX_CBFC_PAUSE_FRAMES2_LO	:
1969 		case  TX_CBFC_PAUSE_FRAMES3	:
1970 		case  TX_CBFC_PAUSE_FRAMES3_LO	:
1971 		case  TX_CBFC_PAUSE_FRAMES4	:
1972 		case  TX_CBFC_PAUSE_FRAMES4_LO	:
1973 		case  TX_CBFC_PAUSE_FRAMES5	:
1974 		case  TX_CBFC_PAUSE_FRAMES5_LO	:
1975 		case  TX_CBFC_PAUSE_FRAMES6	:
1976 		case  TX_CBFC_PAUSE_FRAMES6_LO	:
1977 		case  TX_CBFC_PAUSE_FRAMES7	:
1978 		case  TX_CBFC_PAUSE_FRAMES7_LO	:
1979 		case  TX_FCOE_PKTS		:
1980 		case  TX_FCOE_PKTS_LO		:
1981 		case  TX_MGMT_PKTS		:
1982 		case  TX_MGMT_PKTS_LO		:
1983 		case  RX_CBFC_PAUSE_FRAMES0	:
1984 		case  RX_CBFC_PAUSE_FRAMES0_LO	:
1985 		case  RX_CBFC_PAUSE_FRAMES1	:
1986 		case  RX_CBFC_PAUSE_FRAMES1_LO	:
1987 		case  RX_CBFC_PAUSE_FRAMES2	:
1988 		case  RX_CBFC_PAUSE_FRAMES2_LO	:
1989 		case  RX_CBFC_PAUSE_FRAMES3	:
1990 		case  RX_CBFC_PAUSE_FRAMES3_LO	:
1991 		case  RX_CBFC_PAUSE_FRAMES4	:
1992 		case  RX_CBFC_PAUSE_FRAMES4_LO	:
1993 		case  RX_CBFC_PAUSE_FRAMES5	:
1994 		case  RX_CBFC_PAUSE_FRAMES5_LO	:
1995 		case  RX_CBFC_PAUSE_FRAMES6	:
1996 		case  RX_CBFC_PAUSE_FRAMES6_LO	:
1997 		case  RX_CBFC_PAUSE_FRAMES7	:
1998 		case  RX_CBFC_PAUSE_FRAMES7_LO	:
1999 		case  RX_FCOE_PKTS		:
2000 		case  RX_FCOE_PKTS_LO		:
2001 		case  RX_MGMT_PKTS		:
2002 		case  RX_MGMT_PKTS_LO		:
2003 		case  RX_NIC_FIFO_DROP		:
2004 		case  RX_NIC_FIFO_DROP_LO	:
2005 		case  RX_FCOE_FIFO_DROP		:
2006 		case  RX_FCOE_FIFO_DROP_LO	:
2007 		case  RX_MGMT_FIFO_DROP		:
2008 		case  RX_MGMT_FIFO_DROP_LO	:
2009 		case  RX_PKTS_PRIORITY0		:
2010 		case  RX_PKTS_PRIORITY0_LO	:
2011 		case  RX_PKTS_PRIORITY1		:
2012 		case  RX_PKTS_PRIORITY1_LO	:
2013 		case  RX_PKTS_PRIORITY2		:
2014 		case  RX_PKTS_PRIORITY2_LO	:
2015 		case  RX_PKTS_PRIORITY3		:
2016 		case  RX_PKTS_PRIORITY3_LO	:
2017 		case  RX_PKTS_PRIORITY4		:
2018 		case  RX_PKTS_PRIORITY4_LO	:
2019 		case  RX_PKTS_PRIORITY5		:
2020 		case  RX_PKTS_PRIORITY5_LO	:
2021 		case  RX_PKTS_PRIORITY6		:
2022 		case  RX_PKTS_PRIORITY6_LO	:
2023 		case  RX_PKTS_PRIORITY7		:
2024 		case  RX_PKTS_PRIORITY7_LO	:
2025 		case  RX_OCTETS_PRIORITY0	:
2026 		case  RX_OCTETS_PRIORITY0_LO	:
2027 		case  RX_OCTETS_PRIORITY1	:
2028 		case  RX_OCTETS_PRIORITY1_LO	:
2029 		case  RX_OCTETS_PRIORITY2	:
2030 		case  RX_OCTETS_PRIORITY2_LO	:
2031 		case  RX_OCTETS_PRIORITY3	:
2032 		case  RX_OCTETS_PRIORITY3_LO	:
2033 		case  RX_OCTETS_PRIORITY4	:
2034 		case  RX_OCTETS_PRIORITY4_LO	:
2035 		case  RX_OCTETS_PRIORITY5	:
2036 		case  RX_OCTETS_PRIORITY5_LO	:
2037 		case  RX_OCTETS_PRIORITY6	:
2038 		case  RX_OCTETS_PRIORITY6_LO	:
2039 		case  RX_OCTETS_PRIORITY7	:
2040 		case  RX_OCTETS_PRIORITY7_LO	:
2041 		case  TX_PKTS_PRIORITY0		:
2042 		case  TX_PKTS_PRIORITY0_LO	:
2043 		case  TX_PKTS_PRIORITY1		:
2044 		case  TX_PKTS_PRIORITY1_LO	:
2045 		case  TX_PKTS_PRIORITY2		:
2046 		case  TX_PKTS_PRIORITY2_LO	:
2047 		case  TX_PKTS_PRIORITY3		:
2048 		case  TX_PKTS_PRIORITY3_LO	:
2049 		case  TX_PKTS_PRIORITY4		:
2050 		case  TX_PKTS_PRIORITY4_LO	:
2051 		case  TX_PKTS_PRIORITY5		:
2052 		case  TX_PKTS_PRIORITY5_LO	:
2053 		case  TX_PKTS_PRIORITY6		:
2054 		case  TX_PKTS_PRIORITY6_LO	:
2055 		case  TX_PKTS_PRIORITY7		:
2056 		case  TX_PKTS_PRIORITY7_LO	:
2057 		case  TX_OCTETS_PRIORITY0	:
2058 		case  TX_OCTETS_PRIORITY0_LO	:
2059 		case  TX_OCTETS_PRIORITY1	:
2060 		case  TX_OCTETS_PRIORITY1_LO	:
2061 		case  TX_OCTETS_PRIORITY2	:
2062 		case  TX_OCTETS_PRIORITY2_LO	:
2063 		case  TX_OCTETS_PRIORITY3	:
2064 		case  TX_OCTETS_PRIORITY3_LO	:
2065 		case  TX_OCTETS_PRIORITY4	:
2066 		case  TX_OCTETS_PRIORITY4_LO	:
2067 		case  TX_OCTETS_PRIORITY5	:
2068 		case  TX_OCTETS_PRIORITY5_LO	:
2069 		case  TX_OCTETS_PRIORITY6	:
2070 		case  TX_OCTETS_PRIORITY6_LO	:
2071 		case  TX_OCTETS_PRIORITY7	:
2072 		case  TX_OCTETS_PRIORITY7_LO	:
2073 		case  RX_DISCARD_PRIORITY0	:
2074 		case  RX_DISCARD_PRIORITY0_LO	:
2075 		case  RX_DISCARD_PRIORITY1	:
2076 		case  RX_DISCARD_PRIORITY1_LO	:
2077 		case  RX_DISCARD_PRIORITY2	:
2078 		case  RX_DISCARD_PRIORITY2_LO	:
2079 		case  RX_DISCARD_PRIORITY3	:
2080 		case  RX_DISCARD_PRIORITY3_LO	:
2081 		case  RX_DISCARD_PRIORITY4	:
2082 		case  RX_DISCARD_PRIORITY4_LO	:
2083 		case  RX_DISCARD_PRIORITY5	:
2084 		case  RX_DISCARD_PRIORITY5_LO	:
2085 		case  RX_DISCARD_PRIORITY6	:
2086 		case  RX_DISCARD_PRIORITY6_LO	:
2087 		case  RX_DISCARD_PRIORITY7	:
2088 		case  RX_DISCARD_PRIORITY7_LO	:
2089 			status = ql_read_xgmac_reg(qlge, i, buf);
2090 			if (status != DDI_SUCCESS)
2091 				goto err;
2092 			break;
2093 
2094 		default:
2095 			break;
2096 		}
2097 	}
2098 err:
2099 	return (status);
2100 }
2101 
2102 /*
2103  * Read MPI related registers
2104  */
2105 static int
2106 ql_get_mpi_regs(qlge_t *qlge, uint32_t *buf, uint32_t offset, uint32_t count)
2107 {
2108 	int i, rtn_val = DDI_FAILURE;
2109 
2110 	for (i = 0; i < count; i++, buf++) {
2111 		if (ql_read_processor_data(qlge, offset + i, buf)
2112 		    != DDI_SUCCESS) {
2113 			goto out;
2114 		}
2115 	}
2116 	rtn_val = DDI_SUCCESS;
2117 out:
2118 	return (rtn_val);
2119 }
2120 
2121 /*
2122  * Read processor "shadow" register "addr" value and save
2123  * in "data".Assume all the locks&semaphore have been acquired
2124  */
2125 static int
2126 ql_get_mpi_shadow_regs(qlge_t *qlge, uint32_t *buf)
2127 {
2128 	uint32_t i;
2129 	int rtn_val = DDI_FAILURE;
2130 
2131 #define	RISC_124	0x0003007c
2132 #define	RISC_127	0x0003007f
2133 #define	SHADOW_OFFSET	0xb0000000
2134 
2135 	for (i = 0; i < MPI_CORE_SH_REGS_CNT; i++, buf++) {
2136 		if (ql_write_processor_data(qlge, RISC_124,
2137 		    (SHADOW_OFFSET | i << 20)) != DDI_SUCCESS)
2138 			goto end;
2139 		if (ql_read_processor_data(qlge, RISC_127, buf) != DDI_SUCCESS)
2140 			goto end;
2141 	}
2142 	rtn_val = DDI_SUCCESS;
2143 
2144 end:
2145 	return (rtn_val);
2146 }
2147 
2148 #define	SYS_CLOCK		0x00
2149 #define	PCI_CLOCK		0x80
2150 #define	FC_CLOCK		0x140
2151 #define	XGM_CLOCK		0x180
2152 #define	ADDRESS_REGISTER_ENABLE	0x00010000
2153 #define	UP			0x00008000
2154 #define	MAX_MUX			0x40
2155 #define	MAX_MODULES		0x1F
2156 
2157 static uint32_t *
2158 ql_get_probe(qlge_t *qlge, uint32_t clock, uint8_t *valid, uint32_t *buf)
2159 {
2160 	uint32_t module, mux_sel, probe, lo_val, hi_val;
2161 
2162 	for (module = 0; module < MAX_MODULES; module ++) {
2163 		if (valid[module]) {
2164 			for (mux_sel = 0; mux_sel < MAX_MUX; mux_sel++) {
2165 				probe = clock | ADDRESS_REGISTER_ENABLE |
2166 				    mux_sel |(module << 9);
2167 
2168 				ql_write_reg(qlge, REG_PRB_MX_ADDR, probe);
2169 				lo_val = ql_read_reg(qlge, REG_PRB_MX_DATA);
2170 				if (mux_sel == 0) {
2171 					*buf = probe;
2172 					buf ++;
2173 				}
2174 				probe |= UP;
2175 				ql_write_reg(qlge, REG_PRB_MX_ADDR, probe);
2176 				hi_val = ql_read_reg(qlge, REG_PRB_MX_DATA);
2177 				*buf = lo_val;
2178 				buf++;
2179 				*buf = hi_val;
2180 				buf++;
2181 			}
2182 		}
2183 	}
2184 	return (buf);
2185 }
2186 
2187 static int
2188 ql_get_probe_dump(qlge_t *qlge, uint32_t *buf)
2189 {
2190 	uint8_t sys_clock_valid_modules[0x20] = {
2191 		1,	/* 0x00 */
2192 		1,	/* 0x01 */
2193 		1,	/* 0x02 */
2194 		0,	/* 0x03 */
2195 		1,	/* 0x04 */
2196 		1,	/* 0x05 */
2197 		1,	/* 0x06 */
2198 		1,	/* 0x07 */
2199 		1,	/* 0x08 */
2200 		1,	/* 0x09 */
2201 		1,	/* 0x0A */
2202 		1,	/* 0x0B */
2203 		1,	/* 0x0C */
2204 		1,	/* 0x0D */
2205 		1,	/* 0x0E */
2206 		0,	/* 0x0F */
2207 		1,	/* 0x10 */
2208 		1,	/* 0x11 */
2209 		1,	/* 0x12 */
2210 		1,	/* 0x13 */
2211 		0,	/* 0x14 */
2212 		0,	/* 0x15 */
2213 		0,	/* 0x16 */
2214 		0,	/* 0x17 */
2215 		0,	/* 0x18 */
2216 		0,	/* 0x19 */
2217 		0,	/* 0x1A */
2218 		0,	/* 0x1B */
2219 		0,	/* 0x1C */
2220 		0,	/* 0x1D */
2221 		0,	/* 0x1E */
2222 		0	/* 0x1F */
2223 	};
2224 
2225 	unsigned char pci_clock_valid_modules[0x20] = {
2226 		1,	/* 0x00 */
2227 		0,	/* 0x01 */
2228 		0,	/* 0x02 */
2229 		0,	/* 0x03 */
2230 		0,	/* 0x04 */
2231 		0,	/* 0x05 */
2232 		1,	/* 0x06 */
2233 		1,	/* 0x07 */
2234 		0,	/* 0x08 */
2235 		0,	/* 0x09 */
2236 		0,	/* 0x0A */
2237 		0,	/* 0x0B */
2238 		0,	/* 0x0C */
2239 		0,	/* 0x0D */
2240 		1,	/* 0x0E */
2241 		0,	/* 0x0F */
2242 		0,	/* 0x10 */
2243 		0,	/* 0x11 */
2244 		0,	/* 0x12 */
2245 		0,	/* 0x13 */
2246 		0,	/* 0x14 */
2247 		0,	/* 0x15 */
2248 		0,	/* 0x16 */
2249 		0,	/* 0x17 */
2250 		0,	/* 0x18 */
2251 		0,	/* 0x19 */
2252 		0,	/* 0x1A */
2253 		0,	/* 0x1B */
2254 		0,	/* 0x1C */
2255 		0,	/* 0x1D */
2256 		0,	/* 0x1E */
2257 		0	/* 0x1F */
2258 	};
2259 
2260 	unsigned char xgm_clock_valid_modules[0x20] = {
2261 		1,	/* 0x00 */
2262 		0,	/* 0x01 */
2263 		0,	/* 0x02 */
2264 		1,	/* 0x03 */
2265 		0,	/* 0x04 */
2266 		0,	/* 0x05 */
2267 		0,	/* 0x06 */
2268 		0,	/* 0x07 */
2269 		1,	/* 0x08 */
2270 		1,	/* 0x09 */
2271 		0,	/* 0x0A */
2272 		0,	/* 0x0B */
2273 		1,	/* 0x0C */
2274 		1,	/* 0x0D */
2275 		1,	/* 0x0E */
2276 		0,	/* 0x0F */
2277 		1,	/* 0x10 */
2278 		1,	/* 0x11 */
2279 		0,	/* 0x12 */
2280 		0,	/* 0x13 */
2281 		0,	/* 0x14 */
2282 		0,	/* 0x15 */
2283 		0,	/* 0x16 */
2284 		0,	/* 0x17 */
2285 		0,	/* 0x18 */
2286 		0,	/* 0x19 */
2287 		0,	/* 0x1A */
2288 		0,	/* 0x1B */
2289 		0,	/* 0x1C */
2290 		0,	/* 0x1D */
2291 		0,	/* 0x1E */
2292 		0	/* 0x1F */
2293 	};
2294 
2295 	unsigned char fc_clock_valid_modules[0x20] = {
2296 		1,	/* 0x00 */
2297 		0,	/* 0x01 */
2298 		0,	/* 0x02 */
2299 		0,	/* 0x03 */
2300 		0,	/* 0x04 */
2301 		0,	/* 0x05 */
2302 		0,	/* 0x06 */
2303 		0,	/* 0x07 */
2304 		0,	/* 0x08 */
2305 		0,	/* 0x09 */
2306 		0,	/* 0x0A */
2307 		0,	/* 0x0B */
2308 		1,	/* 0x0C */
2309 		1,	/* 0x0D */
2310 		0,	/* 0x0E */
2311 		0,	/* 0x0F */
2312 		0,	/* 0x10 */
2313 		0,	/* 0x11 */
2314 		0,	/* 0x12 */
2315 		0,	/* 0x13 */
2316 		0,	/* 0x14 */
2317 		0,	/* 0x15 */
2318 		0,	/* 0x16 */
2319 		0,	/* 0x17 */
2320 		0,	/* 0x18 */
2321 		0,	/* 0x19 */
2322 		0,	/* 0x1A */
2323 		0,	/* 0x1B */
2324 		0,	/* 0x1C */
2325 		0,	/* 0x1D */
2326 		0,	/* 0x1E */
2327 		0	/* 0x1F */
2328 	};
2329 
2330 	/*
2331 	 * First we have to enable the probe mux
2332 	 */
2333 	(void) ql_write_processor_data(qlge, 0x100e, 0x18a20000);
2334 
2335 	buf = ql_get_probe(qlge, SYS_CLOCK, sys_clock_valid_modules, buf);
2336 
2337 	buf = ql_get_probe(qlge, PCI_CLOCK, pci_clock_valid_modules, buf);
2338 
2339 	buf = ql_get_probe(qlge, XGM_CLOCK, xgm_clock_valid_modules, buf);
2340 
2341 	buf = ql_get_probe(qlge, FC_CLOCK, fc_clock_valid_modules, buf);
2342 
2343 	return (0);
2344 
2345 }
2346 
2347 /*
2348  * Dump rounting index registers
2349  */
2350 void
2351 ql_get_routing_index_registers(qlge_t *qlge, uint32_t *buf)
2352 {
2353 	uint32_t type, index, index_max;
2354 	uint32_t result_index;
2355 	uint32_t result_data;
2356 	uint32_t val;
2357 
2358 	for (type = 0; type < 4; type ++) {
2359 		if (type < 2) {
2360 			index_max = 8;
2361 		} else {
2362 			index_max = 16;
2363 		}
2364 		for (index = 0; index < index_max; index ++) {
2365 			val = 0x04000000 | (type << 16) | (index << 8);
2366 			ql_write_reg(qlge, REG_ROUTING_INDEX, val);
2367 			result_index = 0;
2368 			while ((result_index & 0x40000000) == 0) {
2369 				result_index =
2370 				    ql_read_reg(qlge, REG_ROUTING_INDEX);
2371 			}
2372 			result_data = ql_read_reg(qlge, REG_ROUTING_DATA);
2373 			*buf = type;
2374 			buf ++;
2375 			*buf = index;
2376 			buf ++;
2377 			*buf = result_index;
2378 			buf ++;
2379 			*buf = result_data;
2380 			buf ++;
2381 		}
2382 	}
2383 }
2384 
2385 /*
2386  * Dump mac protocol registers
2387  */
2388 void
2389 ql_get_mac_protocol_registers(qlge_t *qlge, uint32_t *buf)
2390 {
2391 #define	RS_AND_ADR	0x06000000
2392 #define	RS_ONLY		0x04000000
2393 #define	NUM_TYPES	10
2394 	uint32_t result_index, result_data;
2395 	uint32_t type;
2396 	uint32_t index;
2397 	uint32_t offset;
2398 	uint32_t val;
2399 	uint32_t initial_val;
2400 	uint32_t max_index;
2401 	uint32_t max_offset;
2402 
2403 	for (type = 0; type < NUM_TYPES; type ++) {
2404 		switch (type) {
2405 
2406 		case 0: /* CAM */
2407 			initial_val = RS_AND_ADR;
2408 			max_index = 512;
2409 			max_offset = 3;
2410 			break;
2411 
2412 		case 1: /* Multicast MAC Address */
2413 			initial_val = RS_ONLY;
2414 			max_index = 32;
2415 			max_offset = 2;
2416 			break;
2417 
2418 		case 2: /* VLAN filter mask */
2419 		case 3: /* MC filter mask */
2420 			initial_val = RS_ONLY;
2421 			max_index = 4096;
2422 			max_offset = 1;
2423 			break;
2424 
2425 		case 4: /* FC MAC addresses */
2426 			initial_val = RS_ONLY;
2427 			max_index = 4;
2428 			max_offset = 2;
2429 			break;
2430 
2431 		case 5: /* Mgmt MAC addresses */
2432 			initial_val = RS_ONLY;
2433 			max_index = 8;
2434 			max_offset = 2;
2435 			break;
2436 
2437 		case 6: /* Mgmt VLAN addresses */
2438 			initial_val = RS_ONLY;
2439 			max_index = 16;
2440 			max_offset = 1;
2441 			break;
2442 
2443 		case 7: /* Mgmt IPv4 address */
2444 			initial_val = RS_ONLY;
2445 			max_index = 4;
2446 			max_offset = 1;
2447 			break;
2448 
2449 		case 8: /* Mgmt IPv6 address */
2450 			initial_val = RS_ONLY;
2451 			max_index = 4;
2452 			max_offset = 4;
2453 			break;
2454 
2455 		case 9: /* Mgmt TCP/UDP Dest port */
2456 			initial_val = RS_ONLY;
2457 			max_index = 4;
2458 			max_offset = 1;
2459 			break;
2460 
2461 		default:
2462 			cmn_err(CE_WARN, "Bad type!!! 0x%08x", type);
2463 			max_index = 0;
2464 			max_offset = 0;
2465 			break;
2466 		}
2467 		for (index = 0; index < max_index; index ++) {
2468 			for (offset = 0; offset < max_offset; offset ++) {
2469 				val = initial_val | (type << 16) | (index << 4)
2470 				    | (offset);
2471 				ql_write_reg(qlge,
2472 				    REG_MAC_PROTOCOL_ADDRESS_INDEX, val);
2473 				result_index = 0;
2474 				while ((result_index & 0x40000000) == 0) {
2475 					result_index = ql_read_reg(qlge,
2476 					    REG_MAC_PROTOCOL_ADDRESS_INDEX);
2477 				}
2478 				result_data =
2479 				    ql_read_reg(qlge, REG_MAC_PROTOCOL_DATA);
2480 				*buf = result_index;
2481 				buf ++;
2482 				*buf = result_data;
2483 				buf ++;
2484 			}
2485 		}
2486 	}
2487 }
2488 
2489 /*
2490  * Dump serdes registers
2491  */
2492 static int
2493 ql_get_serdes_regs(qlge_t *qlge, struct ql_mpi_coredump *mpi_coredump)
2494 {
2495 	uint32_t i, j;
2496 	int status;
2497 
2498 	for (i = 0, j = 0; i <= 0x000000034; i += 4) {
2499 		status = ql_read_serdes_reg(qlge, i,
2500 		    &mpi_coredump->serdes_xaui_an[j++]);
2501 		if (status != DDI_SUCCESS) {
2502 			goto err;
2503 		}
2504 	}
2505 
2506 	for (i = 0x800, j = 0; i <= 0x880; i += 4) {
2507 		status = ql_read_serdes_reg(qlge, i,
2508 		    &mpi_coredump->serdes_xaui_hss_pcs[j++]);
2509 		if (status != DDI_SUCCESS) {
2510 			goto err;
2511 		}
2512 	}
2513 
2514 	for (i = 0x1000, j = 0; i <= 0x1034; i += 4) {
2515 		status = ql_read_serdes_reg(qlge, i,
2516 		    &mpi_coredump->serdes_xfi_an[j++]);
2517 		if (status != DDI_SUCCESS) {
2518 			goto err;
2519 		}
2520 	}
2521 
2522 	for (i = 0x1050, j = 0; i <= 0x107c; i += 4) {
2523 		status = ql_read_serdes_reg(qlge, i,
2524 		    &mpi_coredump->serdes_xfi_train[j++]);
2525 		if (status != DDI_SUCCESS) {
2526 			goto err;
2527 		}
2528 	}
2529 
2530 	for (i = 0x1800, j = 0; i <= 0x1838; i += 4) {
2531 		status = ql_read_serdes_reg(qlge, i,
2532 		    &mpi_coredump->serdes_xfi_hss_pcs[j++]);
2533 		if (status != DDI_SUCCESS) {
2534 			goto err;
2535 		}
2536 	}
2537 
2538 	for (i = 0x1c00; i <= 0x1c1f; i++) {
2539 		status = ql_read_serdes_reg(qlge, i,
2540 		    &mpi_coredump->serdes_xfi_hss_tx[i]);
2541 		if (status != DDI_SUCCESS) {
2542 			goto err;
2543 		}
2544 	}
2545 
2546 	for (i = 0x1c40; i <= 0x1c5f; i++) {
2547 		status = ql_read_serdes_reg(qlge, i,
2548 		    &mpi_coredump->serdes_xfi_hss_rx[i]);
2549 		if (status != DDI_SUCCESS) {
2550 			goto err;
2551 		}
2552 	}
2553 
2554 	for (i = 0x1e00; i <= 0x1e1f; i++) {
2555 		status = ql_read_serdes_reg(qlge, i,
2556 		    &mpi_coredump->serdes_xfi_hss_pll[i]);
2557 		if (status != DDI_SUCCESS) {
2558 			goto err;
2559 		}
2560 	}
2561 
2562 err:
2563 	if (status != DDI_SUCCESS) {
2564 		cmn_err(CE_WARN, "Serdes register 0x%x access error", i);
2565 	}
2566 
2567 	return (status);
2568 }
2569 
2570 /*
2571  * Dump ets registers
2572  */
2573 static int
2574 ql_get_ets_regs(qlge_t *qlge, uint32_t *buf)
2575 {
2576 	int i;
2577 
2578 	/*
2579 	 * First read out the NIC ETS
2580 	 */
2581 	for (i = 0; i < 8; i++, buf++) {
2582 		ql_write_reg(qlge, REG_NIC_ENHANCED_TX_SCHEDULE,
2583 		    i << 29 | 0x08000000);
2584 		/* wait for reg to come ready */
2585 		/* get the data */
2586 		*buf = ql_read_reg(qlge, REG_NIC_ENHANCED_TX_SCHEDULE);
2587 	}
2588 	/*
2589 	 * Now read out the CNA ETS
2590 	 */
2591 	for (i = 0; i < 2; i ++, buf ++) {
2592 		ql_write_reg(qlge, REG_CNA_ENHANCED_TX_SCHEDULE,
2593 		    i << 29 | 0x08000000);
2594 		/* wait for reg to come ready */
2595 		*buf = ql_read_reg(qlge, REG_CNA_ENHANCED_TX_SCHEDULE);
2596 	}
2597 
2598 	return (0);
2599 }
2600 
2601 /*
2602  * Core dump in binary format
2603  */
2604 int
2605 ql_8xxx_binary_core_dump(qlge_t *qlge, ql_mpi_coredump_t *mpi_coredump)
2606 {
2607 	int		rtn_val = DDI_FAILURE;
2608 	uint64_t	timestamp, phy_addr;
2609 	uint32_t	addr;
2610 	int		i;
2611 
2612 	if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) {
2613 		return (rtn_val);
2614 	}
2615 
2616 	/* pause the risc */
2617 	if (ql_pause_mpi_risc(qlge) != DDI_SUCCESS) {
2618 		cmn_err(CE_WARN,
2619 		    "%s(%d) Wait for RISC paused timeout.",
2620 		    __func__, qlge->instance);
2621 		goto out;
2622 	}
2623 
2624 	/* 0:make core dump header */
2625 	bzero(&(mpi_coredump->mpi_global_header),
2626 	    sizeof (mpi_coredump_global_header_t));
2627 	mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
2628 	(void) strcpy(mpi_coredump->mpi_global_header.id_string,
2629 	    "MPI Coredump");
2630 	timestamp = ddi_get_time();
2631 	timestamp *= 1000000;
2632 	mpi_coredump->mpi_global_header.time_lo = LSW(timestamp);
2633 	mpi_coredump->mpi_global_header.time_hi = MSW(timestamp);
2634 	mpi_coredump->mpi_global_header.total_image_size =
2635 	    (uint32_t)(sizeof (ql_mpi_coredump_t));
2636 	mpi_coredump->mpi_global_header.global_header_size =
2637 	    sizeof (mpi_coredump_global_header_t);
2638 	(void) strcpy(mpi_coredump->mpi_global_header.driver_info,
2639 	    "driver version is "VERSIONSTR);
2640 
2641 	/* 1:MPI Core Registers */
2642 	ql_build_coredump_seg_header(&mpi_coredump->core_regs_seg_hdr,
2643 	    CORE_SEG_NUM, sizeof (mpi_coredump->core_regs_seg_hdr) +
2644 	    sizeof (mpi_coredump->mpi_core_regs) +
2645 	    sizeof (mpi_coredump->mpi_core_sh_regs),
2646 	    (uint8_t *)"Core Registers");
2647 
2648 	/* first, read 127 core registers */
2649 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->mpi_core_regs[0],
2650 	    MPI_CORE_REGS_ADDR, MPI_CORE_REGS_CNT);
2651 	/* read the next 16 shadow registers */
2652 	(void) ql_get_mpi_shadow_regs(qlge,
2653 	    &mpi_coredump->mpi_core_sh_regs[0]);
2654 
2655 	/* 2:MPI Test Logic Registers */
2656 	ql_build_coredump_seg_header(&mpi_coredump->test_logic_regs_seg_hdr,
2657 	    TEST_LOGIC_SEG_NUM,
2658 	    sizeof (mpi_coredump_segment_header_t) +
2659 	    sizeof (mpi_coredump->test_logic_regs),
2660 	    (uint8_t *)"Test Logic Regs");
2661 
2662 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->test_logic_regs[0],
2663 	    TEST_REGS_ADDR, TEST_REGS_CNT);
2664 
2665 	/* 3:RMII Registers */
2666 	ql_build_coredump_seg_header(&mpi_coredump->rmii_regs_seg_hdr,
2667 	    RMII_SEG_NUM,
2668 	    sizeof (mpi_coredump_segment_header_t) +
2669 	    sizeof (mpi_coredump->rmii_regs),
2670 	    (uint8_t *)"RMII Registers");
2671 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->rmii_regs[0],
2672 	    RMII_REGS_ADDR, RMII_REGS_CNT);
2673 
2674 	/* 4:FCMAC1 Registers */
2675 	ql_build_coredump_seg_header(&mpi_coredump->fcmac1_regs_seg_hdr,
2676 	    FCMAC1_SEG_NUM,
2677 	    sizeof (mpi_coredump_segment_header_t) +
2678 	    sizeof (mpi_coredump->fcmac1_regs),
2679 	    (uint8_t *)"FCMAC1 Registers");
2680 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->fcmac1_regs[0],
2681 	    FCMAC1_REGS_ADDR, FCMAC_REGS_CNT);
2682 
2683 	/* 5:FCMAC2 Registers */
2684 	ql_build_coredump_seg_header(&mpi_coredump->fcmac2_regs_seg_hdr,
2685 	    FCMAC2_SEG_NUM,
2686 	    sizeof (mpi_coredump_segment_header_t) +
2687 	    sizeof (mpi_coredump->fcmac2_regs),
2688 	    (uint8_t *)"FCMAC2 Registers");
2689 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->fcmac2_regs[0],
2690 	    FCMAC2_REGS_ADDR, FCMAC_REGS_CNT);
2691 
2692 	/* 6:FC1 Mailbox Registers */
2693 	ql_build_coredump_seg_header(&mpi_coredump->fc1_mbx_regs_seg_hdr,
2694 	    FC1_MBOX_SEG_NUM,
2695 	    sizeof (mpi_coredump_segment_header_t) +
2696 	    sizeof (mpi_coredump->fc1_mbx_regs),
2697 	    (uint8_t *)"FC1 MBox Regs");
2698 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->fc1_mbx_regs[0],
2699 	    FC1_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
2700 
2701 	/* 7:IDE Registers */
2702 	ql_build_coredump_seg_header(&mpi_coredump->ide_regs_seg_hdr,
2703 	    IDE_SEG_NUM,
2704 	    sizeof (mpi_coredump_segment_header_t) +
2705 	    sizeof (mpi_coredump->ide_regs),
2706 	    (uint8_t *)"IDE Registers");
2707 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->ide_regs[0],
2708 	    IDE_REGS_ADDR, IDE_REGS_CNT);
2709 
2710 	/* 8:Host1 Mailbox Registers */
2711 	ql_build_coredump_seg_header(&mpi_coredump->nic1_mbx_regs_seg_hdr,
2712 	    NIC1_MBOX_SEG_NUM,
2713 	    sizeof (mpi_coredump_segment_header_t) +
2714 	    sizeof (mpi_coredump->nic1_mbx_regs),
2715 	    (uint8_t *)"NIC1 MBox Regs");
2716 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->nic1_mbx_regs[0],
2717 	    NIC1_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
2718 
2719 	/* 9:SMBus Registers */
2720 	ql_build_coredump_seg_header(&mpi_coredump->smbus_regs_seg_hdr,
2721 	    SMBUS_SEG_NUM,
2722 	    sizeof (mpi_coredump_segment_header_t) +
2723 	    sizeof (mpi_coredump->smbus_regs),
2724 	    (uint8_t *)"SMBus Registers");
2725 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->smbus_regs[0],
2726 	    SMBUS_REGS_ADDR, SMBUS_REGS_CNT);
2727 
2728 	/* 10:FC2 Mailbox Registers */
2729 	ql_build_coredump_seg_header(&mpi_coredump->fc2_mbx_regs_seg_hdr,
2730 	    FC2_MBOX_SEG_NUM,
2731 	    sizeof (mpi_coredump_segment_header_t) +
2732 	    sizeof (mpi_coredump->fc2_mbx_regs),
2733 	    (uint8_t *)"FC2 MBox Regs");
2734 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->fc2_mbx_regs[0],
2735 	    FC2_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
2736 
2737 	/* 11:Host2 Mailbox Registers */
2738 	ql_build_coredump_seg_header(&mpi_coredump->nic2_mbx_regs_seg_hdr,
2739 	    NIC2_MBOX_SEG_NUM,
2740 	    sizeof (mpi_coredump_segment_header_t) +
2741 	    sizeof (mpi_coredump->nic2_mbx_regs),
2742 	    (uint8_t *)"NIC2 MBox Regs");
2743 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->nic2_mbx_regs[0],
2744 	    NIC2_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
2745 
2746 	/* 12:i2C Registers */
2747 	ql_build_coredump_seg_header(&mpi_coredump->i2c_regs_seg_hdr,
2748 	    I2C_SEG_NUM,
2749 	    sizeof (mpi_coredump_segment_header_t) +
2750 	    sizeof (mpi_coredump->i2c_regs),
2751 	    (uint8_t *)"I2C Registers");
2752 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->i2c_regs[0],
2753 	    I2C_REGS_ADDR, I2C_REGS_CNT);
2754 
2755 	/* 13:MEMC Registers */
2756 	ql_build_coredump_seg_header(&mpi_coredump->memc_regs_seg_hdr,
2757 	    MEMC_SEG_NUM,
2758 	    sizeof (mpi_coredump_segment_header_t) +
2759 	    sizeof (mpi_coredump->memc_regs),
2760 	    (uint8_t *)"MEMC Registers");
2761 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->memc_regs[0],
2762 	    MEMC_REGS_ADDR, MEMC_REGS_CNT);
2763 
2764 	/* 14:PBus Registers */
2765 	ql_build_coredump_seg_header(&mpi_coredump->pbus_regs_seg_hdr,
2766 	    PBUS_SEG_NUM,
2767 	    sizeof (mpi_coredump_segment_header_t) +
2768 	    sizeof (mpi_coredump->pbus_regs),
2769 	    (uint8_t *)"PBUS Registers");
2770 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->pbus_regs[0],
2771 	    PBUS_REGS_ADDR, PBUS_REGS_CNT);
2772 
2773 	/* 15:MDE Registers */
2774 	ql_build_coredump_seg_header(&mpi_coredump->mde_regs_seg_hdr,
2775 	    MDE_SEG_NUM,
2776 	    sizeof (mpi_coredump_segment_header_t) +
2777 	    sizeof (mpi_coredump->mde_regs),
2778 	    (uint8_t *)"MDE Registers");
2779 	(void) ql_get_mpi_regs(qlge, &mpi_coredump->mde_regs[0],
2780 	    MDE_REGS_ADDR, MDE_REGS_CNT);
2781 
2782 	ql_build_coredump_seg_header(&mpi_coredump->xaui_an_hdr,
2783 	    XAUI_AN_SEG_NUM,
2784 	    sizeof (mpi_coredump_segment_header_t) +
2785 	    sizeof (mpi_coredump->serdes_xaui_an),
2786 	    (uint8_t *)"XAUI AN Registers");
2787 
2788 	ql_build_coredump_seg_header(&mpi_coredump->xaui_hss_pcs_hdr,
2789 	    XAUI_HSS_PCS_SEG_NUM,
2790 	    sizeof (mpi_coredump_segment_header_t) +
2791 	    sizeof (mpi_coredump->serdes_xaui_hss_pcs),
2792 	    (uint8_t *)"XAUI HSS PCS Registers");
2793 
2794 	ql_build_coredump_seg_header(&mpi_coredump->xfi_an_hdr,
2795 	    XFI_AN_SEG_NUM,
2796 	    sizeof (mpi_coredump_segment_header_t) +
2797 	    sizeof (mpi_coredump->serdes_xfi_an),
2798 	    (uint8_t *)"XFI AN Registers");
2799 
2800 	ql_build_coredump_seg_header(&mpi_coredump->xfi_train_hdr,
2801 	    XFI_TRAIN_SEG_NUM,
2802 	    sizeof (mpi_coredump_segment_header_t) +
2803 	    sizeof (mpi_coredump->serdes_xfi_train),
2804 	    (uint8_t *)"XFI TRAIN Registers");
2805 
2806 	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_pcs_hdr,
2807 	    XFI_HSS_PCS_SEG_NUM,
2808 	    sizeof (mpi_coredump_segment_header_t) +
2809 	    sizeof (mpi_coredump->serdes_xfi_hss_pcs),
2810 	    (uint8_t *)"XFI HSS PCS Registers");
2811 
2812 	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_tx_hdr,
2813 	    XFI_HSS_TX_SEG_NUM,
2814 	    sizeof (mpi_coredump_segment_header_t) +
2815 	    sizeof (mpi_coredump->serdes_xfi_hss_tx),
2816 	    (uint8_t *)"XFI HSS TX Registers");
2817 
2818 	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_rx_hdr,
2819 	    XFI_HSS_RX_SEG_NUM,
2820 	    sizeof (mpi_coredump_segment_header_t) +
2821 	    sizeof (mpi_coredump->serdes_xfi_hss_rx),
2822 	    (uint8_t *)"XFI HSS RX Registers");
2823 
2824 	ql_build_coredump_seg_header(&mpi_coredump->xfi_hss_pll_hdr,
2825 	    XFI_HSS_PLL_SEG_NUM,
2826 	    sizeof (mpi_coredump_segment_header_t) +
2827 	    sizeof (mpi_coredump->serdes_xfi_hss_pll),
2828 	    (uint8_t *)"XFI HSS PLL Registers");
2829 
2830 	(void) ql_get_serdes_regs(qlge, mpi_coredump);
2831 
2832 	/* 16:NIC Ctrl Registers Port1 */
2833 	ql_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
2834 	    NIC1_CONTROL_SEG_NUM,
2835 	    sizeof (mpi_coredump_segment_header_t) +
2836 	    sizeof (mpi_coredump->nic_regs),
2837 	    (uint8_t *)"NIC Registers");
2838 	i = 0;
2839 	for (addr = 0; addr <= 0xFC; i++) {
2840 		mpi_coredump->nic_regs[i] = ql_read_reg(qlge, addr);
2841 		addr += 4;
2842 	}
2843 
2844 	ql_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr,
2845 	    INTR_STATES_SEG_NUM,
2846 	    sizeof (mpi_coredump_segment_header_t) +
2847 	    sizeof (mpi_coredump->intr_states),
2848 	    (uint8_t *)"INTR States");
2849 	ql_get_intr_states(qlge, &mpi_coredump->intr_states[0]);
2850 
2851 	ql_build_coredump_seg_header(&mpi_coredump->xgmac_seg_hdr,
2852 	    NIC1_XGMAC_SEG_NUM,
2853 	    sizeof (mpi_coredump_segment_header_t) +
2854 	    sizeof (mpi_coredump->xgmac),
2855 	    (uint8_t *)"NIC XGMac Registers");
2856 	(void) ql_get_xgmac_regs(qlge, &mpi_coredump->xgmac[0]);
2857 
2858 	ql_build_coredump_seg_header(&mpi_coredump->probe_dump_seg_hdr,
2859 	    PROBE_DUMP_SEG_NUM,
2860 	    sizeof (mpi_coredump_segment_header_t) +
2861 	    sizeof (mpi_coredump->probe_dump),
2862 	    (uint8_t *)"Probe Dump");
2863 	(void) ql_get_probe_dump(qlge, &mpi_coredump->probe_dump[0]);
2864 
2865 	ql_build_coredump_seg_header(&mpi_coredump->routing_reg_seg_hdr,
2866 	    ROUTING_INDEX_SEG_NUM,
2867 	    sizeof (mpi_coredump_segment_header_t) +
2868 	    sizeof (mpi_coredump->routing_regs),
2869 	    (uint8_t *)"Routing Regs");
2870 
2871 	ql_get_routing_index_registers(qlge, &mpi_coredump->routing_regs[0]);
2872 
2873 	ql_build_coredump_seg_header(&mpi_coredump->mac_prot_reg_seg_hdr,
2874 	    MAC_PROTOCOL_SEG_NUM,
2875 	    sizeof (mpi_coredump_segment_header_t) +
2876 	    sizeof (mpi_coredump->mac_prot_regs),
2877 	    (uint8_t *)"MAC Prot Regs");
2878 
2879 	ql_get_mac_protocol_registers(qlge, &mpi_coredump->mac_prot_regs[0]);
2880 
2881 	ql_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr,
2882 	    ETS_SEG_NUM,
2883 	    sizeof (mpi_coredump_segment_header_t) +
2884 	    sizeof (mpi_coredump->ets),
2885 	    (uint8_t *)"ETS Registers");
2886 
2887 	(void) ql_get_ets_regs(qlge, &mpi_coredump->ets[0]);
2888 
2889 	/* clear the pause */
2890 	if (ql_unpause_mpi_risc(qlge) != DDI_SUCCESS) {
2891 		cmn_err(CE_WARN,
2892 		    "Failed RISC unpause.");
2893 		goto out;
2894 	}
2895 
2896 	/* Reset the MPI Processor */
2897 	if (ql_reset_mpi_risc(qlge) != DDI_SUCCESS) {
2898 		goto out;
2899 	}
2900 
2901 	/* 22:WCS MPI Ram ?? */
2902 	ql_build_coredump_seg_header(&mpi_coredump->code_ram_seg_hdr,
2903 	    WCS_RAM_SEG_NUM,
2904 	    sizeof (mpi_coredump_segment_header_t) +
2905 	    sizeof (mpi_coredump->code_ram),
2906 	    (uint8_t *)"WCS RAM");
2907 	phy_addr = qlge->ioctl_buf_dma_attr.dma_addr;
2908 	if (ql_read_risc_ram(qlge, CODE_RAM_ADDR, phy_addr, CODE_RAM_CNT)
2909 	    == DDI_SUCCESS) {
2910 		(void) ddi_dma_sync(qlge->ioctl_buf_dma_attr.dma_handle, 0,
2911 		    sizeof (mpi_coredump->code_ram), DDI_DMA_SYNC_FORKERNEL);
2912 		bcopy(qlge->ioctl_buf_dma_attr.vaddr,
2913 		    mpi_coredump->code_ram,
2914 		    sizeof (mpi_coredump->code_ram));
2915 	} else {
2916 		mutex_exit(&qlge->mbx_mutex);
2917 		goto out;
2918 	}
2919 
2920 	/* 23:MEMC Ram ?? */
2921 	ql_build_coredump_seg_header(&mpi_coredump->memc_ram_seg_hdr,
2922 	    MEMC_RAM_SEG_NUM,
2923 	    sizeof (mpi_coredump_segment_header_t) +
2924 	    sizeof (mpi_coredump->memc_ram),
2925 	    (uint8_t *)"MEMC RAM");
2926 	phy_addr = qlge->ioctl_buf_dma_attr.dma_addr;
2927 	if (ql_read_risc_ram(qlge, MEMC_RAM_ADDR, phy_addr, MEMC_RAM_CNT)
2928 	    == DDI_SUCCESS) {
2929 		(void) ddi_dma_sync(qlge->ioctl_buf_dma_attr.dma_handle, 0,
2930 		    sizeof (mpi_coredump->memc_ram), DDI_DMA_SYNC_FORKERNEL);
2931 		bcopy(qlge->ioctl_buf_dma_attr.vaddr, mpi_coredump->memc_ram,
2932 		    sizeof (mpi_coredump->memc_ram));
2933 	} else {
2934 		mutex_exit(&qlge->mbx_mutex);
2935 		goto out;
2936 	}
2937 	/*
2938 	 * 24. Restart MPI
2939 	 */
2940 	if (ql_write_processor_data(qlge, 0x1010, 1) != DDI_SUCCESS) {
2941 		cmn_err(CE_WARN, "MPI restart failure.");
2942 	}
2943 
2944 	rtn_val = DDI_SUCCESS;
2945 out:
2946 	ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK);
2947 	return (rtn_val);
2948 }
2949