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