1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 QLogic Corporation. All rights reserved. 24 */ 25 26 #include <qlge.h> 27 28 static uint32_t ql_dump_buf_8(uint8_t *, uint32_t, uint32_t); 29 static uint32_t ql_dump_buf_16(uint16_t *, uint32_t, uint32_t); 30 static uint32_t ql_dump_buf_32(uint32_t *, uint32_t, uint32_t); 31 static uint32_t ql_dump_buf_64(uint64_t *, uint32_t, uint32_t); 32 static int ql_binary_core_dump(qlge_t *, uint32_t, uint32_t *); 33 34 static char ISP_8100_REGION[] = { 35 "nic: nic_boot, nic_param, nic_vpd \n" 36 "mpi: mpi_fw, mpi_config, edc_fw\n" 37 "fc: fc_boot, fc_fw, fc_nvram, fc_vpd"}; 38 static char ISP_8100_AVAILABLE_DUMPS[] = {"core,register,all"}; 39 40 /* 41 * Get byte from I/O port 42 */ 43 uint8_t 44 ql_get8(qlge_t *qlge, uint32_t index) 45 { 46 uint8_t ret; 47 48 ret = (uint8_t)ddi_get8(qlge->dev_handle, 49 (uint8_t *)(((caddr_t)qlge->iobase) + index)); 50 return (ret); 51 } 52 53 /* 54 * Get word from I/O port 55 */ 56 uint16_t 57 ql_get16(qlge_t *qlge, uint32_t index) 58 { 59 uint16_t ret; 60 61 ret = (uint16_t)ddi_get16(qlge->dev_handle, 62 (uint16_t *)(void *)(((caddr_t)qlge->iobase) + index)); 63 return (ret); 64 } 65 66 /* 67 * Get double word from I/O port 68 */ 69 uint32_t 70 ql_get32(qlge_t *qlge, uint32_t index) 71 { 72 uint32_t ret; 73 74 ret = ddi_get32(qlge->dev_handle, 75 (uint32_t *)(void *)(((caddr_t)qlge->iobase) + index)); 76 return (ret); 77 } 78 79 /* 80 * Send byte to I/O port 81 */ 82 void 83 ql_put8(qlge_t *qlge, uint32_t index, uint8_t data) 84 { 85 ddi_put8(qlge->dev_handle, 86 (uint8_t *)(((caddr_t)qlge->iobase) + index), data); 87 } 88 89 /* 90 * Send word to I/O port 91 */ 92 void 93 ql_put16(qlge_t *qlge, uint32_t index, uint16_t data) 94 { 95 ddi_put16(qlge->dev_handle, 96 (uint16_t *)(void *)(((caddr_t)qlge->iobase) + index), data); 97 } 98 99 /* 100 * Send double word to I/O port 101 */ 102 void 103 ql_put32(qlge_t *qlge, uint32_t index, uint32_t data) 104 { 105 ddi_put32(qlge->dev_handle, 106 (uint32_t *)(void *)(((caddr_t)qlge->iobase) + index), data); 107 } 108 109 /* 110 * Read from a register 111 */ 112 uint32_t 113 ql_read_reg(qlge_t *qlge, uint32_t reg) 114 { 115 uint32_t data = ql_get32(qlge, reg); 116 117 return (data); 118 } 119 120 /* 121 * Write 32 bit data to a register 122 */ 123 void 124 ql_write_reg(qlge_t *qlge, uint32_t reg, uint32_t data) 125 { 126 ql_put32(qlge, reg, data); 127 } 128 129 /* 130 * Set semaphore register bit to lock access to a shared register 131 */ 132 int 133 ql_sem_lock(qlge_t *qlge, uint32_t sem_mask, uint32_t sem_bits) 134 { 135 uint32_t value; 136 137 ql_put32(qlge, REG_SEMAPHORE, (sem_mask | sem_bits)); 138 value = ql_get32(qlge, REG_SEMAPHORE); 139 return ((value & (sem_mask >> 16)) == sem_bits); 140 } 141 /* 142 * Wait up to "delay" seconds until the register "reg"'s 143 * "wait_bit" is set 144 * Default wait time is 5 seconds if "delay" time was not set. 145 */ 146 int 147 ql_wait_reg_bit(qlge_t *qlge, uint32_t reg, uint32_t wait_bit, int set, 148 uint32_t delay) 149 { 150 uint32_t reg_status; 151 uint32_t timer = 5; /* 5 second */ 152 int rtn_val = DDI_SUCCESS; 153 uint32_t delay_ticks; 154 155 if (delay != 0) 156 timer = delay; 157 158 delay_ticks = timer * 100; 159 /* 160 * wait for Configuration register test bit to be set, 161 * if not, then it is still busy. 162 */ 163 do { 164 reg_status = ql_read_reg(qlge, reg); 165 /* wait for bit set or reset? */ 166 if (set == BIT_SET) { 167 if (reg_status & wait_bit) 168 break; 169 else 170 qlge_delay(QL_ONE_SEC_DELAY / 100); 171 } else { 172 if (reg_status & wait_bit) 173 qlge_delay(QL_ONE_SEC_DELAY / 100); 174 else 175 break; 176 } 177 } while (--delay_ticks); 178 179 if (delay_ticks == 0) { 180 rtn_val = DDI_FAILURE; 181 cmn_err(CE_WARN, "qlge(%d)wait reg %x, bit %x time out", 182 qlge->instance, reg, wait_bit); 183 if (qlge->fm_enable) { 184 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 185 atomic_or_32(&qlge->flags, ADAPTER_ERROR); 186 } 187 } 188 return (rtn_val); 189 } 190 191 /* 192 * Dump the value of control registers 193 */ 194 void 195 ql_dump_all_contrl_regs(qlge_t *qlge) 196 { 197 int i; 198 uint32_t data; 199 200 for (i = 0; i < 0xff; i = i+4) { 201 data = ql_read_reg(qlge, i); 202 ql_printf("\tregister# 0x%x value: 0x%x\n", i, data); 203 } 204 } 205 206 /* 207 * Prints string plus buffer. 208 */ 209 void 210 ql_dump_buf(char *string, uint8_t *buffer, uint8_t wd_size, 211 uint32_t count) 212 { 213 uint32_t offset = 0; 214 215 if (strcmp(string, "") != 0) 216 ql_printf(string); 217 218 if ((buffer == NULL) || (count == 0)) 219 return; 220 221 switch (wd_size) { 222 case 8: 223 while (count) { 224 count = ql_dump_buf_8(buffer, count, offset); 225 offset += 8; 226 buffer += 8; 227 } 228 break; 229 230 case 16: 231 while (count) { 232 count = ql_dump_buf_16((uint16_t *)(void *)buffer, 233 count, offset); 234 offset += 16; 235 buffer += 16; 236 } 237 break; 238 case 32: 239 while (count) { 240 count = ql_dump_buf_32((uint32_t *)(void *)buffer, 241 count, offset); 242 offset += 16; 243 buffer += 16; 244 } 245 break; 246 case 64: 247 while (count) { 248 count = ql_dump_buf_64((uint64_t *)(void *)buffer, 249 count, offset); 250 offset += 16; 251 buffer += 16; 252 } 253 break; 254 default: 255 break; 256 } 257 } 258 259 /* 260 * Print as 8bit bytes 261 */ 262 static uint32_t 263 ql_dump_buf_8(uint8_t *bp, uint32_t count, uint32_t offset) 264 { 265 switch (count) { 266 case 1: 267 ql_printf("0x%016x : %02x\n", 268 offset, 269 *bp); 270 break; 271 272 case 2: 273 ql_printf("0x%016x : %02x %02x\n", 274 offset, 275 *bp, *(bp+1)); 276 break; 277 278 case 3: 279 ql_printf("0x%016x : %02x %02x %02x\n", 280 offset, 281 *bp, *(bp+1), *(bp+2)); 282 break; 283 284 case 4: 285 ql_printf("0x%016x : %02x %02x %02x %02x\n", 286 offset, 287 *bp, *(bp+1), *(bp+2), *(bp+3)); 288 break; 289 290 case 5: 291 ql_printf("0x%016x : %02x %02x %02x %02x %02x\n", 292 offset, 293 *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4)); 294 break; 295 296 case 6: 297 ql_printf("0x%016x : %02x %02x %02x %02x %02x %02x\n", 298 offset, 299 *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5)); 300 break; 301 302 case 7: 303 ql_printf("0x%016x : %02x %02x %02x %02x %02x %02x %02x\n", 304 offset, 305 *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5), *(bp+6)); 306 break; 307 308 default: 309 ql_printf("0x%016x : %02x %02x %02x %02x %02x %02x %02x %02x\n", 310 offset, 311 *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5), *(bp+6), 312 *(bp+7)); 313 break; 314 315 } 316 317 if (count < 8) { 318 count = 0; 319 } else { 320 count -= 8; 321 } 322 323 return (count); 324 } 325 326 /* 327 * Print as 16bit 328 */ 329 static uint32_t 330 ql_dump_buf_16(uint16_t *bp, uint32_t count, uint32_t offset) 331 { 332 333 switch (count) { 334 case 1: 335 ql_printf("0x%016x : %04x\n", 336 offset, 337 *bp); 338 break; 339 340 case 2: 341 ql_printf("0x%016x : %04x %04x\n", 342 offset, 343 *bp, *(bp+1)); 344 break; 345 346 case 3: 347 ql_printf("0x%016x : %04x %04x %04x\n", 348 offset, 349 *bp, *(bp+1), *(bp+2)); 350 break; 351 352 case 4: 353 ql_printf("0x%016x : %04x %04x %04x %04x\n", 354 offset, 355 *bp, *(bp+1), *(bp+2), *(bp+3)); 356 break; 357 358 case 5: 359 ql_printf("0x%016x : %04x %04x %04x %04x %04x\n", 360 offset, 361 *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4)); 362 break; 363 364 case 6: 365 ql_printf("0x%016x : %04x %04x %04x %04x %04x %04x\n", 366 offset, 367 *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5)); 368 break; 369 370 case 7: 371 ql_printf("0x%016x : %04x %04x %04x %04x %04x %04x %04x\n", 372 offset, 373 *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5), *(bp+6)); 374 break; 375 376 default: 377 ql_printf("0x%016x : %04x %04x %04x %04x %04x %04x %04x %04x\n", 378 offset, 379 *bp, *(bp+1), *(bp+2), *(bp+3), *(bp+4), *(bp+5), *(bp+6), 380 *(bp+7)); 381 break; 382 } 383 384 if (count < 8) { 385 count = 0; 386 } else { 387 count -= 8; 388 } 389 390 return (count); 391 } 392 393 /* 394 * Print as 32bit 395 */ 396 static uint32_t 397 ql_dump_buf_32(uint32_t *bp, uint32_t count, uint32_t offset) 398 { 399 400 switch (count) { 401 case 1: 402 ql_printf("0x%016x : %08x\n", 403 offset, 404 *bp); 405 break; 406 407 case 2: 408 ql_printf("0x%016x : %08x %08x\n", 409 offset, 410 *bp, *(bp+1)); 411 break; 412 413 case 3: 414 ql_printf("0x%016x : %08x %08x %08x\n", 415 offset, 416 *bp, *(bp+1), *(bp+2)); 417 break; 418 419 default: 420 ql_printf("0x%016x : %08x %08x %08x %08x\n", 421 offset, 422 *bp, *(bp+1), *(bp+2), *(bp+3)); 423 break; 424 } 425 426 if (count < 4) { 427 count = 0; 428 } else { 429 count -= 4; 430 } 431 432 return (count); 433 } 434 435 /* 436 * Print as 64bit 437 */ 438 static uint32_t 439 ql_dump_buf_64(uint64_t *bp, uint32_t count, uint32_t offset) 440 { 441 442 switch (count) { 443 case 1: 444 ql_printf("0x%016x : %016x\n", 445 offset, 446 *bp); 447 break; 448 449 default: 450 ql_printf("0x%016x : %016x %016x\n", 451 offset, 452 *bp, *(bp+1)); 453 break; 454 455 } 456 457 if (count < 2) { 458 count = 0; 459 } else { 460 count -= 2; 461 } 462 463 return (count); 464 } 465 466 /* 467 * Print CQICB control block information 468 */ 469 /* ARGSUSED */ 470 void 471 ql_dump_cqicb(qlge_t *qlge, struct cqicb_t *cqicb) 472 { 473 _NOTE(ARGUNUSED(qlge)); 474 ASSERT(qlge != NULL); 475 ASSERT(cqicb != NULL); 476 ql_printf("ql_dump_cqicb:entered\n"); 477 478 ql_printf("\t msix_vect = 0x%x\n", 479 cqicb->msix_vect); 480 ql_printf("\t reserved1 = 0x%x\n", 481 cqicb->reserved1); 482 ql_printf("\t reserved2 = 0x%x\n", 483 cqicb->reserved2); 484 ql_printf("\t flags = 0x%x\n", 485 cqicb->flags); 486 ql_printf("\t len = 0x%x\n", 487 le16_to_cpu(cqicb->len)); 488 ql_printf("\t rid = 0x%x\n", 489 le16_to_cpu(cqicb->rid)); 490 ql_printf("\t cq_base_addr_lo = 0x%x\n", 491 le32_to_cpu(cqicb->cq_base_addr_lo)); 492 ql_printf("\t cq_base_addr_hi = 0x%x\n", 493 le32_to_cpu(cqicb->cq_base_addr_hi)); 494 ql_printf("\t prod_idx_addr_lo = %x\n", 495 le32_to_cpu(cqicb->prod_idx_addr_lo)); 496 ql_printf("\t prod_idx_addr_hi = %x\n", 497 le32_to_cpu(cqicb->prod_idx_addr_hi)); 498 ql_printf("\t pkt_delay = %d\n", 499 le16_to_cpu(cqicb->pkt_delay)); 500 ql_printf("\t irq_delay = 0x%x\n", 501 le16_to_cpu(cqicb->irq_delay)); 502 ql_printf("\t lbq_addr_lo = 0x%x\n", 503 le32_to_cpu(cqicb->lbq_addr_lo)); 504 ql_printf("\t lbq_addr_hi = 0x%x\n", 505 le32_to_cpu(cqicb->lbq_addr_hi)); 506 ql_printf("\t lbq_buf_size = 0x%x\n", 507 le16_to_cpu(cqicb->lbq_buf_size)); 508 ql_printf("\t lbq_len = 0x%x\n", 509 le16_to_cpu(cqicb->lbq_len)); 510 ql_printf("\t sbq_addr_lo = 0x%x\n", 511 le32_to_cpu(cqicb->sbq_addr_lo)); 512 ql_printf("\t sbq_addr_hi = 0x%x\n", 513 le32_to_cpu(cqicb->sbq_addr_hi)); 514 ql_printf("\t sbq_buf_size = 0x%x\n", 515 le16_to_cpu(cqicb->sbq_buf_size)); 516 ql_printf("\t sbq_len = 0x%x\n", 517 le16_to_cpu(cqicb->sbq_len)); 518 519 ql_printf("ql_dump_cqicb:exiting\n"); 520 } 521 522 /* 523 * Print WQICB control block information 524 */ 525 /* ARGSUSED */ 526 void 527 ql_dump_wqicb(qlge_t *qlge, struct wqicb_t *wqicb) 528 { 529 _NOTE(ARGUNUSED(qlge)); 530 ASSERT(qlge != NULL); 531 ASSERT(wqicb != NULL); 532 533 ql_printf("ql_dump_wqicb:entered\n"); 534 535 ql_printf("\t len = %x\n", 536 le16_to_cpu(wqicb->len)); 537 ql_printf("\t flags = %x\n", 538 le16_to_cpu(wqicb->flags)); 539 ql_printf("\t cq_id_rss = %x\n", 540 le16_to_cpu(wqicb->cq_id_rss)); 541 ql_printf("\t rid = 0x%x\n", 542 le16_to_cpu(wqicb->rid)); 543 ql_printf("\t wq_addr_lo = 0x%x\n", 544 le32_to_cpu(wqicb->wq_addr_lo)); 545 ql_printf("\t wq_addr_hi = 0x%x\n", 546 le32_to_cpu(wqicb->wq_addr_hi)); 547 ql_printf("\t cnsmr_idx_addr_lo = %x\n", 548 le32_to_cpu(wqicb->cnsmr_idx_addr_lo)); 549 ql_printf("\t cnsmr_idx_addr_hi = %x\n", 550 le32_to_cpu(wqicb->cnsmr_idx_addr_hi)); 551 552 ql_printf("ql_dump_wqicb:exit\n"); 553 } 554 555 /* 556 * Print request descriptor information 557 */ 558 void 559 ql_dump_req_pkt(qlge_t *qlge, struct ob_mac_iocb_req *pkt, void *oal, 560 int number) 561 { 562 int i = 0; 563 struct oal_entry *oal_entry; 564 565 ql_printf("ql_dump_req_pkt(%d):enter\n", qlge->instance); 566 567 ql_printf("\t opcode = 0x%x\n", 568 pkt->opcode); 569 ql_printf("\t flag0 = 0x%x\n", 570 pkt->flag0); 571 ql_printf("\t flag1 = 0x%x\n", 572 pkt->flag1); 573 ql_printf("\t flag2 = 0x%x\n", 574 pkt->flag2); 575 ql_printf("\t frame_len = 0x%x\n", 576 le16_to_cpu(pkt->frame_len)); 577 ql_printf("\t transaction_id_low = 0x%x\n", 578 le16_to_cpu(pkt->tid)); 579 ql_printf("\t txq_idx = 0x%x\n", 580 le16_to_cpu(pkt->txq_idx)); 581 ql_printf("\t protocol_hdr_len = 0x%x\n", 582 le16_to_cpu(pkt->protocol_hdr_len)); 583 ql_printf("\t hdr_off = %d\n", 584 le16_to_cpu(pkt->hdr_off)); 585 ql_printf("\t vlan_tci = %d\n", 586 le16_to_cpu(pkt->vlan_tci)); 587 ql_printf("\t mss = %d\n", 588 le16_to_cpu(pkt->mss)); 589 590 /* if OAL is needed */ 591 if (number > TX_DESC_PER_IOCB) { 592 for (i = 0; i < TX_DESC_PER_IOCB; i++) { 593 ql_printf("\t buf_addr%d_low = 0x%x\n", 594 i, pkt->oal_entry[i].buf_addr_low); 595 ql_printf("\t buf_addr%d_high = 0x%x\n", 596 i, pkt->oal_entry[i].buf_addr_high); 597 ql_printf("\t buf%d_len = 0x%x\n", 598 i, pkt->oal_entry[i].buf_len); 599 } 600 oal_entry = (struct oal_entry *)oal; 601 ql_printf("\t additional %d tx descriptors in OAL\n", 602 (number - TX_DESC_PER_IOCB + 1)); 603 for (i = 0; i < (number-TX_DESC_PER_IOCB + 1); i++) { 604 ql_printf("\t buf_addr%d_low = 0x%x\n", 605 i, oal_entry[i].buf_addr_low); 606 ql_printf("\t buf_addr%d_high = 0x%x\n", 607 i, oal_entry[i].buf_addr_high); 608 ql_printf("\t buf%d_len = 0x%x\n", 609 i, oal_entry[i].buf_len); 610 } 611 } else { 612 for (i = 0; i < number; i++) { 613 ql_printf("\t buf_addr%d_low = 0x%x\n", 614 i, pkt->oal_entry[i].buf_addr_low); 615 ql_printf("\t buf_addr%d_high = 0x%x\n", 616 i, pkt->oal_entry[i].buf_addr_high); 617 ql_printf("\t buf%d_len = 0x%x\n", 618 i, pkt->oal_entry[i].buf_len); 619 } 620 } 621 ql_printf("ql_dump_req_pkt:exiting\n"); 622 } 623 624 /* 625 * Print PCI configuration 626 */ 627 void 628 ql_dump_pci_config(qlge_t *qlge) 629 { 630 qlge->pci_cfg.vendor_id = (uint16_t) 631 pci_config_get16(qlge->pci_handle, PCI_CONF_VENID); 632 633 qlge->pci_cfg.device_id = (uint16_t) 634 pci_config_get16(qlge->pci_handle, PCI_CONF_DEVID); 635 636 qlge->pci_cfg.command = (uint16_t) 637 pci_config_get16(qlge->pci_handle, PCI_CONF_COMM); 638 639 qlge->pci_cfg.status = (uint16_t) 640 pci_config_get16(qlge->pci_handle, PCI_CONF_STAT); 641 642 qlge->pci_cfg.revision = (uint8_t) 643 pci_config_get8(qlge->pci_handle, PCI_CONF_REVID); 644 645 qlge->pci_cfg.prog_class = (uint8_t) 646 pci_config_get8(qlge->pci_handle, PCI_CONF_PROGCLASS); 647 648 qlge->pci_cfg.sub_class = (uint8_t) 649 pci_config_get8(qlge->pci_handle, PCI_CONF_SUBCLASS); 650 651 qlge->pci_cfg.base_class = (uint8_t) 652 pci_config_get8(qlge->pci_handle, PCI_CONF_BASCLASS); 653 654 qlge->pci_cfg.cache_line_size = (uint8_t) 655 pci_config_get8(qlge->pci_handle, PCI_CONF_CACHE_LINESZ); 656 657 qlge->pci_cfg.latency_timer = (uint8_t) 658 pci_config_get8(qlge->pci_handle, PCI_CONF_LATENCY_TIMER); 659 660 qlge->pci_cfg.header_type = (uint8_t) 661 pci_config_get8(qlge->pci_handle, PCI_CONF_HEADER); 662 663 qlge->pci_cfg.io_base_address = 664 pci_config_get32(qlge->pci_handle, PCI_CONF_BASE0); 665 666 qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_lower = 667 pci_config_get32(qlge->pci_handle, PCI_CONF_BASE1); 668 669 qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_upper = 670 pci_config_get32(qlge->pci_handle, PCI_CONF_BASE2); 671 672 qlge->pci_cfg.pci_doorbell_mem_base_address_lower = 673 pci_config_get32(qlge->pci_handle, PCI_CONF_BASE3); 674 675 qlge->pci_cfg.pci_doorbell_mem_base_address_upper = 676 pci_config_get32(qlge->pci_handle, PCI_CONF_BASE4); 677 678 qlge->pci_cfg.sub_vendor_id = (uint16_t) 679 pci_config_get16(qlge->pci_handle, PCI_CONF_SUBVENID); 680 681 qlge->pci_cfg.sub_device_id = (uint16_t) 682 pci_config_get16(qlge->pci_handle, PCI_CONF_SUBSYSID); 683 684 qlge->pci_cfg.expansion_rom = 685 pci_config_get32(qlge->pci_handle, PCI_CONF_ROM); 686 687 qlge->pci_cfg.intr_line = (uint8_t) 688 pci_config_get8(qlge->pci_handle, PCI_CONF_ILINE); 689 690 qlge->pci_cfg.intr_pin = (uint8_t) 691 pci_config_get8(qlge->pci_handle, PCI_CONF_IPIN); 692 693 qlge->pci_cfg.min_grant = (uint8_t) 694 pci_config_get8(qlge->pci_handle, PCI_CONF_MIN_G); 695 696 qlge->pci_cfg.max_latency = (uint8_t) 697 pci_config_get8(qlge->pci_handle, PCI_CONF_MAX_L); 698 699 qlge->pci_cfg.pcie_device_control = (uint16_t) 700 pci_config_get16(qlge->pci_handle, 0x54); 701 702 qlge->pci_cfg.link_status = (uint16_t) 703 pci_config_get16(qlge->pci_handle, 0x5e); 704 705 qlge->pci_cfg.msi_msg_control = (uint16_t) 706 pci_config_get16(qlge->pci_handle, 0x8a); 707 708 qlge->pci_cfg.msi_x_msg_control = (uint16_t) 709 pci_config_get16(qlge->pci_handle, 0xa2); 710 711 if (qlge->ql_dbgprnt & DBG_GLD) { 712 ql_printf("ql_dump_pci_config(%d): enter\n", 713 qlge->instance); 714 ql_printf("\tvendorid =0x%x.\n", 715 qlge->pci_cfg.vendor_id); 716 ql_printf("\tdeviceid =0x%x.\n", 717 qlge->pci_cfg.device_id); 718 ql_printf("\tcommand =0x%x.\n", 719 qlge->pci_cfg.command); 720 ql_printf("\tstatus =0x%x.\n", 721 qlge->pci_cfg.status); 722 ql_printf("\trevision id =0x%x.\n", 723 qlge->pci_cfg.revision); 724 ql_printf("\tprogram class =0x%x.\n", 725 qlge->pci_cfg.prog_class); 726 ql_printf("\tsubclass code =0x%x.\n", 727 qlge->pci_cfg.sub_class); 728 ql_printf("\tbase class code =0x%x.\n", 729 qlge->pci_cfg.base_class); 730 ql_printf("\tcache line size =0x%x.\n", 731 qlge->pci_cfg.cache_line_size); 732 ql_printf("\tlatency timer =0x%x.\n", 733 qlge->pci_cfg.latency_timer); 734 ql_printf("\theader =0x%x.\n", 735 qlge->pci_cfg.header_type); 736 ql_printf("\tI/O Base Register Address0 =0x%x.\n", 737 qlge->pci_cfg.io_base_address); 738 ql_printf("\tpci_cntl_reg_set_mem_base_address_lower =0x%x.\n", 739 qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_lower); 740 ql_printf("\tpci_cntl_reg_set_mem_base_address_upper =0x%x.\n", 741 qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_upper); 742 ql_printf("\tpci_doorbell_mem_base_address_lower =0x%x.\n", 743 qlge->pci_cfg.pci_doorbell_mem_base_address_lower); 744 ql_printf("\tpci_doorbell_mem_base_address_upper =0x%x.\n", 745 qlge->pci_cfg.pci_doorbell_mem_base_address_upper); 746 ql_printf("\tSubsytem Vendor Id =0x%x.\n", 747 qlge->pci_cfg.sub_vendor_id); 748 ql_printf("\tSubsytem Id =0x%x.\n", 749 qlge->pci_cfg.sub_device_id); 750 ql_printf("\tExpansion ROM Base Register =0x%x.\n", 751 qlge->pci_cfg.expansion_rom); 752 ql_printf("\tInterrupt Line =0x%x.\n", 753 qlge->pci_cfg.intr_line); 754 ql_printf("\tInterrupt Pin =0x%x.\n", 755 qlge->pci_cfg.intr_pin); 756 ql_printf("\tMin Grant =0x%x.\n", 757 qlge->pci_cfg.min_grant); 758 ql_printf("\tMax Grant =0x%x.\n", 759 qlge->pci_cfg.max_latency); 760 ql_printf("\tdevice_control =0x%x.\n", 761 qlge->pci_cfg.pcie_device_control); 762 ql_printf("\tlink_status =0x%x.\n", 763 qlge->pci_cfg.link_status); 764 ql_printf("\tmsi_msg_control =0x%x.\n", 765 qlge->pci_cfg.msi_msg_control); 766 ql_printf("\tmsi_x_msg_control =0x%x.\n", 767 qlge->pci_cfg.msi_x_msg_control); 768 769 ql_printf("ql_dump_pci_config(%d): exit\n", qlge->instance); 770 } 771 } 772 773 /* 774 * Print a formated string 775 */ 776 void 777 ql_printf(const char *fmt, ...) 778 { 779 va_list ap; 780 781 va_start(ap, fmt); 782 vcmn_err(CE_CONT, fmt, ap); 783 va_end(ap); 784 785 } 786 787 /* 788 * Read all control registers value and save in a string 789 */ 790 static uint32_t 791 read_ctrl_reg_set(qlge_t *qlge, caddr_t bufp) 792 { 793 int i, j; 794 uint32_t data; 795 caddr_t bp = bufp; 796 uint32_t cnt; 797 798 /* read Reg 0 -0xC4 */ 799 for (i = 0, j = 0; i <= 0xfc; i += 4) { 800 data = ql_read_reg(qlge, i); 801 (void) sprintf(bp, "Register[%x] = 0x%x\n", i, data); 802 bp += strlen(bp); 803 if (i == REG_INTERRUPT_ENABLE) { 804 /* Read */ 805 data = INTR_EN_TYPE_READ; 806 ql_write_reg(qlge, i, (data | (data << 16))); 807 data = ql_read_reg(qlge, i); 808 if (data & INTR_EN_EN) { 809 (void) sprintf(bp, "Intr0 enabled: 0x%x\n", 810 data); 811 bp += strlen(bp); 812 } else { 813 (void) sprintf(bp, "Intr0 disabled: 0x%x\n", 814 data); 815 bp += strlen(bp); 816 } 817 } 818 j++; 819 } 820 *bp = '\0'; 821 bp++; 822 cnt = (uint32_t)((uintptr_t)bp - (uintptr_t)bufp); 823 QL_PRINT(DBG_GLD, ("%s(%d) %x bytes to export\n", 824 __func__, qlge->instance, cnt)); 825 return (cnt); 826 } 827 828 /* 829 * Get address and size of image tables in flash memory 830 */ 831 static int 832 ql_get_flash_table_region_info(qlge_t *qlge, uint32_t region, uint32_t *addr, 833 uint32_t *size) 834 { 835 int rval = DDI_SUCCESS; 836 837 switch (region) { 838 case FLT_REGION_FDT: 839 *addr = ISP_8100_FDT_ADDR; 840 *size = ISP_8100_FDT_SIZE; 841 break; 842 case FLT_REGION_FLT: 843 *addr = ISP_8100_FLT_ADDR; 844 *size = ISP_8100_FLT_SIZE; 845 break; 846 case FLT_REGION_NIC_BOOT_CODE: 847 *addr = ISP_8100_NIC_BOOT_CODE_ADDR; 848 *size = ISP_8100_NIC_BOOT_CODE_SIZE; 849 break; 850 case FLT_REGION_MPI_FW_USE: 851 *addr = ISP_8100_MPI_FW_USE_ADDR; 852 *size = ISP_8100_MPI_FW_USE_SIZE; 853 break; 854 case FLT_REGION_MPI_RISC_FW: 855 *addr = ISP_8100_MPI_RISC_FW_ADDR; 856 *size = ISP_8100_MPI_RISC_FW_SIZE; 857 break; 858 case FLT_REGION_VPD0: 859 *addr = ISP_8100_VPD0_ADDR; 860 *size = ISP_8100_VPD0_SIZE; 861 break; 862 case FLT_REGION_NIC_PARAM0: 863 *addr = ISP_8100_NIC_PARAM0_ADDR; 864 *size = ISP_8100_NIC_PARAM0_SIZE; 865 break; 866 case FLT_REGION_VPD1: 867 *addr = ISP_8100_VPD1_ADDR; 868 *size = ISP_8100_VPD1_SIZE; 869 break; 870 case FLT_REGION_NIC_PARAM1: 871 *addr = ISP_8100_NIC_PARAM1_ADDR; 872 *size = ISP_8100_NIC_PARAM1_SIZE; 873 break; 874 case FLT_REGION_MPI_CFG: 875 *addr = ISP_8100_MPI_CFG_ADDR; 876 *size = ISP_8100_MPI_CFG_SIZE; 877 break; 878 case FLT_REGION_EDC_PHY_FW: 879 *addr = ISP_8100_EDC_PHY_FW_ADDR; 880 *size = ISP_8100_EDC_PHY_FW_SIZE; 881 break; 882 case FLT_REGION_FC_BOOT_CODE: 883 *addr = ISP_8100_FC_BOOT_CODE_ADDR; 884 *size = ISP_8100_FC_BOOT_CODE_SIZE; 885 break; 886 case FLT_REGION_FC_FW: 887 *addr = ISP_8100_FC_FW_ADDR; 888 *size = ISP_8100_FC_FW_SIZE; 889 break; 890 default: 891 cmn_err(CE_WARN, "%s(%d): Unknown region code %x!", 892 __func__, qlge->instance, region); 893 rval = DDI_FAILURE; 894 } 895 return (rval); 896 } 897 898 /* 899 * Get PCI bus information 900 */ 901 static int 902 ql_get_pci_bus_info(qlge_t *qlge, uint32_t *pci_bus_info_ptr) 903 { 904 dev_info_t *dip; 905 int *options; 906 unsigned int noptions; 907 int rval = DDI_FAILURE; 908 909 dip = qlge->dip; 910 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, 911 "assigned-addresses", &options, &noptions) == DDI_PROP_SUCCESS) { 912 QL_PRINT(DBG_GLD, ("%s(%d) %d options\n", 913 __func__, qlge->instance, noptions)); 914 915 if (noptions != 0) { 916 *pci_bus_info_ptr = options[0]; 917 rval = DDI_SUCCESS; 918 } 919 920 ddi_prop_free(options); 921 } 922 return (rval); 923 } 924 925 /* 926 * Build the first packet header in case that 1k+ data transfer is required 927 */ 928 void 929 build_init_pkt_header(qlge_t *qlge, ioctl_header_info_t *pheader, uint32_t size) 930 { 931 qlge->ioctl_total_length = size; 932 QL_PRINT(DBG_GLD, ("%d bytes used in kernel buffer\n", 933 qlge->ioctl_total_length)); 934 qlge->expected_trans_times = 935 (uint16_t)(qlge->ioctl_total_length / IOCTL_MAX_DATA_LEN); 936 if ((qlge->ioctl_total_length % IOCTL_MAX_DATA_LEN) != 0) 937 qlge->expected_trans_times++; 938 QL_PRINT(DBG_GLD, ("expected transer times %d \n", 939 qlge->expected_trans_times)); 940 qlge->ioctl_transferred_bytes = 0; 941 /* 942 * tell user total bytes prepare to receive in the 943 * following transactions 944 */ 945 pheader->version = 0; 946 pheader->total_length = qlge->ioctl_total_length; 947 pheader->payload_length = 0; 948 pheader->expected_trans_times = qlge->expected_trans_times; 949 } 950 951 /* 952 * Do ioctl on hardware 953 */ 954 /* ARGSUSED */ 955 enum ioc_reply 956 ql_chip_ioctl(qlge_t *qlge, queue_t *q, mblk_t *mp) 957 { 958 mblk_t *dmp; 959 int cmd, i, rval; 960 struct ql_device_reg *reg; 961 struct ql_pci_reg *pci_reg; 962 struct ql_flash_io_info *flash_io_info_ptr; 963 pci_cfg_t *pci_cfg; 964 uint32_t *pvalue; 965 struct qlnic_prop_info *prop_ptr; 966 ql_adapter_info_t *adapter_info_ptr; 967 uint16_t payload_len; 968 uint32_t remaining_bytes; 969 ioctl_header_info_t *pheader; 970 caddr_t bp, bdesc; 971 uint32_t len; 972 uint32_t addr, size, region; 973 struct iocblk *iocp = (struct iocblk *)(void *)mp->b_rptr; 974 uint16_t iltds_image_entry_regions[] = { 975 FLT_REGION_NIC_BOOT_CODE, FLT_REGION_MPI_RISC_FW, 976 FLT_REGION_EDC_PHY_FW, FLT_REGION_FC_BOOT_CODE, 977 FLT_REGION_FC_FW}; 978 ql_iltds_description_header_t *iltds_ptr; 979 ql_iltds_header_t *ql_iltds_header_ptr; 980 uint32_t offset; 981 uint16_t requested_dump; 982 983 /* 984 * There should be a M_DATA mblk following 985 * the initial M_IOCTL mblk 986 */ 987 if ((dmp = mp->b_cont) == NULL) { 988 cmn_err(CE_WARN, "%s(%d) b_count NULL", 989 __func__, qlge->instance); 990 return (IOC_INVAL); 991 } 992 993 cmd = iocp->ioc_cmd; 994 995 reg = (struct ql_device_reg *)(void *)dmp->b_rptr; 996 pci_reg = (struct ql_pci_reg *)(void *)dmp->b_rptr; 997 pvalue = (uint32_t *)(void *)dmp->b_rptr; 998 flash_io_info_ptr = (struct ql_flash_io_info *)(void *)dmp->b_rptr; 999 adapter_info_ptr = (ql_adapter_info_t *)(void *)dmp->b_rptr; 1000 1001 switch (cmd) { 1002 case QLA_GET_DBGLEAVEL: 1003 if (iocp->ioc_count != sizeof (*pvalue)) { 1004 return (IOC_INVAL); 1005 } 1006 *pvalue = qlge->ql_dbgprnt; 1007 break; 1008 1009 case QLA_SET_DBGLEAVEL: 1010 if (iocp->ioc_count != sizeof (*pvalue)) { 1011 return (IOC_INVAL); 1012 } 1013 qlge->ql_dbgprnt = *pvalue; 1014 break; 1015 1016 case QLA_WRITE_REG: 1017 if (iocp->ioc_count != sizeof (*reg)) { 1018 return (IOC_INVAL); 1019 } 1020 ql_write_reg(qlge, reg->addr, reg->value); 1021 break; 1022 1023 case QLA_READ_PCI_REG: 1024 if (iocp->ioc_count != sizeof (*pci_reg)) { 1025 return (IOC_INVAL); 1026 } 1027 /* protect against bad addr values */ 1028 if (pci_reg->addr > 0xff) 1029 return (IOC_INVAL); 1030 pci_reg->value = 1031 (uint16_t)pci_config_get16(qlge->pci_handle, 1032 pci_reg->addr); 1033 break; 1034 1035 case QLA_WRITE_PCI_REG: 1036 if (iocp->ioc_count != sizeof (*pci_reg)) { 1037 return (IOC_INVAL); 1038 } 1039 /* protect against bad addr values */ 1040 if (pci_reg->addr > 0xff) 1041 return (IOC_INVAL); 1042 pci_config_put16(qlge->pci_handle, pci_reg->addr, 1043 pci_reg->value); 1044 break; 1045 1046 case QLA_PCI_STATUS: 1047 len = (uint32_t)iocp->ioc_count; 1048 if (len != sizeof (pci_cfg_t)) { 1049 cmn_err(CE_WARN, "QLA_PCI_STATUS size error, " 1050 "driver size 0x%x not 0x%x ", 1051 (int)MBLKL(dmp), 1052 (int)sizeof (pci_cfg_t)); 1053 return (IOC_INVAL); 1054 } 1055 pci_cfg = (pci_cfg_t *)(void *)dmp->b_rptr; 1056 /* get PCI configuration */ 1057 bcopy((const void *)(&qlge->pci_cfg), 1058 (void *)pci_cfg, len); 1059 break; 1060 1061 case QLA_GET_PROP: 1062 len = (uint32_t)iocp->ioc_count; 1063 if (len != sizeof (struct qlnic_prop_info)) { 1064 cmn_err(CE_WARN, "QLA_GET_PROP size error, " 1065 "driver size 0x%x not 0x%x ", 1066 (int)MBLKL(dmp), 1067 (int)sizeof (pci_cfg_t)); 1068 return (IOC_INVAL); 1069 } 1070 prop_ptr = 1071 (struct qlnic_prop_info *)(void *)dmp->b_rptr; 1072 /* get various properties */ 1073 mutex_enter(&qlge->mbx_mutex); 1074 (void) ql_get_firmware_version(qlge, 1075 &prop_ptr->mpi_version); 1076 (void) ql_get_fw_state(qlge, &prop_ptr->fw_state); 1077 (void) qlge_get_link_status(qlge, 1078 &prop_ptr->link_status); 1079 mutex_exit(&qlge->mbx_mutex); 1080 break; 1081 1082 case QLA_LIST_ADAPTER_INFO: 1083 /* count must be exactly same */ 1084 if (iocp->ioc_count != sizeof (ql_adapter_info_t)) { 1085 return (IOC_INVAL); 1086 } 1087 if (ql_get_pci_bus_info(qlge, 1088 &(adapter_info_ptr->pci_binding)) != DDI_SUCCESS) { 1089 return (IOC_INVAL); 1090 } 1091 adapter_info_ptr->vendor_id = 1092 qlge->pci_cfg.vendor_id; 1093 adapter_info_ptr->sub_vendor_id = 1094 qlge->pci_cfg.sub_vendor_id; 1095 adapter_info_ptr->device_id = 1096 qlge->pci_cfg.device_id; 1097 adapter_info_ptr->sub_device_id = 1098 qlge->pci_cfg.sub_device_id; 1099 1100 bcopy(qlge->unicst_addr[0].addr.ether_addr_octet, 1101 &(adapter_info_ptr->cur_addr), ETHERADDRL); 1102 break; 1103 1104 case QLA_SHOW_REGION: 1105 len = (uint32_t)iocp->ioc_count; 1106 bdesc = (caddr_t)dmp->b_rptr; 1107 if (CFG_IST(qlge, CFG_CHIP_8100)) 1108 (void) sprintf(bdesc, "ISP 8100 available " 1109 "regions %s", ISP_8100_REGION); 1110 break; 1111 1112 case QLA_CONTINUE_COPY_OUT: 1113 if (qlge->ioctl_buf_ptr == NULL) 1114 return (IOC_INVAL); 1115 len = (uint32_t)iocp->ioc_count; 1116 bp = qlge->ioctl_buf_ptr; 1117 bp += qlge->ioctl_transferred_bytes; 1118 remaining_bytes = 1119 qlge->ioctl_total_length - 1120 qlge->ioctl_transferred_bytes; 1121 /* how many data bytes sent this time */ 1122 payload_len = 1123 (uint16_t)min(IOCTL_MAX_DATA_LEN, remaining_bytes); 1124 /* create packet header */ 1125 pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr; 1126 pheader->version = 0; 1127 pheader->total_length = qlge->ioctl_total_length; 1128 pheader->expected_trans_times = 1129 qlge->expected_trans_times; 1130 pheader->payload_length = payload_len; 1131 /* create packet payload */ 1132 bdesc = (caddr_t)dmp->b_rptr; 1133 bdesc += IOCTL_HEADER_LEN; 1134 bcopy(bp, bdesc, pheader->payload_length); 1135 qlge->ioctl_transferred_bytes += 1136 pheader->payload_length; 1137 QL_PRINT(DBG_GLD, ("QLA_CONTINUE_COPY_OUT, %d bytes" 1138 " exported \n", payload_len)); 1139 if (qlge->ioctl_transferred_bytes >= 1140 qlge->ioctl_total_length) { 1141 QL_PRINT(DBG_GLD, ("all data out,clean up \n")); 1142 kmem_free(qlge->ioctl_buf_ptr, 1143 qlge->ioctl_buf_lenth); 1144 qlge->ioctl_buf_ptr = NULL; 1145 qlge->ioctl_buf_lenth = 0; 1146 } 1147 iocp->ioc_count = len; 1148 break; 1149 1150 case QLA_CONTINUE_COPY_IN: 1151 if (qlge->ioctl_buf_ptr == NULL) 1152 return (IOC_INVAL); 1153 len = (uint32_t)iocp->ioc_count; 1154 bdesc = qlge->ioctl_buf_ptr; 1155 bdesc += qlge->ioctl_transferred_bytes; 1156 remaining_bytes = qlge->ioctl_total_length - 1157 qlge->ioctl_transferred_bytes; 1158 pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr; 1159 payload_len = pheader->payload_length; 1160 /* create packet header */ 1161 pheader->version = 0; 1162 pheader->total_length = qlge->ioctl_total_length; 1163 pheader->expected_trans_times = 1164 qlge->expected_trans_times; 1165 /* get packet payload */ 1166 bp = (caddr_t)dmp->b_rptr; 1167 bp += IOCTL_HEADER_LEN; 1168 bcopy(bp, bdesc, pheader->payload_length); 1169 qlge->ioctl_transferred_bytes += 1170 pheader->payload_length; 1171 QL_PRINT(DBG_GLD, ("QLA_CONTINUE_COPY_IN, %d bytes " 1172 "received \n", payload_len)); 1173 if (qlge->ioctl_transferred_bytes >= 1174 qlge->ioctl_total_length) { 1175 region = pheader->option[0]; 1176 (void) ql_get_flash_table_region_info(qlge, 1177 region, &addr, &size); 1178 QL_PRINT(DBG_GLD, ("write data to region 0x%x," 1179 " addr 0x%x, max size %d bytes\n", 1180 region, addr, size)); 1181 (void) qlge_load_flash(qlge, 1182 (uint8_t *)qlge->ioctl_buf_ptr, 1183 qlge->ioctl_transferred_bytes /* size */, 1184 addr); 1185 QL_PRINT(DBG_GLD, ("all %d data written, do " 1186 "clean up \n", 1187 qlge->ioctl_transferred_bytes)); 1188 kmem_free(qlge->ioctl_buf_ptr, 1189 qlge->ioctl_buf_lenth); 1190 qlge->ioctl_buf_ptr = NULL; 1191 qlge->ioctl_buf_lenth = 0; 1192 } 1193 iocp->ioc_count = len; 1194 break; 1195 1196 case QLA_READ_CONTRL_REGISTERS: 1197 if (qlge->ioctl_buf_ptr == NULL) { 1198 qlge->ioctl_buf_lenth = 1199 IOCTL_MAX_BUF_SIZE; /* 512k */ 1200 qlge->ioctl_buf_ptr = 1201 kmem_zalloc(qlge->ioctl_buf_lenth, 1202 KM_SLEEP); 1203 if (qlge->ioctl_buf_ptr == NULL) { 1204 cmn_err(CE_WARN, "%s(%d): Unable to " 1205 "allocate ioctl buffer", 1206 __func__, qlge->instance); 1207 return (IOC_INVAL); 1208 } 1209 } 1210 len = read_ctrl_reg_set(qlge, qlge->ioctl_buf_ptr); 1211 pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr; 1212 /* build initial ioctl packet header */ 1213 build_init_pkt_header(qlge, pheader, len); 1214 iocp->ioc_count = sizeof (*pheader); 1215 break; 1216 1217 case QLA_SUPPORTED_DUMP_TYPES: /* show available regions */ 1218 len = (uint32_t)iocp->ioc_count; 1219 bdesc = (caddr_t)dmp->b_rptr; 1220 if (CFG_IST(qlge, CFG_CHIP_8100)) 1221 (void) sprintf(bdesc, "ISP 8100 supported dump" 1222 " types: %s", ISP_8100_AVAILABLE_DUMPS); 1223 break; 1224 1225 case QLA_GET_BINARY_CORE_DUMP: 1226 len = (uint32_t)iocp->ioc_count; 1227 requested_dump = *((uint16_t *)(void *)dmp->b_rptr); 1228 rval = ql_binary_core_dump(qlge, requested_dump, &len); 1229 if (rval == DDI_SUCCESS) { 1230 pheader = 1231 (ioctl_header_info_t *)(void *)dmp->b_rptr; 1232 /* build initial ioctl packet header */ 1233 build_init_pkt_header(qlge, pheader, len); 1234 iocp->ioc_count = sizeof (*pheader); 1235 } else { 1236 cmn_err(CE_WARN, "ql_binary_core_dump error"); 1237 return (IOC_INVAL); 1238 } 1239 break; 1240 1241 case QLA_TRIGGER_SYS_ERROR_EVENT: 1242 (void) ql_trigger_system_error_event(qlge); 1243 break; 1244 1245 case QLA_READ_VPD: 1246 if (qlge->ioctl_buf_ptr == NULL) { 1247 qlge->ioctl_buf_lenth = 1248 IOCTL_MAX_BUF_SIZE; /* 512k */ 1249 qlge->ioctl_buf_ptr = 1250 kmem_zalloc(qlge->ioctl_buf_lenth, 1251 KM_SLEEP); 1252 if (qlge->ioctl_buf_ptr == NULL) { 1253 cmn_err(CE_WARN, "%s(%d): Unable to " 1254 "allocate ioctl buffer", 1255 __func__, qlge->instance); 1256 return (IOC_INVAL); 1257 } 1258 } 1259 len = (uint32_t)iocp->ioc_count; 1260 QL_PRINT(DBG_GLD, (" 0x%x user buffer available \n", 1261 len)); 1262 (void) ql_flash_vpd(qlge, 1263 (uint8_t *)qlge->ioctl_buf_ptr); 1264 pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr; 1265 /* build initial ioctl packet header */ 1266 build_init_pkt_header(qlge, pheader, 1267 ISP_8100_VPD0_SIZE); 1268 iocp->ioc_count = sizeof (*pheader); 1269 break; 1270 1271 case QLA_MANUAL_READ_FLASH: 1272 if (qlge->ioctl_buf_ptr == NULL) { 1273 qlge->ioctl_buf_lenth = 1274 IOCTL_MAX_BUF_SIZE; /* 512k */ 1275 qlge->ioctl_buf_ptr = 1276 kmem_zalloc(qlge->ioctl_buf_lenth, 1277 KM_SLEEP); 1278 if (qlge->ioctl_buf_ptr == NULL) { 1279 cmn_err(CE_WARN, "%s(%d): Unable to " 1280 "allocate ioctl buffer", 1281 __func__, qlge->instance); 1282 return (IOC_INVAL); 1283 } 1284 } 1285 len = (uint32_t)iocp->ioc_count; 1286 rval = qlge_dump_fcode(qlge, 1287 (uint8_t *)qlge->ioctl_buf_ptr, 1288 flash_io_info_ptr->size, 1289 flash_io_info_ptr->addr); 1290 if (rval != DDI_SUCCESS) { 1291 return (IOC_INVAL); 1292 } 1293 pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr; 1294 /* build initial ioctl packet header */ 1295 build_init_pkt_header(qlge, pheader, 1296 flash_io_info_ptr->size); 1297 iocp->ioc_count = sizeof (*pheader); 1298 break; 1299 1300 case QLA_READ_FLASH: 1301 if (qlge->ioctl_buf_ptr == NULL) { 1302 qlge->ioctl_buf_lenth = IOCTL_MAX_BUF_SIZE; 1303 qlge->ioctl_buf_ptr = 1304 kmem_zalloc(qlge->ioctl_buf_lenth, 1305 KM_SLEEP); 1306 if (qlge->ioctl_buf_ptr == NULL) { 1307 cmn_err(CE_WARN, "%s(%d): Unable to" 1308 "allocate ioctl buffer", 1309 __func__, qlge->instance); 1310 return (IOC_INVAL); 1311 } 1312 } 1313 len = (uint32_t)iocp->ioc_count; 1314 region = *pvalue; 1315 if (ql_get_flash_table_region_info(qlge, region, &addr, 1316 &size) != DDI_SUCCESS) 1317 return (IOC_INVAL); 1318 rval = qlge_dump_fcode(qlge, 1319 (uint8_t *)qlge->ioctl_buf_ptr, 1320 size, addr); 1321 if (rval != DDI_SUCCESS) { 1322 return (IOC_INVAL); 1323 } 1324 pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr; 1325 /* build initial ioctl packet header */ 1326 build_init_pkt_header(qlge, pheader, size); 1327 iocp->ioc_count = sizeof (*pheader); 1328 break; 1329 1330 case QLA_WRITE_FLASH: 1331 len = (uint32_t)iocp->ioc_count; 1332 pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr; 1333 region = pheader->option[0]; 1334 qlge->ioctl_buf_lenth = pheader->total_length; 1335 qlge->ioctl_total_length = pheader->total_length; 1336 qlge->expected_trans_times = 1337 pheader->expected_trans_times; 1338 qlge->ioctl_transferred_bytes = 0; 1339 if (qlge->ioctl_buf_ptr == NULL) { 1340 qlge->ioctl_buf_ptr = 1341 kmem_zalloc(qlge->ioctl_buf_lenth, 1342 KM_SLEEP); 1343 if (qlge->ioctl_buf_ptr == NULL) { 1344 cmn_err(CE_WARN, "%s(%d): Unable to " 1345 "allocate ioctl buffer", 1346 __func__, qlge->instance); 1347 return (IOC_INVAL); 1348 } 1349 } 1350 QL_PRINT(DBG_GLD, ("QLA_WRITE_FLASH write to region " 1351 "%x, total buffer size 0x%x bytes\n", 1352 region, qlge->ioctl_buf_lenth)); 1353 iocp->ioc_count = sizeof (*pheader); 1354 break; 1355 1356 case QLA_READ_FW_IMAGE: 1357 if (qlge->ioctl_buf_ptr != NULL) { 1358 kmem_free(qlge->ioctl_buf_ptr, 1359 qlge->ioctl_buf_lenth); 1360 } 1361 qlge->ioctl_buf_lenth = IOCTL_MAX_BUF_SIZE * 4; 1362 qlge->ioctl_buf_ptr = kmem_zalloc(qlge->ioctl_buf_lenth, 1363 KM_SLEEP); 1364 if (qlge->ioctl_buf_ptr == NULL) { 1365 cmn_err(CE_WARN, "%s(%d): Unable to " 1366 "allocate ioctl buffer", 1367 __func__, qlge->instance); 1368 return (IOC_INVAL); 1369 } 1370 len = (uint32_t)iocp->ioc_count; 1371 iltds_ptr = (ql_iltds_description_header_t *) 1372 (void *)qlge->ioctl_buf_ptr; 1373 iltds_ptr->iltds_table_header.signature = 1374 FLASH_ILTDS_SIGNATURE; 1375 iltds_ptr->iltds_table_header.table_version = 1; 1376 iltds_ptr->iltds_table_header.length = 1377 ILTDS_DESCRIPTION_HEADERS_LEN; 1378 iltds_ptr->iltds_table_header.number_entries = 1379 IMAGE_TABLE_IMAGE_DEFAULT_ENTRIES + 1380 1 /* timestamp */; 1381 iltds_ptr->iltds_table_header.reserved = 0; 1382 iltds_ptr->iltds_table_header.version = 1; 1383 /* where is the flash data saved */ 1384 bdesc = qlge->ioctl_buf_ptr + 1385 ILTDS_DESCRIPTION_HEADERS_LEN; 1386 offset = iltds_ptr->iltds_table_header.length; 1387 for (i = 0; i < IMAGE_TABLE_IMAGE_DEFAULT_ENTRIES; 1388 i++) { 1389 region = iltds_image_entry_regions[i]; 1390 if (ql_get_flash_table_region_info(qlge, 1391 region, &addr, &size) != DDI_SUCCESS) 1392 return (IOC_INVAL); 1393 QL_PRINT(DBG_GLD, ("region %x addr 0x%x, 0x%x " 1394 "bytes\n", region, addr, size)); 1395 /* Dump one image entry */ 1396 rval = qlge_dump_fcode(qlge, (uint8_t *)bdesc, 1397 size, addr); 1398 if (rval != DDI_SUCCESS) { 1399 return (IOC_INVAL); 1400 } 1401 bdesc += size; 1402 iltds_ptr->img_entry[i].region_type = 1403 (uint16_t)region; 1404 iltds_ptr->img_entry[i].region_version_len = 0; 1405 iltds_ptr->img_entry[i].region_version[0] = 0; 1406 iltds_ptr->img_entry[i].region_version[1] = 0; 1407 iltds_ptr->img_entry[i].region_version[2] = 0; 1408 iltds_ptr->img_entry[i].offset_lo = LSW(offset); 1409 iltds_ptr->img_entry[i].offset_hi = MSW(offset); 1410 iltds_ptr->img_entry[i].size_lo = LSW(size); 1411 iltds_ptr->img_entry[i].size_hi = MSW(size); 1412 iltds_ptr->img_entry[i].swap_mode = 0; 1413 iltds_ptr->img_entry[i].card_type = 0; 1414 QL_PRINT(DBG_GLD, ("image offset %x size %x " 1415 "bytes\n", offset, size)); 1416 QL_PRINT(DBG_GLD, ("offset %x lsw %x msw %x" 1417 " \n", offset, LSW(offset), MSW(offset))); 1418 offset += size; 1419 } 1420 /* Last entry */ 1421 iltds_ptr->time_stamp.region_type = 1422 FLT_REGION_TIME_STAMP; 1423 iltds_ptr->time_stamp.region_version_len = 0; 1424 iltds_ptr->time_stamp.region_version[0] = 0; 1425 iltds_ptr->time_stamp.region_version[1] = 0; 1426 iltds_ptr->time_stamp.region_version[2] = 0; 1427 iltds_ptr->time_stamp.year = 0x09; 1428 iltds_ptr->time_stamp.month = 0x01; 1429 iltds_ptr->time_stamp.day = 0x20; 1430 iltds_ptr->time_stamp.hour = 0x14; 1431 iltds_ptr->time_stamp.min = 0x20; 1432 iltds_ptr->time_stamp.sec = 0x50; 1433 1434 pheader = (ioctl_header_info_t *)(void *)dmp->b_rptr; 1435 /* build initial ioctl packet header */ 1436 build_init_pkt_header(qlge, pheader, offset); 1437 iocp->ioc_count = sizeof (*pheader); 1438 break; 1439 1440 case QLA_WRITE_FW_IMAGE_HEADERS: 1441 len = (uint32_t)iocp->ioc_count; 1442 if (len == 0) 1443 return (IOC_INVAL); 1444 ql_iltds_header_ptr = 1445 (ql_iltds_header_t *)(void *)dmp->b_rptr; 1446 if (len != ql_iltds_header_ptr->length) { 1447 cmn_err(CE_WARN, "QLA_WRITE_FW_IMAGE_HEADERS " 1448 "data length error!" 1449 " %x bytes expected, %x received", 1450 ql_iltds_header_ptr->length, len); 1451 return (IOC_INVAL); 1452 } 1453 QL_PRINT(DBG_GLD, ("Fw Image header len 0x%x bytes, " 1454 "0x%x entries\n", 1455 len, ql_iltds_header_ptr->number_entries)); 1456 ql_dump_buf("all copy in data:\n", 1457 (uint8_t *)dmp->b_rptr, 8, len); 1458 mp->b_cont = NULL; 1459 break; 1460 1461 case QLA_SOFT_RESET: 1462 iocp->ioc_count = 0; 1463 ql_wake_asic_reset_soft_intr(qlge); 1464 QL_PRINT(DBG_GLD, ("QLA_SOFT_RESET started \n")); 1465 break; 1466 1467 default: 1468 return (IOC_INVAL); 1469 } 1470 1471 return (IOC_REPLY); 1472 } 1473 1474 /* 1475 * Loopback ioctl code 1476 */ 1477 static lb_property_t loopmodes[] = { 1478 { normal, "normal", QLGE_LOOP_NONE }, 1479 { internal, "parallel", QLGE_LOOP_INTERNAL_PARALLEL }, 1480 { internal, "serial", QLGE_LOOP_INTERNAL_SERIAL }, 1481 { external, "phy", QLGE_LOOP_EXTERNAL_PHY } 1482 }; 1483 1484 /* 1485 * Set Loopback mode 1486 */ 1487 static enum ioc_reply 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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