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 (void) 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 (void) 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 (void) ql_read_mailbox_cmd(qlge, &qlge->received_mbx_cmds, 668 qlge->max_read_mbx); 669 670 /* 671 * process PI interrupt as async events, if not done, 672 * then pass to mailbox processing 673 */ 674 if (ql_async_event_parser(qlge, &qlge->received_mbx_cmds) == B_FALSE) { 675 QL_PRINT(DBG_MBX, ("%s(%d) mailbox completion interrupt\n", 676 __func__, qlge->instance)); 677 /* 678 * If another thread is waiting for the mail box 679 * completion event to occur 680 */ 681 if (qlge->mbx_wait_completion == 1) { 682 qlge->mbx_wait_completion = 0; 683 cv_broadcast(&qlge->cv_mbx_intr); 684 QL_PRINT(DBG_MBX, 685 ("%s(%d) mailbox completion signaled \n", 686 __func__, qlge->instance)); 687 } 688 } 689 /* inform MPI Firmware to clear the interrupt */ 690 ql_write_reg(qlge, REG_HOST_CMD_STATUS, 691 HOST_CMD_CLEAR_RISC_TO_HOST_INTR /* 0x0A */); 692 mutex_exit(&qlge->mbx_mutex); 693 ql_enable_completion_interrupt(qlge, 0); /* MPI is on irq 0 */ 694 } 695 696 /* 697 * Test if mailbox communication works 698 * This is used when Interrupt is not enabled 699 */ 700 int 701 ql_mbx_test(qlge_t *qlge) 702 { 703 mbx_cmd_t mbx_cmds; 704 mbx_data_t mbx_results; 705 int i, test_ok = 1; 706 int rtn_val = DDI_FAILURE; 707 708 for (i = 0; i < NUM_MAILBOX_REGS; i++) 709 mbx_cmds.mb[i] = i; 710 711 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */ 712 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) { 713 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.", 714 __func__, qlge->instance); 715 goto out; 716 } 717 718 /* delay for the processor interrupt is received */ 719 if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmds.timeout) 720 == DDI_SUCCESS) { 721 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received", 722 __func__, qlge->instance)); 723 (void) ql_read_mailbox_cmd(qlge, &mbx_results, 0); 724 725 ql_write_reg(qlge, REG_HOST_CMD_STATUS, 726 HOST_CMD_CLEAR_RISC_TO_HOST_INTR); 727 728 if (mbx_results.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 729 test_ok = 0; 730 } else { 731 for (i = 1; i < NUM_MAILBOX_REGS; i++) { 732 if (mbx_results.mb[i] != i) { 733 test_ok = 0; 734 break; 735 } 736 } 737 } 738 if (test_ok) { 739 rtn_val = DDI_SUCCESS; 740 } else { 741 cmn_err(CE_WARN, "%s(%d) mailbox test failed!", 742 __func__, qlge->instance); 743 } 744 } else { 745 cmn_err(CE_WARN, "%s(%d) mailbox testing error: " 746 "PI Intr not received ", __func__, qlge->instance); 747 } 748 out: 749 return (rtn_val); 750 } 751 752 /* 753 * ql_mbx_test2 754 * Test if mailbox communication works 755 * This is used when Interrupt is enabled 756 * mailbox cmd:0x06h 757 */ 758 int 759 ql_mbx_test2(qlge_t *qlge) 760 { 761 mbx_cmd_t mbx_cmds = {0}; 762 int i, test_ok = 1; 763 int rtn_val = DDI_FAILURE; 764 765 for (i = 0; i < NUM_MAILBOX_REGS; i++) 766 mbx_cmds.mb[i] = i; 767 768 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */ 769 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 770 cmn_err(CE_WARN, 771 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 772 __func__, qlge->instance); 773 goto out; 774 } 775 776 /* verify if the incoming outbound mailbox value is what we just sent */ 777 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 778 test_ok = 0; 779 } else { 780 for (i = 1; i < qlge->max_read_mbx; i++) { 781 if (mbx_cmds.mb[i] != i) { 782 test_ok = 0; 783 break; 784 } 785 } 786 } 787 if (test_ok) { 788 rtn_val = DDI_SUCCESS; 789 } else { 790 cmn_err(CE_WARN, "%s(%d) mailbox test failed!", 791 __func__, qlge->instance); 792 } 793 out: 794 return (rtn_val); 795 } 796 797 /* 798 * ql_get_fw_state 799 * Get fw state. 800 * mailbox cmd:0x69h 801 */ 802 int 803 ql_get_fw_state(qlge_t *qlge, uint32_t *fw_state_ptr) 804 { 805 int rtn_val = DDI_FAILURE; 806 mbx_cmd_t mbx_cmds = {0}; 807 808 mbx_cmds.mb[0] = MBC_GET_FIRMWARE_STATE; 809 810 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 811 != DDI_SUCCESS) { 812 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 813 " failed.", __func__, qlge->instance); 814 goto out; 815 } 816 /* verify if the transaction is completed successful */ 817 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 818 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", 819 __func__, qlge->instance, mbx_cmds.mb[0]); 820 } else { 821 /* EMPTY */ 822 QL_PRINT(DBG_MBX, ("firmware state: 0x%x\n", mbx_cmds.mb[1])); 823 } 824 if (fw_state_ptr != NULL) 825 *fw_state_ptr = mbx_cmds.mb[1]; 826 rtn_val = DDI_SUCCESS; 827 out: 828 return (rtn_val); 829 } 830 831 /* 832 * ql_set_IDC_Req 833 * Send a IDC Request to firmware to notify all functions 834 * or any specific functions on the same port 835 * mailbox cmd:0x100h 836 */ 837 int 838 ql_set_IDC_Req(qlge_t *qlge, uint8_t dest_functions, uint8_t timeout) 839 { 840 int rtn_val = DDI_FAILURE; 841 mbx_cmd_t mbx_cmds = {0}; 842 843 mbx_cmds.mb[0] = MBC_IDC_REQUEST /* 0x100 */; 844 mbx_cmds.mb[1] = (timeout<<8) | qlge->func_number; 845 846 switch (dest_functions) { 847 case IDC_REQ_DEST_FUNC_ALL: 848 mbx_cmds.mb[1] |= IDC_REQ_ALL_DEST_FUNC_MASK; 849 mbx_cmds.mb[2] = 0; 850 break; 851 case IDC_REQ_DEST_FUNC_0: 852 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_0_MASK; 853 break; 854 case IDC_REQ_DEST_FUNC_1: 855 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_1_MASK; 856 break; 857 case IDC_REQ_DEST_FUNC_2: 858 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_2_MASK; 859 break; 860 case IDC_REQ_DEST_FUNC_3: 861 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_3_MASK; 862 break; 863 default: 864 cmn_err(CE_WARN, "Wrong dest functions %x", 865 dest_functions); 866 } 867 868 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 869 cmn_err(CE_WARN, 870 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 871 __func__, qlge->instance); 872 goto out; 873 } 874 /* verify if the transaction is completed successful */ 875 if (mbx_cmds.mb[0] == MBA_IDC_INTERMEDIATE_COMPLETE /* 0x1000 */) { 876 QL_PRINT(DBG_MBX, ("%s(%d) mbx1: 0x%x, mbx2: 0x%x\n", 877 __func__, qlge->instance, mbx_cmds.mb[1], mbx_cmds.mb[2])); 878 rtn_val = DDI_SUCCESS; 879 } else if (mbx_cmds.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) { 880 QL_PRINT(DBG_MBX, ("%s(%d) cmd sent succesfully 0x%x\n", 881 __func__, qlge->instance)); 882 rtn_val = DDI_SUCCESS; 883 } else if (mbx_cmds.mb[0] == MBS_COMMAND_ERROR /* 0x4005 */) { 884 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_ERROR", 885 __func__, qlge->instance); 886 } else if (mbx_cmds.mb[0] == MBS_COMMAND_PARAMETER_ERROR /* 0x4006 */) { 887 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_PARAMETER_ERROR", 888 __func__, qlge->instance); 889 } else { 890 cmn_err(CE_WARN, "%s(%d) unknow result: mbx[0]: 0x%x; mbx[1]:" 891 " 0x%x; mbx[2]: 0x%x", __func__, qlge->instance, 892 mbx_cmds.mb[0], mbx_cmds.mb[1], mbx_cmds.mb[2]); 893 } 894 895 out: 896 return (rtn_val); 897 } 898 899 /* 900 * ql_set_mpi_port_config 901 * Send new port configuration.to mpi 902 * mailbox cmd:0x122h 903 */ 904 static int 905 ql_set_mpi_port_config(qlge_t *qlge, port_cfg_info_t new_cfg) 906 { 907 int rtn_val = DDI_FAILURE; 908 mbx_cmd_t mbx_cmds = {0}; 909 910 mbx_cmds.mb[0] = MBC_SET_PORT_CONFIG /* 0x122 */; 911 mbx_cmds.mb[1] = new_cfg.link_cfg; 912 mbx_cmds.mb[2] = new_cfg.max_frame_size; 913 914 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 915 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 916 " failed.", __func__, qlge->instance); 917 goto out; 918 } 919 /* verify if the transaction is completed successful */ 920 if ((mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) && 921 (mbx_cmds.mb[0] != MBA_IDC_COMPLETE /* 0x8100 */)) { 922 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", 923 __func__, qlge->instance, mbx_cmds.mb[0]); 924 } else 925 rtn_val = DDI_SUCCESS; 926 out: 927 return (rtn_val); 928 } 929 930 /* 931 * ql_set_port_cfg 932 * Set new port configuration 933 */ 934 int 935 ql_set_port_cfg(qlge_t *qlge) 936 { 937 uint32_t loop_back_bit_mask = 0x0e; /* bit 1-3 */ 938 uint32_t pause_bit_mask = 0x60; /* bit 5-6 */ 939 940 /* clear pause bits */ 941 qlge->port_cfg_info.link_cfg &= ~pause_bit_mask; 942 /* clear loop back bits */ 943 qlge->port_cfg_info.link_cfg &= ~loop_back_bit_mask; 944 /* set new pause mode */ 945 if (qlge->pause == PAUSE_MODE_STANDARD) 946 qlge->port_cfg_info.link_cfg |= STD_PAUSE; 947 else if (qlge->pause == PAUSE_MODE_PER_PRIORITY) 948 qlge->port_cfg_info.link_cfg |= PP_PAUSE; 949 950 /* loop back cfg: bit1-3 */ 951 if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_PARALLEL) 952 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_PARALLEL; 953 else if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_SERIAL) 954 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_SERIAL; 955 956 /* max frame size */ 957 if (qlge->mtu == ETHERMTU) { 958 qlge->port_cfg_info.link_cfg &= ~ENABLE_JUMBO; 959 qlge->port_cfg_info.max_frame_size = NORMAL_FRAME_SIZE; 960 } else { 961 qlge->port_cfg_info.link_cfg |= ENABLE_JUMBO; 962 qlge->port_cfg_info.max_frame_size = JUMBO_FRAME_SIZE; 963 } 964 965 return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info)); 966 967 } 968 969 /* 970 * ql_get_port_cfg 971 * Get port configuration. 972 * mailbox cmd:0x123h 973 */ 974 int 975 ql_get_port_cfg(qlge_t *qlge) 976 { 977 int rtn_val = DDI_FAILURE; 978 mbx_cmd_t mbx_cmds = {0}; 979 980 mbx_cmds.mb[0] = MBC_GET_PORT_CONFIG /* 0x123 */; 981 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 982 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 983 " failed.", __func__, qlge->instance); 984 goto out; 985 } 986 /* verify if the transaction is completed successfully */ 987 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 988 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", 989 __func__, qlge->instance, mbx_cmds.mb[0]); 990 } else { /* verify frame size */ 991 if ((mbx_cmds.mb[2] == NORMAL_FRAME_SIZE) || 992 (mbx_cmds.mb[2] == JUMBO_FRAME_SIZE)) { 993 qlge->port_cfg_info.link_cfg = mbx_cmds.mb[1]; 994 qlge->port_cfg_info.max_frame_size = mbx_cmds.mb[2]; 995 QL_PRINT(DBG_MBX, ("link_cfg: 0x%x, max_frame_size:" 996 " %d bytes\n", mbx_cmds.mb[1], mbx_cmds.mb[2])); 997 rtn_val = DDI_SUCCESS; 998 } else { 999 cmn_err(CE_WARN, "bad link_cfg: 0x%x, max_frame_size:" 1000 " %d bytes", mbx_cmds.mb[1], mbx_cmds.mb[2]); 1001 } 1002 } 1003 out: 1004 return (rtn_val); 1005 } 1006 1007 /* 1008 * qlge_get_link_status 1009 * Get link status. 1010 * mailbox cmd:0x124h 1011 */ 1012 int 1013 qlge_get_link_status(qlge_t *qlge, 1014 struct qlnic_link_status_info *link_status_ptr) 1015 { 1016 int rtn_val = DDI_FAILURE; 1017 mbx_cmd_t mbx_cmds = {0}; 1018 1019 mbx_cmds.mb[0] = MBC_GET_LINK_STATUS /* 0x124 */; 1020 1021 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 1022 != DDI_SUCCESS) { 1023 cmn_err(CE_WARN, 1024 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 1025 __func__, qlge->instance); 1026 goto out; 1027 } 1028 /* verify if the transaction is completed successful */ 1029 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1030 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", __func__, 1031 qlge->instance, mbx_cmds.mb[0]); 1032 } else { 1033 /* EMPTY */ 1034 QL_PRINT(DBG_MBX, 1035 ("link status: status1 : 0x%x, status2 : 0x%x, " 1036 "status3 : 0x%x\n", 1037 mbx_cmds.mb[1], mbx_cmds.mb[2], mbx_cmds.mb[3])); 1038 } 1039 if (link_status_ptr != NULL) { 1040 link_status_ptr->link_status_info = mbx_cmds.mb[1]; 1041 link_status_ptr->additional_info = mbx_cmds.mb[2]; 1042 link_status_ptr->network_hw_info = mbx_cmds.mb[3]; 1043 link_status_ptr->dcbx_frame_counters_info = mbx_cmds.mb[4]; 1044 link_status_ptr->change_counters_info = mbx_cmds.mb[5]; 1045 } 1046 rtn_val = DDI_SUCCESS; 1047 out: 1048 1049 return (rtn_val); 1050 } 1051 1052 /* 1053 * ql_get_firmware_version 1054 * Get firmware version. 1055 */ 1056 int 1057 ql_get_firmware_version(qlge_t *qlge, 1058 struct qlnic_mpi_version_info *mpi_version_ptr) 1059 { 1060 int rtn_val = DDI_FAILURE; 1061 mbx_cmd_t mbx_cmds = {0}; 1062 1063 mbx_cmds.mb[0] = MBC_ABOUT_FIRMWARE /* 0x08 */; 1064 1065 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 1066 != DDI_SUCCESS) { 1067 cmn_err(CE_WARN, 1068 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 1069 __func__, qlge->instance); 1070 goto out; 1071 } 1072 1073 /* verify if the transaction is completed successful */ 1074 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1075 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", __func__, 1076 qlge->instance, mbx_cmds.mb[0]); 1077 } else { 1078 qlge->fw_version_info.major_version = 1079 LSB(MSW(mbx_cmds.mb[1])); 1080 qlge->fw_version_info.minor_version = 1081 MSB(LSW(mbx_cmds.mb[1])); 1082 qlge->fw_version_info.sub_minor_version = 1083 LSB(LSW(mbx_cmds.mb[1])); 1084 qlge->phy_version_info.major_version = 1085 LSB(MSW(mbx_cmds.mb[2])); 1086 qlge->phy_version_info.minor_version = 1087 MSB(LSW(mbx_cmds.mb[2])); 1088 qlge->phy_version_info.sub_minor_version = 1089 LSB(LSW(mbx_cmds.mb[2])); 1090 #ifdef QLGE_LOAD_UNLOAD 1091 cmn_err(CE_NOTE, "firmware version: %d.%d.%d\n", 1092 qlge->fw_version_info.major_version, 1093 qlge->fw_version_info.minor_version, 1094 qlge->fw_version_info.sub_minor_version); 1095 #endif 1096 if (mpi_version_ptr != NULL) { 1097 mpi_version_ptr->fw_version = 1098 (qlge->fw_version_info.major_version<<16) 1099 |(qlge->fw_version_info.minor_version<<8) 1100 |(qlge->fw_version_info.sub_minor_version); 1101 mpi_version_ptr->phy_version = 1102 (qlge->phy_version_info.major_version<<16) 1103 |(qlge->phy_version_info.minor_version<<8) 1104 |(qlge->phy_version_info.sub_minor_version); 1105 } 1106 } 1107 rtn_val = DDI_SUCCESS; 1108 out: 1109 return (rtn_val); 1110 } 1111 1112 /* 1113 * Trigger a system error event 1114 */ 1115 int 1116 ql_trigger_system_error_event(qlge_t *qlge) 1117 { 1118 mbx_cmd_t mbx_cmds = {0}; 1119 int rtn_val = DDI_FAILURE; 1120 1121 mbx_cmds.mb[0] = MBC_GENERATE_SYS_ERROR; /* 0x2A */ 1122 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) { 1123 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.", 1124 __func__, qlge->instance); 1125 goto out; 1126 } 1127 rtn_val = DDI_SUCCESS; 1128 out: 1129 return (rtn_val); 1130 } 1131 1132 /* 1133 * Reset the MPI RISC Processor 1134 */ 1135 int 1136 ql_reset_mpi_risc(qlge_t *qlge) 1137 { 1138 int rtn_val = DDI_FAILURE; 1139 1140 /* Reset the MPI Processor */ 1141 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_RESET); 1142 if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS, RISC_RESET, 1143 BIT_SET, 0) != DDI_SUCCESS) { 1144 (void) ql_read_reg(qlge, REG_HOST_CMD_STATUS); 1145 goto out; 1146 } 1147 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_CLEAR_RISC_RESET); 1148 rtn_val = DDI_SUCCESS; 1149 out: 1150 return (rtn_val); 1151 } 1152 1153 int 1154 ql_read_risc_ram(qlge_t *qlge, uint32_t risc_address, uint64_t bp, 1155 uint32_t word_count) 1156 { 1157 int rval = DDI_FAILURE; 1158 mbx_cmd_t mc = {0}; 1159 mbx_cmd_t *mcp = &mc; 1160 mbx_data_t mbx_results; 1161 1162 QL_PRINT(DBG_MBX, ("%s(%d): read risc addr:0x%x," 1163 "phys_addr %x,%x words\n", __func__, qlge->instance, 1164 risc_address, bp, word_count)); 1165 if (CFG_IST(qlge, CFG_CHIP_8100)) { 1166 mcp->mb[0] = MBC_DUMP_RISC_RAM /* 0x0C */; 1167 mcp->mb[1] = LSW(risc_address); 1168 mcp->mb[2] = MSW(LSD(bp)); 1169 mcp->mb[3] = LSW(LSD(bp)); 1170 mcp->mb[4] = MSW(word_count); 1171 mcp->mb[5] = LSW(word_count); 1172 mcp->mb[6] = MSW(MSD(bp)); 1173 mcp->mb[7] = LSW(MSD(bp)); 1174 mcp->mb[8] = MSW(risc_address); 1175 } 1176 mcp->timeout = 10 /* MAILBOX_TOV */; 1177 1178 if (ql_issue_mailbox_cmd_and_poll_rsp(qlge, mcp, &mbx_results) 1179 != DDI_SUCCESS) { 1180 goto out; 1181 } else { 1182 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received", 1183 __func__, qlge->instance)); 1184 if (mbx_results.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) { 1185 QL_PRINT(DBG_MBX, ("%s(%d): success\n", 1186 __func__, qlge->instance)); 1187 rval = DDI_SUCCESS; 1188 } else { 1189 cmn_err(CE_WARN, "%s(%d): failed , status %x", 1190 __func__, qlge->instance, mbx_results.mb[0]); 1191 } 1192 } 1193 out: 1194 return (rval); 1195 } 1196