1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 QLogic Corporation. All rights reserved. 24 */ 25 26 #include <qlge.h> 27 28 static 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 += drv_sectohz(mbx_cmd->timeout); 326 } else { 327 timer += drv_sectohz(5); 328 } 329 if (cv_timedwait(&qlge->cv_mbx_intr, &qlge->mbx_mutex, 330 timer) == -1) { 331 /* 332 * The timeout time 'timer' was 333 * reached or expired without the condition 334 * being signaled. 335 */ 336 cmn_err(CE_WARN, "%s(%d) Wait for Mailbox cmd " 337 "complete timeout.", 338 __func__, qlge->instance); 339 rtn_val = DDI_FAILURE; 340 done = 1; 341 } else { 342 QL_PRINT(DBG_MBX, 343 ("%s(%d) mailbox completion signal received" 344 " \n", __func__, qlge->instance)); 345 for (i = 0; i < NUM_MAILBOX_REGS; i++) { 346 mbx_cmd->mb[i] = 347 qlge->received_mbx_cmds.mb[i]; 348 } 349 rtn_val = DDI_SUCCESS; 350 done = 1; 351 } 352 } 353 } 354 err: 355 return (rtn_val); 356 } 357 358 /* 359 * Inteprete incoming asynchronous events 360 */ 361 static int 362 ql_async_event_parser(qlge_t *qlge, mbx_data_t *mbx_cmds) 363 { 364 uint32_t link_status, cmd; 365 uint8_t link_speed; 366 uint8_t link_type; 367 boolean_t proc_done = B_TRUE; 368 mbx_cmd_t reply_cmd = {0}; 369 boolean_t fatal_error = B_FALSE; 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 fatal_error = B_TRUE; 385 (void) ql_8xxx_binary_core_dump(qlge, &qlge->ql_mpi_coredump); 386 break; 387 case MBA_LINK_UP /* 8011h */: 388 QL_PRINT(DBG_MBX, ("%s(%d): MBA_LINK_UP received\n", 389 __func__, qlge->instance)); 390 link_status = mbx_cmds->mb[1]; 391 QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n", 392 __func__, qlge->instance, link_status)); 393 link_speed = (uint8_t)((link_status >> 3) & 0x07); 394 395 if (link_speed == 0) { 396 qlge->speed = SPEED_100; 397 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 100M\n", 398 __func__, qlge->instance)); 399 } else if (link_speed == 1) { 400 qlge->speed = SPEED_1000; 401 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 1G\n", 402 __func__, qlge->instance)); 403 } else if (link_speed == 2) { 404 qlge->speed = SPEED_10G; 405 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 10G\n", 406 __func__, qlge->instance)); 407 } 408 409 qlge->link_type = link_type = (uint8_t)(link_status & 0x07); 410 411 if (link_type == XFI_NETWORK_INTERFACE) { 412 /* EMPTY */ 413 QL_PRINT(DBG_MBX, 414 ("%s(%d):Link type XFI_NETWORK_INTERFACE\n", 415 __func__, qlge->instance)); 416 } else if (link_type == XAUI_NETWORK_INTERFACE) { 417 /* EMPTY */ 418 QL_PRINT(DBG_MBX, ("%s(%d):Link type" 419 "XAUI_NETWORK_INTERFACE\n", 420 __func__, qlge->instance)); 421 } else if (link_type == XFI_BACKPLANE_INTERFACE) { 422 /* EMPTY */ 423 QL_PRINT(DBG_MBX, ("%s(%d):Link type" 424 "XFI_BACKPLANE_INTERFACE\n", 425 __func__, qlge->instance)); 426 } else if (link_type == XAUI_BACKPLANE_INTERFACE) { 427 /* EMPTY */ 428 QL_PRINT(DBG_MBX, ("%s(%d):Link type " 429 "XAUI_BACKPLANE_INTERFACE\n", 430 __func__, qlge->instance)); 431 } else if (link_type == EXT_10GBASE_T_PHY) { 432 /* EMPTY */ 433 QL_PRINT(DBG_MBX, 434 ("%s(%d):Link type EXT_10GBASE_T_PHY\n", 435 __func__, qlge->instance)); 436 } else if (link_type == EXT_EXT_EDC_PHY) { 437 /* EMPTY */ 438 QL_PRINT(DBG_MBX, 439 ("%s(%d):Link type EXT_EXT_EDC_PHY\n", 440 __func__, qlge->instance)); 441 } else { 442 /* EMPTY */ 443 QL_PRINT(DBG_MBX, 444 ("%s(%d):unknown Link type \n", 445 __func__, qlge->instance)); 446 } 447 cmn_err(CE_NOTE, "qlge(%d) mpi link up! speed %dMbps\n", 448 qlge->instance, qlge->speed); 449 /* 450 * start timer if not started to delay some time then 451 * check if link is really up or down 452 */ 453 ql_restart_timer(qlge); 454 455 break; 456 case MBA_LINK_DOWN /* 8012h */: 457 QL_PRINT(DBG_MBX, 458 ("%s(%d): MBA_LINK_DOWN received\n", 459 __func__, qlge->instance)); 460 461 link_status = mbx_cmds->mb[1]; 462 463 QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n", 464 __func__, qlge->instance, link_status)); 465 if (link_status & 0x1) { 466 /* EMPTY */ 467 QL_PRINT(DBG_MBX, ("%s(%d): Loss of signal \n", 468 __func__, qlge->instance)); 469 } 470 if (link_status & 0x2) { 471 /* EMPTY */ 472 QL_PRINT(DBG_MBX, 473 ("%s(%d): Auto-Negotiation Failed \n", 474 __func__, qlge->instance)); 475 } 476 if (link_status & 0x4) { 477 /* EMPTY */ 478 QL_PRINT(DBG_MBX, 479 ("%s(%d): XTI-Training Failed \n", 480 __func__, qlge->instance)); 481 } 482 483 cmn_err(CE_NOTE, "qlge(%d) mpi link down!\n", qlge->instance); 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 fatal_error = B_TRUE; 636 break; 637 default: 638 if (mbx_cmds->mb[0] > 0x8000) { 639 cmn_err(CE_WARN, "%s(%d): " 640 "Unknown Async event received: mbx[0] %x ," 641 "mbx[1] %x; mbx[2] %x", 642 __func__, qlge->instance, 643 mbx_cmds->mb[0], mbx_cmds->mb[1], 644 mbx_cmds->mb[2]); 645 proc_done = B_TRUE; 646 } else { 647 proc_done = B_FALSE; 648 } 649 break; 650 } 651 if (fatal_error) { 652 if (qlge->fm_enable) { 653 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 654 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_LOST); 655 atomic_or_32(&qlge->flags, ADAPTER_ERROR); 656 } 657 } 658 return (proc_done); 659 } 660 661 662 /* 663 * MPI Interrupt handler 664 * Caller must have MBX_LOCK 665 */ 666 void 667 ql_do_mpi_intr(qlge_t *qlge) 668 { 669 /* 670 * we just need to read first few mailboxes that this adapter's MPI 671 * will write response to. 672 */ 673 mutex_enter(&qlge->mbx_mutex); 674 675 (void) ql_read_mailbox_cmd(qlge, &qlge->received_mbx_cmds, 676 qlge->max_read_mbx); 677 678 /* 679 * process PI interrupt as async events, if not done, 680 * then pass to mailbox processing 681 */ 682 if (ql_async_event_parser(qlge, &qlge->received_mbx_cmds) == B_FALSE) { 683 QL_PRINT(DBG_MBX, ("%s(%d) mailbox completion interrupt\n", 684 __func__, qlge->instance)); 685 /* 686 * If another thread is waiting for the mail box 687 * completion event to occur 688 */ 689 if (qlge->mbx_wait_completion == 1) { 690 qlge->mbx_wait_completion = 0; 691 cv_broadcast(&qlge->cv_mbx_intr); 692 QL_PRINT(DBG_MBX, 693 ("%s(%d) mailbox completion signaled \n", 694 __func__, qlge->instance)); 695 } 696 } 697 /* inform MPI Firmware to clear the interrupt */ 698 ql_write_reg(qlge, REG_HOST_CMD_STATUS, 699 HOST_CMD_CLEAR_RISC_TO_HOST_INTR /* 0x0A */); 700 mutex_exit(&qlge->mbx_mutex); 701 ql_enable_completion_interrupt(qlge, 0); /* MPI is on irq 0 */ 702 } 703 704 /* 705 * Test if mailbox communication works 706 * This is used when Interrupt is not enabled 707 */ 708 int 709 ql_mbx_test(qlge_t *qlge) 710 { 711 mbx_cmd_t mbx_cmds; 712 mbx_data_t mbx_results; 713 int i, test_ok = 1; 714 int rtn_val = DDI_FAILURE; 715 716 for (i = 0; i < NUM_MAILBOX_REGS; i++) 717 mbx_cmds.mb[i] = i; 718 719 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */ 720 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) { 721 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.", 722 __func__, qlge->instance); 723 goto out; 724 } 725 726 /* delay for the processor interrupt is received */ 727 if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmds.timeout) 728 == DDI_SUCCESS) { 729 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received", 730 __func__, qlge->instance)); 731 (void) ql_read_mailbox_cmd(qlge, &mbx_results, 0); 732 733 ql_write_reg(qlge, REG_HOST_CMD_STATUS, 734 HOST_CMD_CLEAR_RISC_TO_HOST_INTR); 735 736 if (mbx_results.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 737 test_ok = 0; 738 } else { 739 for (i = 1; i < NUM_MAILBOX_REGS; i++) { 740 if (mbx_results.mb[i] != i) { 741 test_ok = 0; 742 break; 743 } 744 } 745 } 746 if (test_ok) { 747 rtn_val = DDI_SUCCESS; 748 } else { 749 cmn_err(CE_WARN, "%s(%d) mailbox test failed!", 750 __func__, qlge->instance); 751 } 752 } else { 753 cmn_err(CE_WARN, "%s(%d) mailbox testing error: " 754 "PI Intr not received ", __func__, qlge->instance); 755 } 756 out: 757 return (rtn_val); 758 } 759 760 /* 761 * ql_mbx_test2 762 * Test if mailbox communication works 763 * This is used when Interrupt is enabled 764 * mailbox cmd:0x06h 765 */ 766 int 767 ql_mbx_test2(qlge_t *qlge) 768 { 769 mbx_cmd_t mbx_cmds = {0}; 770 int i, test_ok = 1; 771 int rtn_val = DDI_FAILURE; 772 773 for (i = 0; i < NUM_MAILBOX_REGS; i++) 774 mbx_cmds.mb[i] = i; 775 776 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */ 777 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 778 cmn_err(CE_WARN, 779 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 780 __func__, qlge->instance); 781 goto out; 782 } 783 784 /* verify if the incoming outbound mailbox value is what we just sent */ 785 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 786 test_ok = 0; 787 } else { 788 for (i = 1; i < qlge->max_read_mbx; i++) { 789 if (mbx_cmds.mb[i] != i) { 790 test_ok = 0; 791 break; 792 } 793 } 794 } 795 if (test_ok) { 796 rtn_val = DDI_SUCCESS; 797 } else { 798 cmn_err(CE_WARN, "%s(%d) mailbox test failed!", 799 __func__, qlge->instance); 800 } 801 out: 802 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 803 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 804 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 805 } 806 return (rtn_val); 807 } 808 809 /* 810 * ql_get_fw_state 811 * Get fw state. 812 * mailbox cmd:0x69h 813 */ 814 int 815 ql_get_fw_state(qlge_t *qlge, uint32_t *fw_state_ptr) 816 { 817 int rtn_val = DDI_FAILURE; 818 mbx_cmd_t mbx_cmds = {0}; 819 820 mbx_cmds.mb[0] = MBC_GET_FIRMWARE_STATE; 821 822 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 823 != DDI_SUCCESS) { 824 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 825 " failed.", __func__, qlge->instance); 826 goto out; 827 } 828 /* verify if the transaction is completed successful */ 829 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 830 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", 831 __func__, qlge->instance, mbx_cmds.mb[0]); 832 } else { 833 /* EMPTY */ 834 QL_PRINT(DBG_MBX, ("firmware state: 0x%x\n", mbx_cmds.mb[1])); 835 } 836 if (fw_state_ptr != NULL) 837 *fw_state_ptr = mbx_cmds.mb[1]; 838 rtn_val = DDI_SUCCESS; 839 out: 840 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 841 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 842 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 843 } 844 return (rtn_val); 845 } 846 847 /* 848 * ql_set_IDC_Req 849 * Send a IDC Request to firmware to notify all functions 850 * or any specific functions on the same port 851 * mailbox cmd:0x100h 852 */ 853 int 854 ql_set_IDC_Req(qlge_t *qlge, uint8_t dest_functions, uint8_t timeout) 855 { 856 int rtn_val = DDI_FAILURE; 857 mbx_cmd_t mbx_cmds = {0}; 858 859 mbx_cmds.mb[0] = MBC_IDC_REQUEST /* 0x100 */; 860 mbx_cmds.mb[1] = (timeout<<8) | qlge->func_number; 861 862 switch (dest_functions) { 863 case IDC_REQ_DEST_FUNC_ALL: 864 mbx_cmds.mb[1] |= IDC_REQ_ALL_DEST_FUNC_MASK; 865 mbx_cmds.mb[2] = 0; 866 break; 867 case IDC_REQ_DEST_FUNC_0: 868 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_0_MASK; 869 break; 870 case IDC_REQ_DEST_FUNC_1: 871 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_1_MASK; 872 break; 873 case IDC_REQ_DEST_FUNC_2: 874 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_2_MASK; 875 break; 876 case IDC_REQ_DEST_FUNC_3: 877 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_3_MASK; 878 break; 879 default: 880 cmn_err(CE_WARN, "Wrong dest functions %x", 881 dest_functions); 882 } 883 884 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 885 cmn_err(CE_WARN, 886 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 887 __func__, qlge->instance); 888 goto out; 889 } 890 /* verify if the transaction is completed successful */ 891 if (mbx_cmds.mb[0] == MBA_IDC_INTERMEDIATE_COMPLETE /* 0x1000 */) { 892 QL_PRINT(DBG_MBX, ("%s(%d) mbx1: 0x%x, mbx2: 0x%x\n", 893 __func__, qlge->instance, mbx_cmds.mb[1], mbx_cmds.mb[2])); 894 rtn_val = DDI_SUCCESS; 895 } else if (mbx_cmds.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) { 896 QL_PRINT(DBG_MBX, ("%s(%d) cmd sent succesfully 0x%x\n", 897 __func__, qlge->instance)); 898 rtn_val = DDI_SUCCESS; 899 } else if (mbx_cmds.mb[0] == MBS_COMMAND_ERROR /* 0x4005 */) { 900 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_ERROR", 901 __func__, qlge->instance); 902 } else if (mbx_cmds.mb[0] == MBS_COMMAND_PARAMETER_ERROR /* 0x4006 */) { 903 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_PARAMETER_ERROR", 904 __func__, qlge->instance); 905 } else { 906 cmn_err(CE_WARN, "%s(%d) unknow result: mbx[0]: 0x%x; mbx[1]:" 907 " 0x%x; mbx[2]: 0x%x", __func__, qlge->instance, 908 mbx_cmds.mb[0], mbx_cmds.mb[1], mbx_cmds.mb[2]); 909 } 910 911 out: 912 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 913 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 914 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 915 } 916 return (rtn_val); 917 } 918 919 /* 920 * ql_set_mpi_port_config 921 * Send new port configuration.to mpi 922 * mailbox cmd:0x122h 923 */ 924 int 925 ql_set_mpi_port_config(qlge_t *qlge, port_cfg_info_t new_cfg) 926 { 927 int rtn_val = DDI_FAILURE; 928 mbx_cmd_t mbx_cmds = {0}; 929 930 mbx_cmds.mb[0] = MBC_SET_PORT_CONFIG /* 0x122 */; 931 mbx_cmds.mb[1] = new_cfg.link_cfg; 932 mbx_cmds.mb[2] = new_cfg.max_frame_size; 933 934 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 935 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 936 " failed.", __func__, qlge->instance); 937 goto out; 938 } 939 /* verify if the transaction is completed successful */ 940 if ((mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) && 941 (mbx_cmds.mb[0] != MBA_IDC_COMPLETE /* 0x8100 */)) { 942 cmn_err(CE_WARN, "set port config (%d) failed, 0x%x", 943 qlge->instance, mbx_cmds.mb[0]); 944 } else 945 rtn_val = DDI_SUCCESS; 946 out: 947 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 948 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 949 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 950 } 951 return (rtn_val); 952 } 953 954 int 955 ql_set_pause_mode(qlge_t *qlge) 956 { 957 uint32_t pause_bit_mask = 0x60; /* bit 5-6 */ 958 959 /* clear pause bits */ 960 qlge->port_cfg_info.link_cfg &= ~pause_bit_mask; 961 962 /* set new pause mode */ 963 if (qlge->pause == PAUSE_MODE_STANDARD) 964 qlge->port_cfg_info.link_cfg |= STD_PAUSE; 965 else if (qlge->pause == PAUSE_MODE_PER_PRIORITY) 966 qlge->port_cfg_info.link_cfg |= PP_PAUSE; 967 968 return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info)); 969 } 970 971 int 972 ql_set_loop_back_mode(qlge_t *qlge) 973 { 974 uint32_t loop_back_bit_mask = 0x0e; /* bit 1-3 */ 975 976 /* clear loop back bits */ 977 qlge->port_cfg_info.link_cfg &= ~loop_back_bit_mask; 978 /* loop back cfg: bit1-3 */ 979 if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_PARALLEL) 980 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_PARALLEL; 981 else if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_SERIAL) 982 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_SERIAL; 983 else if (qlge->loop_back_mode == QLGE_LOOP_EXTERNAL_PHY) 984 qlge->port_cfg_info.link_cfg |= LOOP_EXTERNAL_PHY; 985 986 return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info)); 987 988 } 989 /* 990 * ql_get_port_cfg 991 * Get port configuration. 992 * mailbox cmd:0x123h 993 */ 994 int 995 ql_get_port_cfg(qlge_t *qlge) 996 { 997 int rtn_val = DDI_FAILURE; 998 mbx_cmd_t mbx_cmds = {0}; 999 1000 mbx_cmds.mb[0] = MBC_GET_PORT_CONFIG /* 0x123 */; 1001 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 1002 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 1003 " failed.", __func__, qlge->instance); 1004 goto out; 1005 } 1006 /* verify if the transaction is completed successfully */ 1007 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1008 cmn_err(CE_WARN, "get port config (%d) failed, 0x%x", 1009 qlge->instance, mbx_cmds.mb[0]); 1010 } else { /* verify frame size */ 1011 if ((mbx_cmds.mb[2] == NORMAL_FRAME_SIZE) || 1012 (mbx_cmds.mb[2] == JUMBO_FRAME_SIZE)) { 1013 qlge->port_cfg_info.link_cfg = mbx_cmds.mb[1]; 1014 qlge->port_cfg_info.max_frame_size = mbx_cmds.mb[2]; 1015 QL_PRINT(DBG_MBX, ("link_cfg: 0x%x, max_frame_size:" 1016 " %d bytes\n", mbx_cmds.mb[1], mbx_cmds.mb[2])); 1017 rtn_val = DDI_SUCCESS; 1018 } else { 1019 cmn_err(CE_WARN, "bad link_cfg: 0x%x, max_frame_size:" 1020 " %d bytes", mbx_cmds.mb[1], mbx_cmds.mb[2]); 1021 } 1022 } 1023 out: 1024 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 1025 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 1026 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 1027 } 1028 return (rtn_val); 1029 } 1030 1031 /* 1032 * qlge_get_link_status 1033 * Get link status. 1034 * mailbox cmd:0x124h 1035 */ 1036 int 1037 qlge_get_link_status(qlge_t *qlge, 1038 struct qlnic_link_status_info *link_status_ptr) 1039 { 1040 int rtn_val = DDI_FAILURE; 1041 mbx_cmd_t mbx_cmds = {0}; 1042 1043 mbx_cmds.mb[0] = MBC_GET_LINK_STATUS /* 0x124 */; 1044 1045 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 1046 != DDI_SUCCESS) { 1047 cmn_err(CE_WARN, 1048 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 1049 __func__, qlge->instance); 1050 goto out; 1051 } 1052 /* verify if the transaction is completed successful */ 1053 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1054 cmn_err(CE_WARN, "get link status(%d) failed, 0x%x", 1055 qlge->instance, mbx_cmds.mb[0]); 1056 } else { 1057 /* EMPTY */ 1058 QL_PRINT(DBG_MBX, 1059 ("link status: status1 : 0x%x, status2 : 0x%x, " 1060 "status3 : 0x%x\n", 1061 mbx_cmds.mb[1], mbx_cmds.mb[2], mbx_cmds.mb[3])); 1062 } 1063 if (link_status_ptr != NULL) { 1064 link_status_ptr->link_status_info = mbx_cmds.mb[1]; 1065 link_status_ptr->additional_info = mbx_cmds.mb[2]; 1066 link_status_ptr->network_hw_info = mbx_cmds.mb[3]; 1067 link_status_ptr->dcbx_frame_counters_info = mbx_cmds.mb[4]; 1068 link_status_ptr->change_counters_info = mbx_cmds.mb[5]; 1069 } 1070 rtn_val = DDI_SUCCESS; 1071 out: 1072 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 1073 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 1074 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 1075 } 1076 return (rtn_val); 1077 } 1078 1079 /* 1080 * ql_get_firmware_version 1081 * Get firmware version. 1082 */ 1083 int 1084 ql_get_firmware_version(qlge_t *qlge, 1085 struct qlnic_mpi_version_info *mpi_version_ptr) 1086 { 1087 int rtn_val = DDI_FAILURE; 1088 mbx_cmd_t mbx_cmds = {0}; 1089 1090 mbx_cmds.mb[0] = MBC_ABOUT_FIRMWARE /* 0x08 */; 1091 1092 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 1093 != DDI_SUCCESS) { 1094 cmn_err(CE_WARN, 1095 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 1096 __func__, qlge->instance); 1097 goto out; 1098 } 1099 1100 /* verify if the transaction is completed successful */ 1101 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1102 cmn_err(CE_WARN, "get firmware version(%d) failed, 0x%x", 1103 qlge->instance, mbx_cmds.mb[0]); 1104 } else { 1105 qlge->fw_version_info.major_version = 1106 LSB(MSW(mbx_cmds.mb[1])); 1107 qlge->fw_version_info.minor_version = 1108 MSB(LSW(mbx_cmds.mb[1])); 1109 qlge->fw_version_info.sub_minor_version = 1110 LSB(LSW(mbx_cmds.mb[1])); 1111 qlge->phy_version_info.major_version = 1112 LSB(MSW(mbx_cmds.mb[2])); 1113 qlge->phy_version_info.minor_version = 1114 MSB(LSW(mbx_cmds.mb[2])); 1115 qlge->phy_version_info.sub_minor_version = 1116 LSB(LSW(mbx_cmds.mb[2])); 1117 #ifdef QLGE_LOAD_UNLOAD 1118 cmn_err(CE_NOTE, "firmware version: %d.%d.%d\n", 1119 qlge->fw_version_info.major_version, 1120 qlge->fw_version_info.minor_version, 1121 qlge->fw_version_info.sub_minor_version); 1122 #endif 1123 if (mpi_version_ptr != NULL) { 1124 mpi_version_ptr->fw_version = 1125 (qlge->fw_version_info.major_version<<16) 1126 |(qlge->fw_version_info.minor_version<<8) 1127 |(qlge->fw_version_info.sub_minor_version); 1128 mpi_version_ptr->phy_version = 1129 (qlge->phy_version_info.major_version<<16) 1130 |(qlge->phy_version_info.minor_version<<8) 1131 |(qlge->phy_version_info.sub_minor_version); 1132 } 1133 } 1134 rtn_val = DDI_SUCCESS; 1135 out: 1136 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 1137 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 1138 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 1139 } 1140 return (rtn_val); 1141 } 1142 1143 /* 1144 * Trigger a system error event 1145 */ 1146 int 1147 ql_trigger_system_error_event(qlge_t *qlge) 1148 { 1149 mbx_cmd_t mbx_cmds = {0}; 1150 int rtn_val = DDI_FAILURE; 1151 1152 mbx_cmds.mb[0] = MBC_GENERATE_SYS_ERROR; /* 0x2A */ 1153 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) { 1154 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.", 1155 __func__, qlge->instance); 1156 goto out; 1157 } 1158 rtn_val = DDI_SUCCESS; 1159 out: 1160 return (rtn_val); 1161 } 1162 1163 /* 1164 * Reset the MPI RISC Processor 1165 */ 1166 int 1167 ql_reset_mpi_risc(qlge_t *qlge) 1168 { 1169 int rtn_val = DDI_FAILURE; 1170 1171 /* Reset the MPI Processor */ 1172 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_RESET); 1173 if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS, RISC_RESET, 1174 BIT_SET, 0) != DDI_SUCCESS) { 1175 (void) ql_read_reg(qlge, REG_HOST_CMD_STATUS); 1176 goto out; 1177 } 1178 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_CLEAR_RISC_RESET); 1179 rtn_val = DDI_SUCCESS; 1180 out: 1181 return (rtn_val); 1182 } 1183 1184 int 1185 ql_read_risc_ram(qlge_t *qlge, uint32_t risc_address, uint64_t bp, 1186 uint32_t word_count) 1187 { 1188 int rval = DDI_FAILURE; 1189 mbx_cmd_t mc = {0}; 1190 mbx_cmd_t *mcp = &mc; 1191 mbx_data_t mbx_results; 1192 1193 QL_PRINT(DBG_MBX, ("%s(%d): read risc addr:0x%x," 1194 "phys_addr %x,%x words\n", __func__, qlge->instance, 1195 risc_address, bp, word_count)); 1196 if (CFG_IST(qlge, CFG_CHIP_8100)) { 1197 mcp->mb[0] = MBC_DUMP_RISC_RAM /* 0x0C */; 1198 mcp->mb[1] = LSW(risc_address); 1199 mcp->mb[2] = MSW(LSD(bp)); 1200 mcp->mb[3] = LSW(LSD(bp)); 1201 mcp->mb[4] = MSW(word_count); 1202 mcp->mb[5] = LSW(word_count); 1203 mcp->mb[6] = MSW(MSD(bp)); 1204 mcp->mb[7] = LSW(MSD(bp)); 1205 mcp->mb[8] = MSW(risc_address); 1206 } 1207 mcp->timeout = 10 /* MAILBOX_TOV */; 1208 1209 if (ql_issue_mailbox_cmd_and_poll_rsp(qlge, mcp, &mbx_results) 1210 != DDI_SUCCESS) { 1211 goto out; 1212 } else { 1213 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received", 1214 __func__, qlge->instance)); 1215 if (mbx_results.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) { 1216 QL_PRINT(DBG_MBX, ("%s(%d): success\n", 1217 __func__, qlge->instance)); 1218 rval = DDI_SUCCESS; 1219 } else { 1220 cmn_err(CE_WARN, "read_risc_ram(%d): failed, status %x", 1221 qlge->instance, mbx_results.mb[0]); 1222 } 1223 } 1224 out: 1225 return (rval); 1226 }