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 int ql_async_event_parser(qlge_t *, mbx_data_t *); 29 30 /* 31 * Wait upto timeout seconds for Processor Interrupt 32 * if timeout is 0, then wait for default waittime 33 */ 34 static int 35 ql_poll_processor_intr(qlge_t *qlge, uint8_t timeout) 36 { 37 int rtn_val = DDI_SUCCESS; 38 39 if (ql_wait_reg_bit(qlge, REG_STATUS, STS_PI, BIT_SET, timeout) 40 != DDI_SUCCESS) { 41 cmn_err(CE_WARN, "Polling for processor interrupt failed."); 42 rtn_val = DDI_FAILURE; 43 } 44 return (rtn_val); 45 } 46 47 /* 48 * Wait for mailbox Processor Register Ready 49 */ 50 static int 51 ql_wait_processor_addr_reg_ready(qlge_t *qlge) 52 { 53 int rtn_val = DDI_SUCCESS; 54 55 if (ql_wait_reg_bit(qlge, REG_PROCESSOR_ADDR, 56 PROCESSOR_ADDRESS_RDY, BIT_SET, 0) != DDI_SUCCESS) { 57 cmn_err(CE_WARN, 58 "Wait for processor address register ready timeout."); 59 rtn_val = DDI_FAILURE; 60 } 61 return (rtn_val); 62 } 63 64 /* 65 * Read and write MPI registers using the indirect register interface 66 * Assume all the locks&semaphore have been acquired 67 */ 68 int 69 ql_write_processor_data(qlge_t *qlge, uint32_t addr, uint32_t data) 70 { 71 int rtn_val = DDI_FAILURE; 72 73 /* wait for processor address register ready */ 74 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE) 75 goto out; 76 /* write the data to the data reg */ 77 ql_write_reg(qlge, REG_PROCESSOR_DATA, data); 78 /* trigger the write */ 79 ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr); 80 /* wait for register to come ready */ 81 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE) 82 goto out; 83 84 rtn_val = DDI_SUCCESS; 85 86 out: 87 return (rtn_val); 88 89 } 90 91 /* 92 * Read from processor register 93 */ 94 int 95 ql_read_processor_data(qlge_t *qlge, uint32_t addr, uint32_t *data) 96 { 97 int rtn_val = DDI_FAILURE; 98 99 /* enable read operation */ 100 addr |= PROCESSOR_ADDRESS_READ; 101 /* wait for processor address register ready */ 102 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE) 103 goto out; 104 105 /* Write read address, wait for data ready in Data register */ 106 ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr); 107 /* wait for data ready */ 108 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE) 109 goto out; 110 /* read data */ 111 *data = ql_read_reg(qlge, REG_PROCESSOR_DATA); 112 113 rtn_val = DDI_SUCCESS; 114 115 out: 116 return (rtn_val); 117 118 } 119 120 /* 121 * Read "count" number of outgoing Mailbox register starting 122 * from mailbox #0 if count is 0 then read all mailboxes 123 */ 124 static int 125 ql_read_mailbox_cmd(qlge_t *qlge, mbx_data_t *mbx_buf, uint32_t count) 126 { 127 int rtn_val = DDI_FAILURE; 128 uint32_t reg_status; 129 uint32_t addr; 130 int i; 131 132 if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) { 133 cmn_err(CE_WARN, 134 "%s(%d) get QL_PROCESSOR_SEM_MASK time out error", 135 __func__, qlge->instance); 136 return (DDI_FAILURE); 137 } 138 139 if (qlge->func_number == qlge->fn0_net) 140 addr = FUNC_0_OUT_MAILBOX_0_REG_OFFSET; 141 else 142 addr = FUNC_1_OUT_MAILBOX_0_REG_OFFSET; 143 144 if (count == 0) 145 count = NUM_MAILBOX_REGS; 146 for (i = 0; i < count; i++) { 147 if (ql_read_processor_data(qlge, addr, ®_status) 148 == DDI_FAILURE) 149 goto out; 150 QL_PRINT(DBG_MBX, ("%s(%d) mailbox %d value 0x%x\n", 151 __func__, qlge->instance, i, reg_status)); 152 mbx_buf->mb[i] = reg_status; 153 addr ++; 154 } 155 156 rtn_val = DDI_SUCCESS; 157 158 out: 159 ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK); 160 161 return (rtn_val); 162 163 } 164 165 /* 166 * Write mail box command (upto 16) to MPI Firmware 167 */ 168 int 169 ql_issue_mailbox_cmd(qlge_t *qlge, mbx_cmd_t *mbx_cmd) 170 { 171 int rtn_val = DDI_FAILURE; 172 uint32_t addr; 173 int i; 174 /* 175 * Get semaphore to access Processor Address and 176 * Processor Data Registers 177 */ 178 if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) { 179 return (DDI_FAILURE); 180 } 181 /* ensure no overwriting current command */ 182 if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS, 183 HOST_TO_MPI_INTR_NOT_DONE, BIT_RESET, 0) != DDI_SUCCESS) { 184 goto out; 185 } 186 187 if (qlge->func_number == qlge->fn0_net) 188 addr = FUNC_0_IN_MAILBOX_0_REG_OFFSET; 189 else 190 addr = FUNC_1_IN_MAILBOX_0_REG_OFFSET; 191 192 /* wait for mailbox registers to be ready to access */ 193 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE) 194 goto out; 195 196 /* issue mailbox command one by one */ 197 for (i = 0; i < NUM_MAILBOX_REGS; i++) { 198 /* write sending cmd to mailbox data register */ 199 ql_write_reg(qlge, REG_PROCESSOR_DATA, mbx_cmd->mb[i]); 200 /* write mailbox address to address register */ 201 ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr); 202 QL_PRINT(DBG_MBX, ("%s(%d) write %x to mailbox(%x) addr %x \n", 203 __func__, qlge->instance, mbx_cmd->mb[i], i, addr)); 204 addr++; 205 /* 206 * wait for mailbox cmd to be written before 207 * next write can start 208 */ 209 if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE) 210 goto out; 211 } 212 /* inform MPI that new mailbox commands are available */ 213 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_INTR); 214 rtn_val = DDI_SUCCESS; 215 out: 216 ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK); 217 return (rtn_val); 218 } 219 220 /* 221 * Send mail box command (upto 16) to MPI Firmware 222 * and polling for MPI mailbox completion response when 223 * interrupt is not enabled. 224 * The MBX_LOCK mutexe should have been held and released 225 * externally 226 */ 227 int 228 ql_issue_mailbox_cmd_and_poll_rsp(qlge_t *qlge, mbx_cmd_t *mbx_cmd, 229 mbx_data_t *p_results) 230 { 231 int rtn_val = DDI_FAILURE; 232 boolean_t done; 233 int max_wait; 234 235 if (mbx_cmd == NULL) 236 goto err; 237 238 rtn_val = ql_issue_mailbox_cmd(qlge, mbx_cmd); 239 if (rtn_val != DDI_SUCCESS) { 240 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd failed", 241 __func__, qlge->instance); 242 goto err; 243 } 244 done = B_FALSE; 245 max_wait = 5; /* wait upto 5 PI interrupt */ 246 /* delay for the processor interrupt is received */ 247 while ((done != B_TRUE) && (max_wait--)) { 248 /* wait up to 5s for PI interrupt */ 249 if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmd->timeout) 250 == DDI_SUCCESS) { 251 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received", 252 __func__, qlge->instance)); 253 ql_read_mailbox_cmd(qlge, p_results, 0); 254 /* 255 * Sometimes, the incoming messages is not what we are 256 * waiting for, ie. async events, then, continue to 257 * wait. If it is the result * of previous mailbox 258 * command, then Done. No matter what, send 259 * HOST_CMD_CLEAR_RISC_TO_HOST_INTR to clear each 260 * PI interrupt 261 */ 262 if (ql_async_event_parser(qlge, p_results) == B_FALSE) { 263 /* 264 * we get what we are waiting for, 265 * clear the interrupt 266 */ 267 rtn_val = DDI_SUCCESS; 268 done = B_TRUE; 269 } else { 270 /*EMPTY*/ 271 QL_PRINT(DBG_MBX, 272 ("%s(%d) result ignored, not we wait for\n", 273 __func__, qlge->instance)); 274 } 275 ql_write_reg(qlge, REG_HOST_CMD_STATUS, 276 HOST_CMD_CLEAR_RISC_TO_HOST_INTR); 277 } else { /* timeout */ 278 done = B_TRUE; 279 } 280 rtn_val = DDI_SUCCESS; 281 } 282 err: 283 return (rtn_val); 284 } 285 /* 286 * Send mail box command (upto 16) to MPI Firmware 287 * and wait for MPI mailbox completion response which 288 * is saved in interrupt. Thus, this function can only 289 * be used after interrupt is enabled. 290 * Must hold MBX mutex before calling this function 291 */ 292 static int 293 ql_issue_mailbox_cmd_and_wait_rsp(qlge_t *qlge, mbx_cmd_t *mbx_cmd) 294 { 295 int rtn_val = DDI_FAILURE; 296 clock_t timer; 297 int i; 298 int done = 0; 299 300 if (mbx_cmd == NULL) 301 goto err; 302 303 ASSERT(mutex_owned(&qlge->mbx_mutex)); 304 305 /* if interrupts are not enabled, poll when results are available */ 306 if (!(qlge->flags & INTERRUPTS_ENABLED)) { 307 rtn_val = ql_issue_mailbox_cmd_and_poll_rsp(qlge, mbx_cmd, 308 &qlge->received_mbx_cmds); 309 if (rtn_val == DDI_SUCCESS) { 310 for (i = 0; i < NUM_MAILBOX_REGS; i++) 311 mbx_cmd->mb[i] = qlge->received_mbx_cmds.mb[i]; 312 } 313 } else { 314 rtn_val = ql_issue_mailbox_cmd(qlge, mbx_cmd); 315 if (rtn_val != DDI_SUCCESS) { 316 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd failed", 317 __func__, qlge->instance); 318 goto err; 319 } 320 qlge->mbx_wait_completion = 1; 321 while (!done && qlge->mbx_wait_completion && !ddi_in_panic()) { 322 /* default 5 seconds from now to timeout */ 323 timer = ddi_get_lbolt(); 324 if (mbx_cmd->timeout) { 325 timer += 326 mbx_cmd->timeout * drv_usectohz(1000000); 327 } else { 328 timer += 5 * drv_usectohz(1000000); 329 } 330 if (cv_timedwait(&qlge->cv_mbx_intr, &qlge->mbx_mutex, 331 timer) == -1) { 332 /* 333 * The timeout time 'timer' was 334 * reached or expired without the condition 335 * being signaled. 336 */ 337 cmn_err(CE_WARN, "%s(%d) Wait for Mailbox cmd " 338 "complete timeout.", 339 __func__, qlge->instance); 340 rtn_val = DDI_FAILURE; 341 done = 1; 342 } else { 343 QL_PRINT(DBG_MBX, 344 ("%s(%d) mailbox completion signal received" 345 " \n", __func__, qlge->instance)); 346 for (i = 0; i < NUM_MAILBOX_REGS; i++) { 347 mbx_cmd->mb[i] = 348 qlge->received_mbx_cmds.mb[i]; 349 } 350 rtn_val = DDI_SUCCESS; 351 done = 1; 352 } 353 } 354 } 355 err: 356 return (rtn_val); 357 } 358 359 /* 360 * Inteprete incoming asynchronous events 361 */ 362 static int 363 ql_async_event_parser(qlge_t *qlge, mbx_data_t *mbx_cmds) 364 { 365 uint32_t link_status, cmd; 366 uint8_t link_speed; 367 uint8_t link_type; 368 boolean_t proc_done = B_TRUE; 369 mbx_cmd_t reply_cmd = {0}; 370 371 switch (mbx_cmds->mb[0]) { 372 case MBA_IDC_INTERMEDIATE_COMPLETE /* 1000h */: 373 QL_PRINT(DBG_MBX, ("%s(%d):" 374 "MBA_IDC_INTERMEDIATE_COMPLETE received\n", 375 __func__, qlge->instance)); 376 break; 377 case MBA_SYSTEM_ERR /* 8002h */: 378 cmn_err(CE_WARN, "%s(%d): MBA_SYSTEM_ERR received", 379 __func__, qlge->instance); 380 cmn_err(CE_WARN, "%s(%d): File id %x, Line # %x," 381 "Firmware Ver# %x", 382 __func__, qlge->instance, mbx_cmds->mb[1], 383 mbx_cmds->mb[2], mbx_cmds->mb[3]); 384 ql_8xxx_binary_core_dump(qlge, &qlge->ql_mpi_coredump); 385 break; 386 case MBA_LINK_UP /* 8011h */: 387 QL_PRINT(DBG_MBX, ("%s(%d): MBA_LINK_UP received\n", 388 __func__, qlge->instance)); 389 link_status = mbx_cmds->mb[1]; 390 QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n", 391 __func__, qlge->instance, link_status)); 392 link_speed = (uint8_t)((link_status >> 3) & 0x07); 393 394 if (link_speed == 0) { 395 qlge->speed = SPEED_100; 396 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 100M\n", 397 __func__, qlge->instance)); 398 } else if (link_speed == 1) { 399 qlge->speed = SPEED_1000; 400 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 1G\n", 401 __func__, qlge->instance)); 402 } else if (link_speed == 2) { 403 qlge->speed = SPEED_10G; 404 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 10G\n", 405 __func__, qlge->instance)); 406 } 407 408 qlge->link_type = link_type = (uint8_t)(link_status & 0x07); 409 410 if (link_type == XFI_NETWORK_INTERFACE) { 411 /* EMPTY */ 412 QL_PRINT(DBG_MBX, 413 ("%s(%d):Link type XFI_NETWORK_INTERFACE\n", 414 __func__, qlge->instance)); 415 } else if (link_type == XAUI_NETWORK_INTERFACE) { 416 /* EMPTY */ 417 QL_PRINT(DBG_MBX, ("%s(%d):Link type" 418 "XAUI_NETWORK_INTERFACE\n", 419 __func__, qlge->instance)); 420 } else if (link_type == XFI_BACKPLANE_INTERFACE) { 421 /* EMPTY */ 422 QL_PRINT(DBG_MBX, ("%s(%d):Link type" 423 "XFI_BACKPLANE_INTERFACE\n", 424 __func__, qlge->instance)); 425 } else if (link_type == XAUI_BACKPLANE_INTERFACE) { 426 /* EMPTY */ 427 QL_PRINT(DBG_MBX, ("%s(%d):Link type " 428 "XAUI_BACKPLANE_INTERFACE\n", 429 __func__, qlge->instance)); 430 } else if (link_type == EXT_10GBASE_T_PHY) { 431 /* EMPTY */ 432 QL_PRINT(DBG_MBX, 433 ("%s(%d):Link type EXT_10GBASE_T_PHY\n", 434 __func__, qlge->instance)); 435 } else if (link_type == EXT_EXT_EDC_PHY) { 436 /* EMPTY */ 437 QL_PRINT(DBG_MBX, 438 ("%s(%d):Link type EXT_EXT_EDC_PHY\n", 439 __func__, qlge->instance)); 440 } else { 441 /* EMPTY */ 442 QL_PRINT(DBG_MBX, 443 ("%s(%d):unknown Link type \n", 444 __func__, qlge->instance)); 445 } 446 447 cmn_err(CE_NOTE, "mpi link up! link_status %x \n", link_status); 448 /* 449 * start timer if not started to delay some time then 450 * check if link is really up or down 451 */ 452 ql_restart_timer(qlge); 453 454 break; 455 case MBA_LINK_DOWN /* 8012h */: 456 QL_PRINT(DBG_MBX, 457 ("%s(%d): MBA_LINK_DOWN received\n", 458 __func__, qlge->instance)); 459 460 link_status = mbx_cmds->mb[1]; 461 462 QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n", 463 __func__, qlge->instance, link_status)); 464 if (link_status & 0x1) { 465 /* EMPTY */ 466 QL_PRINT(DBG_MBX, ("%s(%d): Loss of signal \n", 467 __func__, qlge->instance)); 468 } 469 if (link_status & 0x2) { 470 /* EMPTY */ 471 QL_PRINT(DBG_MBX, 472 ("%s(%d): Auto-Negotiation Failed \n", 473 __func__, qlge->instance)); 474 } 475 if (link_status & 0x4) { 476 /* EMPTY */ 477 QL_PRINT(DBG_MBX, 478 ("%s(%d): XTI-Training Failed \n", 479 __func__, qlge->instance)); 480 } 481 482 cmn_err(CE_NOTE, "mpi link down! link_status %x \n", 483 link_status); 484 ql_restart_timer(qlge); 485 break; 486 case MBA_IDC_COMPLETE /* 8100h */: 487 488 QL_PRINT(DBG_MBX, 489 ("%s(%d): MBA_IDC_COMPLETE received\n", 490 __func__, qlge->instance)); 491 cmd = mbx_cmds->mb[1]; 492 if (cmd == MBC_STOP_FIRMWARE) { 493 /* EMPTY */ 494 QL_PRINT(DBG_MBX, 495 ("%s(%d): STOP_FIRMWARE event completed\n", 496 __func__, qlge->instance)); 497 } else if (cmd == MBC_IDC_REQUEST) { 498 /* EMPTY */ 499 QL_PRINT(DBG_MBX, 500 ("%s(%d): IDC_REQUEST event completed\n", 501 __func__, qlge->instance)); 502 } else if (cmd == MBC_PORT_RESET) { 503 /* EMPTY */ 504 QL_PRINT(DBG_MBX, 505 ("%s(%d): PORT_RESET event completed\n", 506 __func__, qlge->instance)); 507 } else if (cmd == MBC_SET_PORT_CONFIG) { 508 /* EMPTY */ 509 QL_PRINT(DBG_MBX, 510 ("%s(%d): SET_PORT_CONFIG event " 511 "completed\n", __func__, qlge->instance)); 512 } else { 513 /* EMPTY */ 514 QL_PRINT(DBG_MBX, 515 ("%s(%d): unknown IDC completion request" 516 " event %x %x\n", __func__, qlge->instance, 517 mbx_cmds->mb[1], mbx_cmds->mb[2])); 518 } 519 proc_done = B_FALSE; 520 break; 521 522 case MBA_IDC_REQUEST_NOTIFICATION /* 8101h */: 523 QL_PRINT(DBG_MBX, 524 ("%s(%d): MBA_IDC_REQUEST_NOTIFICATION " 525 "received\n", __func__, qlge->instance)); 526 cmd = mbx_cmds->mb[1]; 527 if (cmd == MBC_STOP_FIRMWARE) { 528 /* EMPTY */ 529 QL_PRINT(DBG_MBX, 530 ("%s(%d): STOP_FIRMWARE notification" 531 " received\n", __func__, qlge->instance)); 532 } else if (cmd == MBC_IDC_REQUEST) { 533 /* EMPTY */ 534 QL_PRINT(DBG_MBX, 535 ("%s(%d): IDC_REQUEST notification " 536 "received\n", __func__, qlge->instance)); 537 } else if (cmd == MBC_PORT_RESET) { 538 /* EMPTY */ 539 QL_PRINT(DBG_MBX, ("%s(%d): PORT_RESET " 540 "notification received\n", 541 __func__, qlge->instance)); 542 } else if (cmd == MBC_SET_PORT_CONFIG) { 543 /* EMPTY */ 544 QL_PRINT(DBG_MBX, 545 ("%s(%d): SET_PORT_CONFIG notification " 546 "received\n", __func__, qlge->instance)); 547 } else { 548 /* EMPTY */ 549 QL_PRINT(DBG_MBX, ("%s(%d): " 550 "unknown request received %x %x\n", 551 __func__, qlge->instance, mbx_cmds->mb[1], 552 mbx_cmds->mb[2])); 553 } 554 reply_cmd.mb[0] = MBC_IDC_ACK; 555 reply_cmd.mb[1] = mbx_cmds->mb[1]; 556 reply_cmd.mb[2] = mbx_cmds->mb[2]; 557 reply_cmd.mb[3] = mbx_cmds->mb[3]; 558 reply_cmd.mb[4] = mbx_cmds->mb[4]; 559 if (ql_issue_mailbox_cmd(qlge, &reply_cmd) 560 != DDI_SUCCESS) { 561 cmn_err(CE_WARN, 562 "%s(%d) send IDC Ack failed.", 563 __func__, qlge->instance); 564 } 565 /* 566 * verify if the incoming outbound mailbox value is what 567 * we just sent 568 */ 569 if (mbx_cmds->mb[0] == MBS_COMMAND_COMPLETE) { 570 /* 0x4000 */ 571 /* EMPTY */ 572 QL_PRINT(DBG_MBX, 573 ("%s(%d): IDC Ack sent success.\n", 574 __func__, qlge->instance)); 575 } else { 576 /* EMPTY */ 577 QL_PRINT(DBG_MBX, 578 ("%s(%d): IDC Ack reply error %x %x %x.\n", 579 __func__, qlge->instance, mbx_cmds->mb[0], 580 mbx_cmds->mb[1], mbx_cmds->mb[2])); 581 } 582 break; 583 case MBA_IDC_TIME_EXTENDED /* 8102 */: 584 QL_PRINT(DBG_MBX, 585 ("%s(%d): MBA_IDC_TIME_EXTENDED received\n", 586 __func__, qlge->instance)); 587 break; 588 case MBA_DCBX_CONFIG_CHANGE /* 8110 */: 589 QL_PRINT(DBG_MBX, 590 ("%s(%d): MBA_DCBX_CONFIG_CHANGE received\n", 591 __func__, qlge->instance)); 592 break; 593 case MBA_NOTIFICATION_LOST /* 8120 */: 594 QL_PRINT(DBG_MBX, 595 ("%s(%d): MBA_NOTIFICATION_LOST received\n", 596 __func__, qlge->instance)); 597 break; 598 case MBA_SFT_TRANSCEIVER_INSERTION /* 8130 */: 599 QL_PRINT(DBG_MBX, 600 ("%s(%d): MBA_SFT_TRANSCEIVER_INSERTION " 601 "received\n", __func__, qlge->instance)); 602 break; 603 case MBA_SFT_TRANSCEIVER_REMOVAL /* 8140 */: 604 QL_PRINT(DBG_MBX, 605 ("%s(%d): MBA_SFT_TRANSCEIVER_REMOVAL " 606 "received\n", __func__, qlge->instance)); 607 break; 608 case MBA_FIRMWARE_INIT_COMPLETE /* 8400 */: 609 QL_PRINT(DBG_MBX, 610 ("%s(%d): MBA_FIRMWARE_INIT_COMPLETE " 611 "received\n", __func__, qlge->instance)); 612 QL_PRINT(DBG_MBX, 613 ("%s(%d): mbx[1] %x, mbx[2] %x\n", __func__, 614 qlge->instance, mbx_cmds->mb[1], mbx_cmds->mb[2])); 615 qlge->fw_init_complete = B_TRUE; 616 qlge->fw_version_info.major_version = 617 LSB(MSW(mbx_cmds->mb[1])); 618 qlge->fw_version_info.minor_version = 619 MSB(LSW(mbx_cmds->mb[1])); 620 qlge->fw_version_info.sub_minor_version = 621 LSB(LSW(mbx_cmds->mb[1])); 622 qlge->phy_version_info.major_version = 623 LSB(MSW(mbx_cmds->mb[2])); 624 qlge->phy_version_info.minor_version = 625 MSB(LSW(mbx_cmds->mb[2])); 626 qlge->phy_version_info.sub_minor_version = 627 LSB(LSW(mbx_cmds->mb[2])); 628 break; 629 case MBA_FIRMWARE_INIT_FAILED /* 8401 */: 630 cmn_err(CE_WARN, "%s(%d):" 631 "ASYNC_EVENT_FIRMWARE_INIT_FAILURE " 632 "received: mbx[1] %x, mbx[2] %x", 633 __func__, qlge->instance, 634 mbx_cmds->mb[1], mbx_cmds->mb[2]); 635 break; 636 default: 637 if (mbx_cmds->mb[0] > 0x8000) { 638 cmn_err(CE_WARN, "%s(%d): " 639 "Unknown Async event received: mbx[0] %x ," 640 "mbx[1] %x; mbx[2] %x", 641 __func__, qlge->instance, 642 mbx_cmds->mb[0], mbx_cmds->mb[1], 643 mbx_cmds->mb[2]); 644 proc_done = B_TRUE; 645 } else { 646 proc_done = B_FALSE; 647 } 648 break; 649 } 650 return (proc_done); 651 } 652 653 654 /* 655 * MPI Interrupt handler 656 * Caller must have MBX_LOCK 657 */ 658 void 659 ql_do_mpi_intr(qlge_t *qlge) 660 { 661 /* 662 * we just need to read first few mailboxes that this adapter's MPI 663 * will write response to. 664 */ 665 mutex_enter(&qlge->mbx_mutex); 666 667 ql_read_mailbox_cmd(qlge, &qlge->received_mbx_cmds, qlge->max_read_mbx); 668 669 /* 670 * process PI interrupt as async events, if not done, 671 * then pass to mailbox processing 672 */ 673 if (ql_async_event_parser(qlge, &qlge->received_mbx_cmds) == B_FALSE) { 674 QL_PRINT(DBG_MBX, ("%s(%d) mailbox completion interrupt\n", 675 __func__, qlge->instance)); 676 /* 677 * If another thread is waiting for the mail box 678 * completion event to occur 679 */ 680 if (qlge->mbx_wait_completion == 1) { 681 qlge->mbx_wait_completion = 0; 682 cv_broadcast(&qlge->cv_mbx_intr); 683 QL_PRINT(DBG_MBX, 684 ("%s(%d) mailbox completion signaled \n", 685 __func__, qlge->instance)); 686 } 687 } 688 /* inform MPI Firmware to clear the interrupt */ 689 ql_write_reg(qlge, REG_HOST_CMD_STATUS, 690 HOST_CMD_CLEAR_RISC_TO_HOST_INTR /* 0x0A */); 691 mutex_exit(&qlge->mbx_mutex); 692 ql_enable_completion_interrupt(qlge, 0); /* MPI is on irq 0 */ 693 } 694 695 /* 696 * Test if mailbox communication works 697 * This is used when Interrupt is not enabled 698 */ 699 int 700 ql_mbx_test(qlge_t *qlge) 701 { 702 mbx_cmd_t mbx_cmds; 703 mbx_data_t mbx_results; 704 int i, test_ok = 1; 705 int rtn_val = DDI_FAILURE; 706 707 for (i = 0; i < NUM_MAILBOX_REGS; i++) 708 mbx_cmds.mb[i] = i; 709 710 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */ 711 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) { 712 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.", 713 __func__, qlge->instance); 714 goto out; 715 } 716 717 /* delay for the processor interrupt is received */ 718 if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmds.timeout) 719 == DDI_SUCCESS) { 720 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received", 721 __func__, qlge->instance)); 722 ql_read_mailbox_cmd(qlge, &mbx_results, 0); 723 724 ql_write_reg(qlge, REG_HOST_CMD_STATUS, 725 HOST_CMD_CLEAR_RISC_TO_HOST_INTR); 726 727 if (mbx_results.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 728 test_ok = 0; 729 } else { 730 for (i = 1; i < NUM_MAILBOX_REGS; i++) { 731 if (mbx_results.mb[i] != i) { 732 test_ok = 0; 733 break; 734 } 735 } 736 } 737 if (test_ok) { 738 rtn_val = DDI_SUCCESS; 739 } else { 740 cmn_err(CE_WARN, "%s(%d) mailbox test failed!", 741 __func__, qlge->instance); 742 } 743 } else { 744 cmn_err(CE_WARN, "%s(%d) mailbox testing error: " 745 "PI Intr not received ", __func__, qlge->instance); 746 } 747 out: 748 return (rtn_val); 749 } 750 751 /* 752 * ql_mbx_test2 753 * Test if mailbox communication works 754 * This is used when Interrupt is enabled 755 * mailbox cmd:0x06h 756 */ 757 int 758 ql_mbx_test2(qlge_t *qlge) 759 { 760 mbx_cmd_t mbx_cmds = {0}; 761 int i, test_ok = 1; 762 int rtn_val = DDI_FAILURE; 763 764 for (i = 0; i < NUM_MAILBOX_REGS; i++) 765 mbx_cmds.mb[i] = i; 766 767 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */ 768 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 769 cmn_err(CE_WARN, 770 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 771 __func__, qlge->instance); 772 goto out; 773 } 774 775 /* verify if the incoming outbound mailbox value is what we just sent */ 776 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 777 test_ok = 0; 778 } else { 779 for (i = 1; i < qlge->max_read_mbx; i++) { 780 if (mbx_cmds.mb[i] != i) { 781 test_ok = 0; 782 break; 783 } 784 } 785 } 786 if (test_ok) { 787 rtn_val = DDI_SUCCESS; 788 } else { 789 cmn_err(CE_WARN, "%s(%d) mailbox test failed!", 790 __func__, qlge->instance); 791 } 792 out: 793 return (rtn_val); 794 } 795 796 /* 797 * ql_get_fw_state 798 * Get fw state. 799 * mailbox cmd:0x69h 800 */ 801 int 802 ql_get_fw_state(qlge_t *qlge, uint32_t *fw_state_ptr) 803 { 804 int rtn_val = DDI_FAILURE; 805 mbx_cmd_t mbx_cmds = {0}; 806 807 mbx_cmds.mb[0] = MBC_GET_FIRMWARE_STATE; 808 809 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 810 != DDI_SUCCESS) { 811 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 812 " failed.", __func__, qlge->instance); 813 goto out; 814 } 815 /* verify if the transaction is completed successful */ 816 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 817 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", 818 __func__, qlge->instance, mbx_cmds.mb[0]); 819 } else { 820 /* EMPTY */ 821 QL_PRINT(DBG_MBX, ("firmware state: 0x%x\n", mbx_cmds.mb[1])); 822 } 823 if (fw_state_ptr != NULL) 824 *fw_state_ptr = mbx_cmds.mb[1]; 825 rtn_val = DDI_SUCCESS; 826 out: 827 return (rtn_val); 828 } 829 830 /* 831 * ql_set_IDC_Req 832 * Send a IDC Request to firmware to notify all functions 833 * or any specific functions on the same port 834 * mailbox cmd:0x100h 835 */ 836 int 837 ql_set_IDC_Req(qlge_t *qlge, uint8_t dest_functions, uint8_t timeout) 838 { 839 int rtn_val = DDI_FAILURE; 840 mbx_cmd_t mbx_cmds = {0}; 841 842 mbx_cmds.mb[0] = MBC_IDC_REQUEST /* 0x100 */; 843 mbx_cmds.mb[1] = (timeout<<8) | qlge->func_number; 844 845 switch (dest_functions) { 846 case IDC_REQ_DEST_FUNC_ALL: 847 mbx_cmds.mb[1] |= IDC_REQ_ALL_DEST_FUNC_MASK; 848 mbx_cmds.mb[2] = 0; 849 break; 850 case IDC_REQ_DEST_FUNC_0: 851 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_0_MASK; 852 break; 853 case IDC_REQ_DEST_FUNC_1: 854 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_1_MASK; 855 break; 856 case IDC_REQ_DEST_FUNC_2: 857 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_2_MASK; 858 break; 859 case IDC_REQ_DEST_FUNC_3: 860 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_3_MASK; 861 break; 862 default: 863 cmn_err(CE_WARN, "Wrong dest functions %x", 864 dest_functions); 865 } 866 867 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 868 cmn_err(CE_WARN, 869 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 870 __func__, qlge->instance); 871 goto out; 872 } 873 /* verify if the transaction is completed successful */ 874 if (mbx_cmds.mb[0] == MBA_IDC_INTERMEDIATE_COMPLETE /* 0x1000 */) { 875 QL_PRINT(DBG_MBX, ("%s(%d) mbx1: 0x%x, mbx2: 0x%x\n", 876 __func__, qlge->instance, mbx_cmds.mb[1], mbx_cmds.mb[2])); 877 rtn_val = DDI_SUCCESS; 878 } else if (mbx_cmds.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) { 879 QL_PRINT(DBG_MBX, ("%s(%d) cmd sent succesfully 0x%x\n", 880 __func__, qlge->instance)); 881 rtn_val = DDI_SUCCESS; 882 } else if (mbx_cmds.mb[0] == MBS_COMMAND_ERROR /* 0x4005 */) { 883 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_ERROR", 884 __func__, qlge->instance); 885 } else if (mbx_cmds.mb[0] == MBS_COMMAND_PARAMETER_ERROR /* 0x4006 */) { 886 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_PARAMETER_ERROR", 887 __func__, qlge->instance); 888 } else { 889 cmn_err(CE_WARN, "%s(%d) unknow result: mbx[0]: 0x%x; mbx[1]:" 890 " 0x%x; mbx[2]: 0x%x", __func__, qlge->instance, 891 mbx_cmds.mb[0], mbx_cmds.mb[1], mbx_cmds.mb[2]); 892 } 893 894 out: 895 return (rtn_val); 896 } 897 898 /* 899 * ql_set_mpi_port_config 900 * Send new port configuration.to mpi 901 * mailbox cmd:0x122h 902 */ 903 static int 904 ql_set_mpi_port_config(qlge_t *qlge, port_cfg_info_t new_cfg) 905 { 906 int rtn_val = DDI_FAILURE; 907 mbx_cmd_t mbx_cmds = {0}; 908 909 mbx_cmds.mb[0] = MBC_SET_PORT_CONFIG /* 0x122 */; 910 mbx_cmds.mb[1] = new_cfg.link_cfg; 911 mbx_cmds.mb[2] = new_cfg.max_frame_size; 912 913 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 914 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 915 " failed.", __func__, qlge->instance); 916 goto out; 917 } 918 /* verify if the transaction is completed successful */ 919 if ((mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) && 920 (mbx_cmds.mb[0] != MBA_IDC_COMPLETE /* 0x8100 */)) { 921 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", 922 __func__, qlge->instance, mbx_cmds.mb[0]); 923 } else 924 rtn_val = DDI_SUCCESS; 925 out: 926 return (rtn_val); 927 } 928 929 /* 930 * ql_set_port_cfg 931 * Set new port configuration 932 */ 933 int 934 ql_set_port_cfg(qlge_t *qlge) 935 { 936 uint32_t loop_back_bit_mask = 0x0e; /* bit 1-3 */ 937 uint32_t pause_bit_mask = 0x60; /* bit 5-6 */ 938 939 /* clear pause bits */ 940 qlge->port_cfg_info.link_cfg &= ~pause_bit_mask; 941 /* clear loop back bits */ 942 qlge->port_cfg_info.link_cfg &= ~loop_back_bit_mask; 943 /* set new pause mode */ 944 if (qlge->pause == PAUSE_MODE_STANDARD) 945 qlge->port_cfg_info.link_cfg |= STD_PAUSE; 946 else if (qlge->pause == PAUSE_MODE_PER_PRIORITY) 947 qlge->port_cfg_info.link_cfg |= PP_PAUSE; 948 949 /* loop back cfg: bit1-3 */ 950 if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_PARALLEL) 951 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_PARALLEL; 952 else if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_SERIAL) 953 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_SERIAL; 954 955 /* max frame size */ 956 if (qlge->mtu == ETHERMTU) { 957 qlge->port_cfg_info.link_cfg &= ~ENABLE_JUMBO; 958 qlge->port_cfg_info.max_frame_size = NORMAL_FRAME_SIZE; 959 } else { 960 qlge->port_cfg_info.link_cfg |= ENABLE_JUMBO; 961 qlge->port_cfg_info.max_frame_size = JUMBO_FRAME_SIZE; 962 } 963 964 return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info)); 965 966 } 967 968 /* 969 * ql_get_port_cfg 970 * Get port configuration. 971 * mailbox cmd:0x123h 972 */ 973 int 974 ql_get_port_cfg(qlge_t *qlge) 975 { 976 int rtn_val = DDI_FAILURE; 977 mbx_cmd_t mbx_cmds = {0}; 978 979 mbx_cmds.mb[0] = MBC_GET_PORT_CONFIG /* 0x123 */; 980 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 981 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 982 " failed.", __func__, qlge->instance); 983 goto out; 984 } 985 /* verify if the transaction is completed successfully */ 986 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 987 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", 988 __func__, qlge->instance, mbx_cmds.mb[0]); 989 } else { /* verify frame size */ 990 if ((mbx_cmds.mb[2] == NORMAL_FRAME_SIZE) || 991 (mbx_cmds.mb[2] == JUMBO_FRAME_SIZE)) { 992 qlge->port_cfg_info.link_cfg = mbx_cmds.mb[1]; 993 qlge->port_cfg_info.max_frame_size = mbx_cmds.mb[2]; 994 QL_PRINT(DBG_MBX, ("link_cfg: 0x%x, max_frame_size:" 995 " %d bytes\n", mbx_cmds.mb[1], mbx_cmds.mb[2])); 996 rtn_val = DDI_SUCCESS; 997 } else { 998 cmn_err(CE_WARN, "bad link_cfg: 0x%x, max_frame_size:" 999 " %d bytes", mbx_cmds.mb[1], mbx_cmds.mb[2]); 1000 } 1001 } 1002 out: 1003 return (rtn_val); 1004 } 1005 1006 /* 1007 * qlge_get_link_status 1008 * Get link status. 1009 * mailbox cmd:0x124h 1010 */ 1011 int 1012 qlge_get_link_status(qlge_t *qlge, 1013 struct qlnic_link_status_info *link_status_ptr) 1014 { 1015 int rtn_val = DDI_FAILURE; 1016 mbx_cmd_t mbx_cmds = {0}; 1017 1018 mbx_cmds.mb[0] = MBC_GET_LINK_STATUS /* 0x124 */; 1019 1020 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 1021 != DDI_SUCCESS) { 1022 cmn_err(CE_WARN, 1023 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 1024 __func__, qlge->instance); 1025 goto out; 1026 } 1027 /* verify if the transaction is completed successful */ 1028 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1029 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", __func__, 1030 qlge->instance, mbx_cmds.mb[0]); 1031 } else { 1032 /* EMPTY */ 1033 QL_PRINT(DBG_MBX, 1034 ("link status: status1 : 0x%x, status2 : 0x%x, " 1035 "status3 : 0x%x\n", 1036 mbx_cmds.mb[1], mbx_cmds.mb[2], mbx_cmds.mb[3])); 1037 } 1038 if (link_status_ptr != NULL) { 1039 link_status_ptr->link_status_info = mbx_cmds.mb[1]; 1040 link_status_ptr->additional_info = mbx_cmds.mb[2]; 1041 link_status_ptr->network_hw_info = mbx_cmds.mb[3]; 1042 link_status_ptr->dcbx_frame_counters_info = mbx_cmds.mb[4]; 1043 link_status_ptr->change_counters_info = mbx_cmds.mb[5]; 1044 } 1045 rtn_val = DDI_SUCCESS; 1046 out: 1047 1048 return (rtn_val); 1049 } 1050 1051 /* 1052 * ql_get_firmware_version 1053 * Get firmware version. 1054 */ 1055 int 1056 ql_get_firmware_version(qlge_t *qlge, 1057 struct qlnic_mpi_version_info *mpi_version_ptr) 1058 { 1059 int rtn_val = DDI_FAILURE; 1060 mbx_cmd_t mbx_cmds = {0}; 1061 1062 mbx_cmds.mb[0] = MBC_ABOUT_FIRMWARE /* 0x08 */; 1063 1064 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 1065 != DDI_SUCCESS) { 1066 cmn_err(CE_WARN, 1067 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 1068 __func__, qlge->instance); 1069 goto out; 1070 } 1071 1072 /* verify if the transaction is completed successful */ 1073 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1074 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", __func__, 1075 qlge->instance, mbx_cmds.mb[0]); 1076 } else { 1077 qlge->fw_version_info.major_version = 1078 LSB(MSW(mbx_cmds.mb[1])); 1079 qlge->fw_version_info.minor_version = 1080 MSB(LSW(mbx_cmds.mb[1])); 1081 qlge->fw_version_info.sub_minor_version = 1082 LSB(LSW(mbx_cmds.mb[1])); 1083 qlge->phy_version_info.major_version = 1084 LSB(MSW(mbx_cmds.mb[2])); 1085 qlge->phy_version_info.minor_version = 1086 MSB(LSW(mbx_cmds.mb[2])); 1087 qlge->phy_version_info.sub_minor_version = 1088 LSB(LSW(mbx_cmds.mb[2])); 1089 #ifdef QLGE_LOAD_UNLOAD 1090 cmn_err(CE_NOTE, "firmware version: %d.%d.%d\n", 1091 qlge->fw_version_info.major_version, 1092 qlge->fw_version_info.minor_version, 1093 qlge->fw_version_info.sub_minor_version); 1094 #endif 1095 if (mpi_version_ptr != NULL) { 1096 mpi_version_ptr->fw_version = 1097 (qlge->fw_version_info.major_version<<16) 1098 |(qlge->fw_version_info.minor_version<<8) 1099 |(qlge->fw_version_info.sub_minor_version); 1100 mpi_version_ptr->phy_version = 1101 (qlge->phy_version_info.major_version<<16) 1102 |(qlge->phy_version_info.minor_version<<8) 1103 |(qlge->phy_version_info.sub_minor_version); 1104 } 1105 } 1106 rtn_val = DDI_SUCCESS; 1107 out: 1108 return (rtn_val); 1109 } 1110 1111 /* 1112 * Trigger a system error event 1113 */ 1114 int 1115 ql_trigger_system_error_event(qlge_t *qlge) 1116 { 1117 mbx_cmd_t mbx_cmds = {0}; 1118 int rtn_val = DDI_FAILURE; 1119 1120 mbx_cmds.mb[0] = MBC_GENERATE_SYS_ERROR; /* 0x2A */ 1121 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) { 1122 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.", 1123 __func__, qlge->instance); 1124 goto out; 1125 } 1126 rtn_val = DDI_SUCCESS; 1127 out: 1128 return (rtn_val); 1129 } 1130 1131 /* 1132 * Reset the MPI RISC Processor 1133 */ 1134 int 1135 ql_reset_mpi_risc(qlge_t *qlge) 1136 { 1137 int rtn_val = DDI_FAILURE; 1138 1139 /* Reset the MPI Processor */ 1140 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_RESET); 1141 if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS, RISC_RESET, 1142 BIT_SET, 0) != DDI_SUCCESS) { 1143 ql_read_reg(qlge, REG_HOST_CMD_STATUS); 1144 goto out; 1145 } 1146 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_CLEAR_RISC_RESET); 1147 rtn_val = DDI_SUCCESS; 1148 out: 1149 return (rtn_val); 1150 } 1151 1152 int 1153 ql_read_risc_ram(qlge_t *qlge, uint32_t risc_address, uint64_t bp, 1154 uint32_t word_count) 1155 { 1156 int rval = DDI_FAILURE; 1157 mbx_cmd_t mc = {0}; 1158 mbx_cmd_t *mcp = &mc; 1159 mbx_data_t mbx_results; 1160 1161 QL_PRINT(DBG_MBX, ("%s(%d): read risc addr:0x%x," 1162 "phys_addr %x,%x words\n", __func__, qlge->instance, 1163 risc_address, bp, word_count)); 1164 if (CFG_IST(qlge, CFG_CHIP_8100)) { 1165 mcp->mb[0] = MBC_DUMP_RISC_RAM /* 0x0C */; 1166 mcp->mb[1] = LSW(risc_address); 1167 mcp->mb[2] = MSW(LSD(bp)); 1168 mcp->mb[3] = LSW(LSD(bp)); 1169 mcp->mb[4] = MSW(word_count); 1170 mcp->mb[5] = LSW(word_count); 1171 mcp->mb[6] = MSW(MSD(bp)); 1172 mcp->mb[7] = LSW(MSD(bp)); 1173 mcp->mb[8] = MSW(risc_address); 1174 } 1175 mcp->timeout = 10 /* MAILBOX_TOV */; 1176 1177 if (ql_issue_mailbox_cmd_and_poll_rsp(qlge, mcp, &mbx_results) 1178 != DDI_SUCCESS) { 1179 goto out; 1180 } else { 1181 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received", 1182 __func__, qlge->instance)); 1183 if (mbx_results.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) { 1184 QL_PRINT(DBG_MBX, ("%s(%d): success\n", 1185 __func__, qlge->instance)); 1186 rval = DDI_SUCCESS; 1187 } else { 1188 cmn_err(CE_WARN, "%s(%d): failed , status %x", 1189 __func__, qlge->instance, mbx_results.mb[0]); 1190 } 1191 } 1192 out: 1193 return (rval); 1194 } 1195