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