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 += 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 boolean_t fatal_error = B_FALSE; 371 372 switch (mbx_cmds->mb[0]) { 373 case MBA_IDC_INTERMEDIATE_COMPLETE /* 1000h */: 374 QL_PRINT(DBG_MBX, ("%s(%d):" 375 "MBA_IDC_INTERMEDIATE_COMPLETE received\n", 376 __func__, qlge->instance)); 377 break; 378 case MBA_SYSTEM_ERR /* 8002h */: 379 cmn_err(CE_WARN, "%s(%d): MBA_SYSTEM_ERR received", 380 __func__, qlge->instance); 381 cmn_err(CE_WARN, "%s(%d): File id %x, Line # %x," 382 "Firmware Ver# %x", 383 __func__, qlge->instance, mbx_cmds->mb[1], 384 mbx_cmds->mb[2], mbx_cmds->mb[3]); 385 fatal_error = B_TRUE; 386 (void) ql_8xxx_binary_core_dump(qlge, &qlge->ql_mpi_coredump); 387 break; 388 case MBA_LINK_UP /* 8011h */: 389 QL_PRINT(DBG_MBX, ("%s(%d): MBA_LINK_UP received\n", 390 __func__, qlge->instance)); 391 link_status = mbx_cmds->mb[1]; 392 QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n", 393 __func__, qlge->instance, link_status)); 394 link_speed = (uint8_t)((link_status >> 3) & 0x07); 395 396 if (link_speed == 0) { 397 qlge->speed = SPEED_100; 398 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 100M\n", 399 __func__, qlge->instance)); 400 } else if (link_speed == 1) { 401 qlge->speed = SPEED_1000; 402 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 1G\n", 403 __func__, qlge->instance)); 404 } else if (link_speed == 2) { 405 qlge->speed = SPEED_10G; 406 QL_PRINT(DBG_MBX, ("%s(%d):Link speed 10G\n", 407 __func__, qlge->instance)); 408 } 409 410 qlge->link_type = link_type = (uint8_t)(link_status & 0x07); 411 412 if (link_type == XFI_NETWORK_INTERFACE) { 413 /* EMPTY */ 414 QL_PRINT(DBG_MBX, 415 ("%s(%d):Link type XFI_NETWORK_INTERFACE\n", 416 __func__, qlge->instance)); 417 } else if (link_type == XAUI_NETWORK_INTERFACE) { 418 /* EMPTY */ 419 QL_PRINT(DBG_MBX, ("%s(%d):Link type" 420 "XAUI_NETWORK_INTERFACE\n", 421 __func__, qlge->instance)); 422 } else if (link_type == XFI_BACKPLANE_INTERFACE) { 423 /* EMPTY */ 424 QL_PRINT(DBG_MBX, ("%s(%d):Link type" 425 "XFI_BACKPLANE_INTERFACE\n", 426 __func__, qlge->instance)); 427 } else if (link_type == XAUI_BACKPLANE_INTERFACE) { 428 /* EMPTY */ 429 QL_PRINT(DBG_MBX, ("%s(%d):Link type " 430 "XAUI_BACKPLANE_INTERFACE\n", 431 __func__, qlge->instance)); 432 } else if (link_type == EXT_10GBASE_T_PHY) { 433 /* EMPTY */ 434 QL_PRINT(DBG_MBX, 435 ("%s(%d):Link type EXT_10GBASE_T_PHY\n", 436 __func__, qlge->instance)); 437 } else if (link_type == EXT_EXT_EDC_PHY) { 438 /* EMPTY */ 439 QL_PRINT(DBG_MBX, 440 ("%s(%d):Link type EXT_EXT_EDC_PHY\n", 441 __func__, qlge->instance)); 442 } else { 443 /* EMPTY */ 444 QL_PRINT(DBG_MBX, 445 ("%s(%d):unknown Link type \n", 446 __func__, qlge->instance)); 447 } 448 cmn_err(CE_NOTE, "qlge(%d) mpi link up! speed %dMbps\n", 449 qlge->instance, qlge->speed); 450 /* 451 * start timer if not started to delay some time then 452 * check if link is really up or down 453 */ 454 ql_restart_timer(qlge); 455 456 break; 457 case MBA_LINK_DOWN /* 8012h */: 458 QL_PRINT(DBG_MBX, 459 ("%s(%d): MBA_LINK_DOWN received\n", 460 __func__, qlge->instance)); 461 462 link_status = mbx_cmds->mb[1]; 463 464 QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n", 465 __func__, qlge->instance, link_status)); 466 if (link_status & 0x1) { 467 /* EMPTY */ 468 QL_PRINT(DBG_MBX, ("%s(%d): Loss of signal \n", 469 __func__, qlge->instance)); 470 } 471 if (link_status & 0x2) { 472 /* EMPTY */ 473 QL_PRINT(DBG_MBX, 474 ("%s(%d): Auto-Negotiation Failed \n", 475 __func__, qlge->instance)); 476 } 477 if (link_status & 0x4) { 478 /* EMPTY */ 479 QL_PRINT(DBG_MBX, 480 ("%s(%d): XTI-Training Failed \n", 481 __func__, qlge->instance)); 482 } 483 484 cmn_err(CE_NOTE, "qlge(%d) mpi link down!\n", qlge->instance); 485 ql_restart_timer(qlge); 486 break; 487 case MBA_IDC_COMPLETE /* 8100h */: 488 489 QL_PRINT(DBG_MBX, 490 ("%s(%d): MBA_IDC_COMPLETE received\n", 491 __func__, qlge->instance)); 492 cmd = mbx_cmds->mb[1]; 493 if (cmd == MBC_STOP_FIRMWARE) { 494 /* EMPTY */ 495 QL_PRINT(DBG_MBX, 496 ("%s(%d): STOP_FIRMWARE event completed\n", 497 __func__, qlge->instance)); 498 } else if (cmd == MBC_IDC_REQUEST) { 499 /* EMPTY */ 500 QL_PRINT(DBG_MBX, 501 ("%s(%d): IDC_REQUEST event completed\n", 502 __func__, qlge->instance)); 503 } else if (cmd == MBC_PORT_RESET) { 504 /* EMPTY */ 505 QL_PRINT(DBG_MBX, 506 ("%s(%d): PORT_RESET event completed\n", 507 __func__, qlge->instance)); 508 } else if (cmd == MBC_SET_PORT_CONFIG) { 509 /* EMPTY */ 510 QL_PRINT(DBG_MBX, 511 ("%s(%d): SET_PORT_CONFIG event " 512 "completed\n", __func__, qlge->instance)); 513 } else { 514 /* EMPTY */ 515 QL_PRINT(DBG_MBX, 516 ("%s(%d): unknown IDC completion request" 517 " event %x %x\n", __func__, qlge->instance, 518 mbx_cmds->mb[1], mbx_cmds->mb[2])); 519 } 520 proc_done = B_FALSE; 521 break; 522 523 case MBA_IDC_REQUEST_NOTIFICATION /* 8101h */: 524 QL_PRINT(DBG_MBX, 525 ("%s(%d): MBA_IDC_REQUEST_NOTIFICATION " 526 "received\n", __func__, qlge->instance)); 527 cmd = mbx_cmds->mb[1]; 528 if (cmd == MBC_STOP_FIRMWARE) { 529 /* EMPTY */ 530 QL_PRINT(DBG_MBX, 531 ("%s(%d): STOP_FIRMWARE notification" 532 " received\n", __func__, qlge->instance)); 533 } else if (cmd == MBC_IDC_REQUEST) { 534 /* EMPTY */ 535 QL_PRINT(DBG_MBX, 536 ("%s(%d): IDC_REQUEST notification " 537 "received\n", __func__, qlge->instance)); 538 } else if (cmd == MBC_PORT_RESET) { 539 /* EMPTY */ 540 QL_PRINT(DBG_MBX, ("%s(%d): PORT_RESET " 541 "notification received\n", 542 __func__, qlge->instance)); 543 } else if (cmd == MBC_SET_PORT_CONFIG) { 544 /* EMPTY */ 545 QL_PRINT(DBG_MBX, 546 ("%s(%d): SET_PORT_CONFIG notification " 547 "received\n", __func__, qlge->instance)); 548 } else { 549 /* EMPTY */ 550 QL_PRINT(DBG_MBX, ("%s(%d): " 551 "unknown request received %x %x\n", 552 __func__, qlge->instance, mbx_cmds->mb[1], 553 mbx_cmds->mb[2])); 554 } 555 reply_cmd.mb[0] = MBC_IDC_ACK; 556 reply_cmd.mb[1] = mbx_cmds->mb[1]; 557 reply_cmd.mb[2] = mbx_cmds->mb[2]; 558 reply_cmd.mb[3] = mbx_cmds->mb[3]; 559 reply_cmd.mb[4] = mbx_cmds->mb[4]; 560 if (ql_issue_mailbox_cmd(qlge, &reply_cmd) 561 != DDI_SUCCESS) { 562 cmn_err(CE_WARN, 563 "%s(%d) send IDC Ack failed.", 564 __func__, qlge->instance); 565 } 566 /* 567 * verify if the incoming outbound mailbox value is what 568 * we just sent 569 */ 570 if (mbx_cmds->mb[0] == MBS_COMMAND_COMPLETE) { 571 /* 0x4000 */ 572 /* EMPTY */ 573 QL_PRINT(DBG_MBX, 574 ("%s(%d): IDC Ack sent success.\n", 575 __func__, qlge->instance)); 576 } else { 577 /* EMPTY */ 578 QL_PRINT(DBG_MBX, 579 ("%s(%d): IDC Ack reply error %x %x %x.\n", 580 __func__, qlge->instance, mbx_cmds->mb[0], 581 mbx_cmds->mb[1], mbx_cmds->mb[2])); 582 } 583 break; 584 case MBA_IDC_TIME_EXTENDED /* 8102 */: 585 QL_PRINT(DBG_MBX, 586 ("%s(%d): MBA_IDC_TIME_EXTENDED received\n", 587 __func__, qlge->instance)); 588 break; 589 case MBA_DCBX_CONFIG_CHANGE /* 8110 */: 590 QL_PRINT(DBG_MBX, 591 ("%s(%d): MBA_DCBX_CONFIG_CHANGE received\n", 592 __func__, qlge->instance)); 593 break; 594 case MBA_NOTIFICATION_LOST /* 8120 */: 595 QL_PRINT(DBG_MBX, 596 ("%s(%d): MBA_NOTIFICATION_LOST received\n", 597 __func__, qlge->instance)); 598 break; 599 case MBA_SFT_TRANSCEIVER_INSERTION /* 8130 */: 600 QL_PRINT(DBG_MBX, 601 ("%s(%d): MBA_SFT_TRANSCEIVER_INSERTION " 602 "received\n", __func__, qlge->instance)); 603 break; 604 case MBA_SFT_TRANSCEIVER_REMOVAL /* 8140 */: 605 QL_PRINT(DBG_MBX, 606 ("%s(%d): MBA_SFT_TRANSCEIVER_REMOVAL " 607 "received\n", __func__, qlge->instance)); 608 break; 609 case MBA_FIRMWARE_INIT_COMPLETE /* 8400 */: 610 QL_PRINT(DBG_MBX, 611 ("%s(%d): MBA_FIRMWARE_INIT_COMPLETE " 612 "received\n", __func__, qlge->instance)); 613 QL_PRINT(DBG_MBX, 614 ("%s(%d): mbx[1] %x, mbx[2] %x\n", __func__, 615 qlge->instance, mbx_cmds->mb[1], mbx_cmds->mb[2])); 616 qlge->fw_init_complete = B_TRUE; 617 qlge->fw_version_info.major_version = 618 LSB(MSW(mbx_cmds->mb[1])); 619 qlge->fw_version_info.minor_version = 620 MSB(LSW(mbx_cmds->mb[1])); 621 qlge->fw_version_info.sub_minor_version = 622 LSB(LSW(mbx_cmds->mb[1])); 623 qlge->phy_version_info.major_version = 624 LSB(MSW(mbx_cmds->mb[2])); 625 qlge->phy_version_info.minor_version = 626 MSB(LSW(mbx_cmds->mb[2])); 627 qlge->phy_version_info.sub_minor_version = 628 LSB(LSW(mbx_cmds->mb[2])); 629 break; 630 case MBA_FIRMWARE_INIT_FAILED /* 8401 */: 631 cmn_err(CE_WARN, "%s(%d):" 632 "ASYNC_EVENT_FIRMWARE_INIT_FAILURE " 633 "received: mbx[1] %x, mbx[2] %x", 634 __func__, qlge->instance, 635 mbx_cmds->mb[1], mbx_cmds->mb[2]); 636 fatal_error = B_TRUE; 637 break; 638 default: 639 if (mbx_cmds->mb[0] > 0x8000) { 640 cmn_err(CE_WARN, "%s(%d): " 641 "Unknown Async event received: mbx[0] %x ," 642 "mbx[1] %x; mbx[2] %x", 643 __func__, qlge->instance, 644 mbx_cmds->mb[0], mbx_cmds->mb[1], 645 mbx_cmds->mb[2]); 646 proc_done = B_TRUE; 647 } else { 648 proc_done = B_FALSE; 649 } 650 break; 651 } 652 if (fatal_error) { 653 if (qlge->fm_enable) { 654 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 655 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_LOST); 656 atomic_or_32(&qlge->flags, ADAPTER_ERROR); 657 } 658 } 659 return (proc_done); 660 } 661 662 663 /* 664 * MPI Interrupt handler 665 * Caller must have MBX_LOCK 666 */ 667 void 668 ql_do_mpi_intr(qlge_t *qlge) 669 { 670 /* 671 * we just need to read first few mailboxes that this adapter's MPI 672 * will write response to. 673 */ 674 mutex_enter(&qlge->mbx_mutex); 675 676 (void) ql_read_mailbox_cmd(qlge, &qlge->received_mbx_cmds, 677 qlge->max_read_mbx); 678 679 /* 680 * process PI interrupt as async events, if not done, 681 * then pass to mailbox processing 682 */ 683 if (ql_async_event_parser(qlge, &qlge->received_mbx_cmds) == B_FALSE) { 684 QL_PRINT(DBG_MBX, ("%s(%d) mailbox completion interrupt\n", 685 __func__, qlge->instance)); 686 /* 687 * If another thread is waiting for the mail box 688 * completion event to occur 689 */ 690 if (qlge->mbx_wait_completion == 1) { 691 qlge->mbx_wait_completion = 0; 692 cv_broadcast(&qlge->cv_mbx_intr); 693 QL_PRINT(DBG_MBX, 694 ("%s(%d) mailbox completion signaled \n", 695 __func__, qlge->instance)); 696 } 697 } 698 /* inform MPI Firmware to clear the interrupt */ 699 ql_write_reg(qlge, REG_HOST_CMD_STATUS, 700 HOST_CMD_CLEAR_RISC_TO_HOST_INTR /* 0x0A */); 701 mutex_exit(&qlge->mbx_mutex); 702 ql_enable_completion_interrupt(qlge, 0); /* MPI is on irq 0 */ 703 } 704 705 /* 706 * Test if mailbox communication works 707 * This is used when Interrupt is not enabled 708 */ 709 int 710 ql_mbx_test(qlge_t *qlge) 711 { 712 mbx_cmd_t mbx_cmds; 713 mbx_data_t mbx_results; 714 int i, test_ok = 1; 715 int rtn_val = DDI_FAILURE; 716 717 for (i = 0; i < NUM_MAILBOX_REGS; i++) 718 mbx_cmds.mb[i] = i; 719 720 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */ 721 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) { 722 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.", 723 __func__, qlge->instance); 724 goto out; 725 } 726 727 /* delay for the processor interrupt is received */ 728 if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmds.timeout) 729 == DDI_SUCCESS) { 730 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received", 731 __func__, qlge->instance)); 732 (void) ql_read_mailbox_cmd(qlge, &mbx_results, 0); 733 734 ql_write_reg(qlge, REG_HOST_CMD_STATUS, 735 HOST_CMD_CLEAR_RISC_TO_HOST_INTR); 736 737 if (mbx_results.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 738 test_ok = 0; 739 } else { 740 for (i = 1; i < NUM_MAILBOX_REGS; i++) { 741 if (mbx_results.mb[i] != i) { 742 test_ok = 0; 743 break; 744 } 745 } 746 } 747 if (test_ok) { 748 rtn_val = DDI_SUCCESS; 749 } else { 750 cmn_err(CE_WARN, "%s(%d) mailbox test failed!", 751 __func__, qlge->instance); 752 } 753 } else { 754 cmn_err(CE_WARN, "%s(%d) mailbox testing error: " 755 "PI Intr not received ", __func__, qlge->instance); 756 } 757 out: 758 return (rtn_val); 759 } 760 761 /* 762 * ql_mbx_test2 763 * Test if mailbox communication works 764 * This is used when Interrupt is enabled 765 * mailbox cmd:0x06h 766 */ 767 int 768 ql_mbx_test2(qlge_t *qlge) 769 { 770 mbx_cmd_t mbx_cmds = {0}; 771 int i, test_ok = 1; 772 int rtn_val = DDI_FAILURE; 773 774 for (i = 0; i < NUM_MAILBOX_REGS; i++) 775 mbx_cmds.mb[i] = i; 776 777 mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */ 778 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 779 cmn_err(CE_WARN, 780 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 781 __func__, qlge->instance); 782 goto out; 783 } 784 785 /* verify if the incoming outbound mailbox value is what we just sent */ 786 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 787 test_ok = 0; 788 } else { 789 for (i = 1; i < qlge->max_read_mbx; i++) { 790 if (mbx_cmds.mb[i] != i) { 791 test_ok = 0; 792 break; 793 } 794 } 795 } 796 if (test_ok) { 797 rtn_val = DDI_SUCCESS; 798 } else { 799 cmn_err(CE_WARN, "%s(%d) mailbox test failed!", 800 __func__, qlge->instance); 801 } 802 out: 803 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 804 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 805 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 806 } 807 return (rtn_val); 808 } 809 810 /* 811 * ql_get_fw_state 812 * Get fw state. 813 * mailbox cmd:0x69h 814 */ 815 int 816 ql_get_fw_state(qlge_t *qlge, uint32_t *fw_state_ptr) 817 { 818 int rtn_val = DDI_FAILURE; 819 mbx_cmd_t mbx_cmds = {0}; 820 821 mbx_cmds.mb[0] = MBC_GET_FIRMWARE_STATE; 822 823 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 824 != DDI_SUCCESS) { 825 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 826 " failed.", __func__, qlge->instance); 827 goto out; 828 } 829 /* verify if the transaction is completed successful */ 830 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 831 cmn_err(CE_WARN, "%s(%d) failed, 0x%x", 832 __func__, qlge->instance, mbx_cmds.mb[0]); 833 } else { 834 /* EMPTY */ 835 QL_PRINT(DBG_MBX, ("firmware state: 0x%x\n", mbx_cmds.mb[1])); 836 } 837 if (fw_state_ptr != NULL) 838 *fw_state_ptr = mbx_cmds.mb[1]; 839 rtn_val = DDI_SUCCESS; 840 out: 841 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 842 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 843 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 844 } 845 return (rtn_val); 846 } 847 848 /* 849 * ql_set_IDC_Req 850 * Send a IDC Request to firmware to notify all functions 851 * or any specific functions on the same port 852 * mailbox cmd:0x100h 853 */ 854 int 855 ql_set_IDC_Req(qlge_t *qlge, uint8_t dest_functions, uint8_t timeout) 856 { 857 int rtn_val = DDI_FAILURE; 858 mbx_cmd_t mbx_cmds = {0}; 859 860 mbx_cmds.mb[0] = MBC_IDC_REQUEST /* 0x100 */; 861 mbx_cmds.mb[1] = (timeout<<8) | qlge->func_number; 862 863 switch (dest_functions) { 864 case IDC_REQ_DEST_FUNC_ALL: 865 mbx_cmds.mb[1] |= IDC_REQ_ALL_DEST_FUNC_MASK; 866 mbx_cmds.mb[2] = 0; 867 break; 868 case IDC_REQ_DEST_FUNC_0: 869 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_0_MASK; 870 break; 871 case IDC_REQ_DEST_FUNC_1: 872 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_1_MASK; 873 break; 874 case IDC_REQ_DEST_FUNC_2: 875 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_2_MASK; 876 break; 877 case IDC_REQ_DEST_FUNC_3: 878 mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_3_MASK; 879 break; 880 default: 881 cmn_err(CE_WARN, "Wrong dest functions %x", 882 dest_functions); 883 } 884 885 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 886 cmn_err(CE_WARN, 887 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 888 __func__, qlge->instance); 889 goto out; 890 } 891 /* verify if the transaction is completed successful */ 892 if (mbx_cmds.mb[0] == MBA_IDC_INTERMEDIATE_COMPLETE /* 0x1000 */) { 893 QL_PRINT(DBG_MBX, ("%s(%d) mbx1: 0x%x, mbx2: 0x%x\n", 894 __func__, qlge->instance, mbx_cmds.mb[1], mbx_cmds.mb[2])); 895 rtn_val = DDI_SUCCESS; 896 } else if (mbx_cmds.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) { 897 QL_PRINT(DBG_MBX, ("%s(%d) cmd sent succesfully 0x%x\n", 898 __func__, qlge->instance)); 899 rtn_val = DDI_SUCCESS; 900 } else if (mbx_cmds.mb[0] == MBS_COMMAND_ERROR /* 0x4005 */) { 901 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_ERROR", 902 __func__, qlge->instance); 903 } else if (mbx_cmds.mb[0] == MBS_COMMAND_PARAMETER_ERROR /* 0x4006 */) { 904 cmn_err(CE_WARN, "%s(%d) failed: COMMAND_PARAMETER_ERROR", 905 __func__, qlge->instance); 906 } else { 907 cmn_err(CE_WARN, "%s(%d) unknow result: mbx[0]: 0x%x; mbx[1]:" 908 " 0x%x; mbx[2]: 0x%x", __func__, qlge->instance, 909 mbx_cmds.mb[0], mbx_cmds.mb[1], mbx_cmds.mb[2]); 910 } 911 912 out: 913 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 914 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 915 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 916 } 917 return (rtn_val); 918 } 919 920 /* 921 * ql_set_mpi_port_config 922 * Send new port configuration.to mpi 923 * mailbox cmd:0x122h 924 */ 925 int 926 ql_set_mpi_port_config(qlge_t *qlge, port_cfg_info_t new_cfg) 927 { 928 int rtn_val = DDI_FAILURE; 929 mbx_cmd_t mbx_cmds = {0}; 930 931 mbx_cmds.mb[0] = MBC_SET_PORT_CONFIG /* 0x122 */; 932 mbx_cmds.mb[1] = new_cfg.link_cfg; 933 mbx_cmds.mb[2] = new_cfg.max_frame_size; 934 935 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 936 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 937 " failed.", __func__, qlge->instance); 938 goto out; 939 } 940 /* verify if the transaction is completed successful */ 941 if ((mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) && 942 (mbx_cmds.mb[0] != MBA_IDC_COMPLETE /* 0x8100 */)) { 943 cmn_err(CE_WARN, "set port config (%d) failed, 0x%x", 944 qlge->instance, mbx_cmds.mb[0]); 945 } else 946 rtn_val = DDI_SUCCESS; 947 out: 948 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 949 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 950 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 951 } 952 return (rtn_val); 953 } 954 955 int 956 ql_set_pause_mode(qlge_t *qlge) 957 { 958 uint32_t pause_bit_mask = 0x60; /* bit 5-6 */ 959 960 /* clear pause bits */ 961 qlge->port_cfg_info.link_cfg &= ~pause_bit_mask; 962 963 /* set new pause mode */ 964 if (qlge->pause == PAUSE_MODE_STANDARD) 965 qlge->port_cfg_info.link_cfg |= STD_PAUSE; 966 else if (qlge->pause == PAUSE_MODE_PER_PRIORITY) 967 qlge->port_cfg_info.link_cfg |= PP_PAUSE; 968 969 return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info)); 970 } 971 972 int 973 ql_set_loop_back_mode(qlge_t *qlge) 974 { 975 uint32_t loop_back_bit_mask = 0x0e; /* bit 1-3 */ 976 977 /* clear loop back bits */ 978 qlge->port_cfg_info.link_cfg &= ~loop_back_bit_mask; 979 /* loop back cfg: bit1-3 */ 980 if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_PARALLEL) 981 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_PARALLEL; 982 else if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_SERIAL) 983 qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_SERIAL; 984 else if (qlge->loop_back_mode == QLGE_LOOP_EXTERNAL_PHY) 985 qlge->port_cfg_info.link_cfg |= LOOP_EXTERNAL_PHY; 986 987 return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info)); 988 989 } 990 /* 991 * ql_get_port_cfg 992 * Get port configuration. 993 * mailbox cmd:0x123h 994 */ 995 int 996 ql_get_port_cfg(qlge_t *qlge) 997 { 998 int rtn_val = DDI_FAILURE; 999 mbx_cmd_t mbx_cmds = {0}; 1000 1001 mbx_cmds.mb[0] = MBC_GET_PORT_CONFIG /* 0x123 */; 1002 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) { 1003 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp" 1004 " failed.", __func__, qlge->instance); 1005 goto out; 1006 } 1007 /* verify if the transaction is completed successfully */ 1008 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1009 cmn_err(CE_WARN, "get port config (%d) failed, 0x%x", 1010 qlge->instance, mbx_cmds.mb[0]); 1011 } else { /* verify frame size */ 1012 if ((mbx_cmds.mb[2] == NORMAL_FRAME_SIZE) || 1013 (mbx_cmds.mb[2] == JUMBO_FRAME_SIZE)) { 1014 qlge->port_cfg_info.link_cfg = mbx_cmds.mb[1]; 1015 qlge->port_cfg_info.max_frame_size = mbx_cmds.mb[2]; 1016 QL_PRINT(DBG_MBX, ("link_cfg: 0x%x, max_frame_size:" 1017 " %d bytes\n", mbx_cmds.mb[1], mbx_cmds.mb[2])); 1018 rtn_val = DDI_SUCCESS; 1019 } else { 1020 cmn_err(CE_WARN, "bad link_cfg: 0x%x, max_frame_size:" 1021 " %d bytes", mbx_cmds.mb[1], mbx_cmds.mb[2]); 1022 } 1023 } 1024 out: 1025 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 1026 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 1027 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 1028 } 1029 return (rtn_val); 1030 } 1031 1032 /* 1033 * qlge_get_link_status 1034 * Get link status. 1035 * mailbox cmd:0x124h 1036 */ 1037 int 1038 qlge_get_link_status(qlge_t *qlge, 1039 struct qlnic_link_status_info *link_status_ptr) 1040 { 1041 int rtn_val = DDI_FAILURE; 1042 mbx_cmd_t mbx_cmds = {0}; 1043 1044 mbx_cmds.mb[0] = MBC_GET_LINK_STATUS /* 0x124 */; 1045 1046 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 1047 != DDI_SUCCESS) { 1048 cmn_err(CE_WARN, 1049 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 1050 __func__, qlge->instance); 1051 goto out; 1052 } 1053 /* verify if the transaction is completed successful */ 1054 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1055 cmn_err(CE_WARN, "get link status(%d) failed, 0x%x", 1056 qlge->instance, mbx_cmds.mb[0]); 1057 } else { 1058 /* EMPTY */ 1059 QL_PRINT(DBG_MBX, 1060 ("link status: status1 : 0x%x, status2 : 0x%x, " 1061 "status3 : 0x%x\n", 1062 mbx_cmds.mb[1], mbx_cmds.mb[2], mbx_cmds.mb[3])); 1063 } 1064 if (link_status_ptr != NULL) { 1065 link_status_ptr->link_status_info = mbx_cmds.mb[1]; 1066 link_status_ptr->additional_info = mbx_cmds.mb[2]; 1067 link_status_ptr->network_hw_info = mbx_cmds.mb[3]; 1068 link_status_ptr->dcbx_frame_counters_info = mbx_cmds.mb[4]; 1069 link_status_ptr->change_counters_info = mbx_cmds.mb[5]; 1070 } 1071 rtn_val = DDI_SUCCESS; 1072 out: 1073 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 1074 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 1075 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 1076 } 1077 return (rtn_val); 1078 } 1079 1080 /* 1081 * ql_get_firmware_version 1082 * Get firmware version. 1083 */ 1084 int 1085 ql_get_firmware_version(qlge_t *qlge, 1086 struct qlnic_mpi_version_info *mpi_version_ptr) 1087 { 1088 int rtn_val = DDI_FAILURE; 1089 mbx_cmd_t mbx_cmds = {0}; 1090 1091 mbx_cmds.mb[0] = MBC_ABOUT_FIRMWARE /* 0x08 */; 1092 1093 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) 1094 != DDI_SUCCESS) { 1095 cmn_err(CE_WARN, 1096 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.", 1097 __func__, qlge->instance); 1098 goto out; 1099 } 1100 1101 /* verify if the transaction is completed successful */ 1102 if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) { 1103 cmn_err(CE_WARN, "get firmware version(%d) failed, 0x%x", 1104 qlge->instance, mbx_cmds.mb[0]); 1105 } else { 1106 qlge->fw_version_info.major_version = 1107 LSB(MSW(mbx_cmds.mb[1])); 1108 qlge->fw_version_info.minor_version = 1109 MSB(LSW(mbx_cmds.mb[1])); 1110 qlge->fw_version_info.sub_minor_version = 1111 LSB(LSW(mbx_cmds.mb[1])); 1112 qlge->phy_version_info.major_version = 1113 LSB(MSW(mbx_cmds.mb[2])); 1114 qlge->phy_version_info.minor_version = 1115 MSB(LSW(mbx_cmds.mb[2])); 1116 qlge->phy_version_info.sub_minor_version = 1117 LSB(LSW(mbx_cmds.mb[2])); 1118 #ifdef QLGE_LOAD_UNLOAD 1119 cmn_err(CE_NOTE, "firmware version: %d.%d.%d\n", 1120 qlge->fw_version_info.major_version, 1121 qlge->fw_version_info.minor_version, 1122 qlge->fw_version_info.sub_minor_version); 1123 #endif 1124 if (mpi_version_ptr != NULL) { 1125 mpi_version_ptr->fw_version = 1126 (qlge->fw_version_info.major_version<<16) 1127 |(qlge->fw_version_info.minor_version<<8) 1128 |(qlge->fw_version_info.sub_minor_version); 1129 mpi_version_ptr->phy_version = 1130 (qlge->phy_version_info.major_version<<16) 1131 |(qlge->phy_version_info.minor_version<<8) 1132 |(qlge->phy_version_info.sub_minor_version); 1133 } 1134 } 1135 rtn_val = DDI_SUCCESS; 1136 out: 1137 if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) { 1138 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE); 1139 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); 1140 } 1141 return (rtn_val); 1142 } 1143 1144 /* 1145 * Trigger a system error event 1146 */ 1147 int 1148 ql_trigger_system_error_event(qlge_t *qlge) 1149 { 1150 mbx_cmd_t mbx_cmds = {0}; 1151 int rtn_val = DDI_FAILURE; 1152 1153 mbx_cmds.mb[0] = MBC_GENERATE_SYS_ERROR; /* 0x2A */ 1154 if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) { 1155 cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.", 1156 __func__, qlge->instance); 1157 goto out; 1158 } 1159 rtn_val = DDI_SUCCESS; 1160 out: 1161 return (rtn_val); 1162 } 1163 1164 /* 1165 * Reset the MPI RISC Processor 1166 */ 1167 int 1168 ql_reset_mpi_risc(qlge_t *qlge) 1169 { 1170 int rtn_val = DDI_FAILURE; 1171 1172 /* Reset the MPI Processor */ 1173 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_RESET); 1174 if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS, RISC_RESET, 1175 BIT_SET, 0) != DDI_SUCCESS) { 1176 (void) ql_read_reg(qlge, REG_HOST_CMD_STATUS); 1177 goto out; 1178 } 1179 ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_CLEAR_RISC_RESET); 1180 rtn_val = DDI_SUCCESS; 1181 out: 1182 return (rtn_val); 1183 } 1184 1185 int 1186 ql_read_risc_ram(qlge_t *qlge, uint32_t risc_address, uint64_t bp, 1187 uint32_t word_count) 1188 { 1189 int rval = DDI_FAILURE; 1190 mbx_cmd_t mc = {0}; 1191 mbx_cmd_t *mcp = &mc; 1192 mbx_data_t mbx_results; 1193 1194 QL_PRINT(DBG_MBX, ("%s(%d): read risc addr:0x%x," 1195 "phys_addr %x,%x words\n", __func__, qlge->instance, 1196 risc_address, bp, word_count)); 1197 if (CFG_IST(qlge, CFG_CHIP_8100)) { 1198 mcp->mb[0] = MBC_DUMP_RISC_RAM /* 0x0C */; 1199 mcp->mb[1] = LSW(risc_address); 1200 mcp->mb[2] = MSW(LSD(bp)); 1201 mcp->mb[3] = LSW(LSD(bp)); 1202 mcp->mb[4] = MSW(word_count); 1203 mcp->mb[5] = LSW(word_count); 1204 mcp->mb[6] = MSW(MSD(bp)); 1205 mcp->mb[7] = LSW(MSD(bp)); 1206 mcp->mb[8] = MSW(risc_address); 1207 } 1208 mcp->timeout = 10 /* MAILBOX_TOV */; 1209 1210 if (ql_issue_mailbox_cmd_and_poll_rsp(qlge, mcp, &mbx_results) 1211 != DDI_SUCCESS) { 1212 goto out; 1213 } else { 1214 QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received", 1215 __func__, qlge->instance)); 1216 if (mbx_results.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) { 1217 QL_PRINT(DBG_MBX, ("%s(%d): success\n", 1218 __func__, qlge->instance)); 1219 rval = DDI_SUCCESS; 1220 } else { 1221 cmn_err(CE_WARN, "read_risc_ram(%d): failed, status %x", 1222 qlge->instance, mbx_results.mb[0]); 1223 } 1224 } 1225 out: 1226 return (rval); 1227 } 1228