FILE
qla_mbx.c
File preview with syntax highlighting.
linux-6.19.14/drivers/scsi/qla2xxx/qla_mbx.c
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * QLogic Fibre Channel HBA Driver 4 * Copyright (c) 2003-2014 QLogic Corporation 5 */ 6#include "qla_def.h" 7#include "qla_target.h" 8 9#include <linux/delay.h> 10#include <linux/gfp.h> 11 12#ifdef CONFIG_PPC 13#define IS_PPCARCH true 14#else 15#define IS_PPCARCH false 16#endif 17 18static struct mb_cmd_name { 19 uint16_t cmd; 20 const char *str; 21} mb_str[] = { 22 {MBC_GET_PORT_DATABASE, "GPDB"}, 23 {MBC_GET_ID_LIST, "GIDList"}, 24 {MBC_GET_LINK_PRIV_STATS, "Stats"}, 25 {MBC_GET_RESOURCE_COUNTS, "ResCnt"}, 26}; 27 28static const char *mb_to_str(uint16_t cmd) 29{ 30 int i; 31 struct mb_cmd_name *e; 32 33 for (i = 0; i < ARRAY_SIZE(mb_str); i++) { 34 e = mb_str + i; 35 if (cmd == e->cmd) 36 return e->str; 37 } 38 return "unknown"; 39} 40 41static struct rom_cmd { 42 uint16_t cmd; 43} rom_cmds[] = { 44 { MBC_LOAD_RAM }, 45 { MBC_EXECUTE_FIRMWARE }, 46 { MBC_READ_RAM_WORD }, 47 { MBC_MAILBOX_REGISTER_TEST }, 48 { MBC_VERIFY_CHECKSUM }, 49 { MBC_GET_FIRMWARE_VERSION }, 50 { MBC_LOAD_RISC_RAM }, 51 { MBC_DUMP_RISC_RAM }, 52 { MBC_LOAD_RISC_RAM_EXTENDED }, 53 { MBC_DUMP_RISC_RAM_EXTENDED }, 54 { MBC_WRITE_RAM_WORD_EXTENDED }, 55 { MBC_READ_RAM_EXTENDED }, 56 { MBC_GET_RESOURCE_COUNTS }, 57 { MBC_SET_FIRMWARE_OPTION }, 58 { MBC_MID_INITIALIZE_FIRMWARE }, 59 { MBC_GET_FIRMWARE_STATE }, 60 { MBC_GET_MEM_OFFLOAD_CNTRL_STAT }, 61 { MBC_GET_RETRY_COUNT }, 62 { MBC_TRACE_CONTROL }, 63 { MBC_INITIALIZE_MULTIQ }, 64 { MBC_IOCB_COMMAND_A64 }, 65 { MBC_GET_ADAPTER_LOOP_ID }, 66 { MBC_READ_SFP }, 67 { MBC_SET_RNID_PARAMS }, 68 { MBC_GET_RNID_PARAMS }, 69 { MBC_GET_SET_ZIO_THRESHOLD }, 70}; 71 72static int is_rom_cmd(uint16_t cmd) 73{ 74 int i; 75 struct rom_cmd *wc; 76 77 for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) { 78 wc = rom_cmds + i; 79 if (wc->cmd == cmd) 80 return 1; 81 } 82 83 return 0; 84} 85 86/* 87 * qla2x00_mailbox_command 88 * Issue mailbox command and waits for completion. 89 * 90 * Input: 91 * ha = adapter block pointer. 92 * mcp = driver internal mbx struct pointer. 93 * 94 * Output: 95 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data. 96 * 97 * Returns: 98 * 0 : QLA_SUCCESS = cmd performed success 99 * 1 : QLA_FUNCTION_FAILED (error encountered) 100 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered) 101 * 102 * Context: 103 * Kernel context. 104 */ 105static int 106qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) 107{ 108 int rval, i; 109 unsigned long flags = 0; 110 device_reg_t *reg; 111 uint8_t abort_active, eeh_delay; 112 uint8_t io_lock_on; 113 uint16_t command = 0; 114 uint16_t *iptr; 115 __le16 __iomem *optr; 116 uint32_t cnt; 117 uint32_t mboxes; 118 unsigned long wait_time; 119 struct qla_hw_data *ha = vha->hw; 120 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 121 u32 chip_reset; 122 123 124 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__); 125 126 if (ha->pdev->error_state == pci_channel_io_perm_failure) { 127 ql_log(ql_log_warn, vha, 0x1001, 128 "PCI channel failed permanently, exiting.\n"); 129 return QLA_FUNCTION_TIMEOUT; 130 } 131 132 if (vha->device_flags & DFLG_DEV_FAILED) { 133 ql_log(ql_log_warn, vha, 0x1002, 134 "Device in failed state, exiting.\n"); 135 return QLA_FUNCTION_TIMEOUT; 136 } 137 138 /* if PCI error, then avoid mbx processing.*/ 139 if (test_bit(PFLG_DISCONNECTED, &base_vha->dpc_flags) && 140 test_bit(UNLOADING, &base_vha->dpc_flags)) { 141 ql_log(ql_log_warn, vha, 0xd04e, 142 "PCI error, exiting.\n"); 143 return QLA_FUNCTION_TIMEOUT; 144 } 145 eeh_delay = 0; 146 reg = ha->iobase; 147 io_lock_on = base_vha->flags.init_done; 148 149 rval = QLA_SUCCESS; 150 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); 151 chip_reset = ha->chip_reset; 152 153 if (ha->flags.pci_channel_io_perm_failure) { 154 ql_log(ql_log_warn, vha, 0x1003, 155 "Perm failure on EEH timeout MBX, exiting.\n"); 156 return QLA_FUNCTION_TIMEOUT; 157 } 158 159 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) { 160 /* Setting Link-Down error */ 161 mcp->mb[0] = MBS_LINK_DOWN_ERROR; 162 ql_log(ql_log_warn, vha, 0x1004, 163 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung); 164 return QLA_FUNCTION_TIMEOUT; 165 } 166 167 /* check if ISP abort is active and return cmd with timeout */ 168 if (((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || 169 test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || 170 test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) && 171 !is_rom_cmd(mcp->mb[0])) || ha->flags.eeh_busy) { 172 ql_log(ql_log_info, vha, 0x1005, 173 "Cmd 0x%x aborted with timeout since ISP Abort is pending\n", 174 mcp->mb[0]); 175 return QLA_FUNCTION_TIMEOUT; 176 } 177 178 atomic_inc(&ha->num_pend_mbx_stage1); 179 /* 180 * Wait for active mailbox commands to finish by waiting at most tov 181 * seconds. This is to serialize actual issuing of mailbox cmds during 182 * non ISP abort time. 183 */ 184 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) { 185 /* Timeout occurred. Return error. */ 186 ql_log(ql_log_warn, vha, 0xd035, 187 "Cmd access timeout, cmd=0x%x, Exiting.\n", 188 mcp->mb[0]); 189 vha->hw_err_cnt++; 190 atomic_dec(&ha->num_pend_mbx_stage1); 191 return QLA_FUNCTION_TIMEOUT; 192 } 193 atomic_dec(&ha->num_pend_mbx_stage1); 194 if (ha->flags.purge_mbox || chip_reset != ha->chip_reset || 195 ha->flags.eeh_busy) { 196 ql_log(ql_log_warn, vha, 0xd035, 197 "Purge mbox: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n", 198 ha->flags.purge_mbox, ha->flags.eeh_busy, mcp->mb[0]); 199 rval = QLA_ABORTED; 200 goto premature_exit; 201 } 202 203 204 /* Save mailbox command for debug */ 205 ha->mcp = mcp; 206 207 ql_dbg(ql_dbg_mbx, vha, 0x1006, 208 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]); 209 210 spin_lock_irqsave(&ha->hardware_lock, flags); 211 212 if (ha->flags.purge_mbox || chip_reset != ha->chip_reset || 213 ha->flags.mbox_busy) { 214 rval = QLA_ABORTED; 215 spin_unlock_irqrestore(&ha->hardware_lock, flags); 216 goto premature_exit; 217 } 218 ha->flags.mbox_busy = 1; 219 220 /* Load mailbox registers. */ 221 if (IS_P3P_TYPE(ha)) 222 optr = ®->isp82.mailbox_in[0]; 223 else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) 224 optr = ®->isp24.mailbox0; 225 else 226 optr = MAILBOX_REG(ha, ®->isp, 0); 227 228 iptr = mcp->mb; 229 command = mcp->mb[0]; 230 mboxes = mcp->out_mb; 231 232 ql_dbg(ql_dbg_mbx, vha, 0x1111, 233 "Mailbox registers (OUT):\n"); 234 for (cnt = 0; cnt < ha->mbx_count; cnt++) { 235 if (IS_QLA2200(ha) && cnt == 8) 236 optr = MAILBOX_REG(ha, ®->isp, 8); 237 if (mboxes & BIT_0) { 238 ql_dbg(ql_dbg_mbx, vha, 0x1112, 239 "mbox[%d]<-0x%04x\n", cnt, *iptr); 240 wrt_reg_word(optr, *iptr); 241 } else { 242 wrt_reg_word(optr, 0); 243 } 244 245 mboxes >>= 1; 246 optr++; 247 iptr++; 248 } 249 250 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117, 251 "I/O Address = %p.\n", optr); 252 253 /* Issue set host interrupt command to send cmd out. */ 254 ha->flags.mbox_int = 0; 255 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 256 reinit_completion(&ha->mbx_intr_comp); 257 258 /* Unlock mbx registers and wait for interrupt */ 259 ql_dbg(ql_dbg_mbx, vha, 0x100f, 260 "Going to unlock irq & waiting for interrupts. " 261 "jiffies=%lx.\n", jiffies); 262 263 /* Wait for mbx cmd completion until timeout */ 264 atomic_inc(&ha->num_pend_mbx_stage2); 265 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) { 266 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 267 268 if (IS_P3P_TYPE(ha)) 269 wrt_reg_dword(®->isp82.hint, HINT_MBX_INT_PENDING); 270 else if (IS_FWI2_CAPABLE(ha)) 271 wrt_reg_dword(®->isp24.hccr, HCCRX_SET_HOST_INT); 272 else 273 wrt_reg_word(®->isp.hccr, HCCR_SET_HOST_INT); 274 spin_unlock_irqrestore(&ha->hardware_lock, flags); 275 276 wait_time = jiffies; 277 if (!wait_for_completion_timeout(&ha->mbx_intr_comp, 278 mcp->tov * HZ)) { 279 ql_dbg(ql_dbg_mbx, vha, 0x117a, 280 "cmd=%x Timeout.\n", command); 281 spin_lock_irqsave(&ha->hardware_lock, flags); 282 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 283 reinit_completion(&ha->mbx_intr_comp); 284 spin_unlock_irqrestore(&ha->hardware_lock, flags); 285 286 if (chip_reset != ha->chip_reset) { 287 eeh_delay = ha->flags.eeh_busy ? 1 : 0; 288 289 spin_lock_irqsave(&ha->hardware_lock, flags); 290 ha->flags.mbox_busy = 0; 291 spin_unlock_irqrestore(&ha->hardware_lock, 292 flags); 293 atomic_dec(&ha->num_pend_mbx_stage2); 294 rval = QLA_ABORTED; 295 goto premature_exit; 296 } 297 } else if (ha->flags.purge_mbox || 298 chip_reset != ha->chip_reset) { 299 eeh_delay = ha->flags.eeh_busy ? 1 : 0; 300 301 spin_lock_irqsave(&ha->hardware_lock, flags); 302 ha->flags.mbox_busy = 0; 303 spin_unlock_irqrestore(&ha->hardware_lock, flags); 304 atomic_dec(&ha->num_pend_mbx_stage2); 305 rval = QLA_ABORTED; 306 goto premature_exit; 307 } 308 309 if (time_after(jiffies, wait_time + 5 * HZ)) 310 ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n", 311 command, jiffies_to_msecs(jiffies - wait_time)); 312 } else { 313 ql_dbg(ql_dbg_mbx, vha, 0x1011, 314 "Cmd=%x Polling Mode.\n", command); 315 316 if (IS_P3P_TYPE(ha)) { 317 if (rd_reg_dword(®->isp82.hint) & 318 HINT_MBX_INT_PENDING) { 319 ha->flags.mbox_busy = 0; 320 spin_unlock_irqrestore(&ha->hardware_lock, 321 flags); 322 atomic_dec(&ha->num_pend_mbx_stage2); 323 ql_dbg(ql_dbg_mbx, vha, 0x1012, 324 "Pending mailbox timeout, exiting.\n"); 325 vha->hw_err_cnt++; 326 rval = QLA_FUNCTION_TIMEOUT; 327 goto premature_exit; 328 } 329 wrt_reg_dword(®->isp82.hint, HINT_MBX_INT_PENDING); 330 } else if (IS_FWI2_CAPABLE(ha)) 331 wrt_reg_dword(®->isp24.hccr, HCCRX_SET_HOST_INT); 332 else 333 wrt_reg_word(®->isp.hccr, HCCR_SET_HOST_INT); 334 spin_unlock_irqrestore(&ha->hardware_lock, flags); 335 336 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */ 337 while (!ha->flags.mbox_int) { 338 if (ha->flags.purge_mbox || 339 chip_reset != ha->chip_reset) { 340 eeh_delay = ha->flags.eeh_busy ? 1 : 0; 341 342 spin_lock_irqsave(&ha->hardware_lock, flags); 343 ha->flags.mbox_busy = 0; 344 spin_unlock_irqrestore(&ha->hardware_lock, 345 flags); 346 atomic_dec(&ha->num_pend_mbx_stage2); 347 rval = QLA_ABORTED; 348 goto premature_exit; 349 } 350 351 if (time_after(jiffies, wait_time)) 352 break; 353 354 /* Check for pending interrupts. */ 355 qla2x00_poll(ha->rsp_q_map[0]); 356 357 if (!ha->flags.mbox_int && 358 !(IS_QLA2200(ha) && 359 command == MBC_LOAD_RISC_RAM_EXTENDED)) 360 msleep(10); 361 } /* while */ 362 ql_dbg(ql_dbg_mbx, vha, 0x1013, 363 "Waited %d sec.\n", 364 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ)); 365 } 366 atomic_dec(&ha->num_pend_mbx_stage2); 367 368 /* Check whether we timed out */ 369 if (ha->flags.mbox_int) { 370 uint16_t *iptr2; 371 372 ql_dbg(ql_dbg_mbx, vha, 0x1014, 373 "Cmd=%x completed.\n", command); 374 375 /* Got interrupt. Clear the flag. */ 376 ha->flags.mbox_int = 0; 377 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 378 379 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) { 380 spin_lock_irqsave(&ha->hardware_lock, flags); 381 ha->flags.mbox_busy = 0; 382 spin_unlock_irqrestore(&ha->hardware_lock, flags); 383 384 /* Setting Link-Down error */ 385 mcp->mb[0] = MBS_LINK_DOWN_ERROR; 386 ha->mcp = NULL; 387 rval = QLA_FUNCTION_FAILED; 388 ql_log(ql_log_warn, vha, 0xd048, 389 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung); 390 goto premature_exit; 391 } 392 393 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) { 394 ql_dbg(ql_dbg_mbx, vha, 0x11ff, 395 "mb_out[0] = %#x <> %#x\n", ha->mailbox_out[0], 396 MBS_COMMAND_COMPLETE); 397 rval = QLA_FUNCTION_FAILED; 398 } 399 400 /* Load return mailbox registers. */ 401 iptr2 = mcp->mb; 402 iptr = (uint16_t *)&ha->mailbox_out[0]; 403 mboxes = mcp->in_mb; 404 405 ql_dbg(ql_dbg_mbx, vha, 0x1113, 406 "Mailbox registers (IN):\n"); 407 for (cnt = 0; cnt < ha->mbx_count; cnt++) { 408 if (mboxes & BIT_0) { 409 *iptr2 = *iptr; 410 ql_dbg(ql_dbg_mbx, vha, 0x1114, 411 "mbox[%d]->0x%04x\n", cnt, *iptr2); 412 } 413 414 mboxes >>= 1; 415 iptr2++; 416 iptr++; 417 } 418 } else { 419 420 uint16_t mb[8]; 421 uint32_t ictrl, host_status, hccr; 422 uint16_t w; 423 424 if (IS_FWI2_CAPABLE(ha)) { 425 mb[0] = rd_reg_word(®->isp24.mailbox0); 426 mb[1] = rd_reg_word(®->isp24.mailbox1); 427 mb[2] = rd_reg_word(®->isp24.mailbox2); 428 mb[3] = rd_reg_word(®->isp24.mailbox3); 429 mb[7] = rd_reg_word(®->isp24.mailbox7); 430 ictrl = rd_reg_dword(®->isp24.ictrl); 431 host_status = rd_reg_dword(®->isp24.host_status); 432 hccr = rd_reg_dword(®->isp24.hccr); 433 434 ql_log(ql_log_warn, vha, 0xd04c, 435 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx " 436 "mb[0-3]=[0x%x 0x%x 0x%x 0x%x] mb7 0x%x host_status 0x%x hccr 0x%x\n", 437 command, ictrl, jiffies, mb[0], mb[1], mb[2], mb[3], 438 mb[7], host_status, hccr); 439 vha->hw_err_cnt++; 440 441 } else { 442 mb[0] = RD_MAILBOX_REG(ha, ®->isp, 0); 443 ictrl = rd_reg_word(®->isp.ictrl); 444 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119, 445 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx " 446 "mb[0]=0x%x\n", command, ictrl, jiffies, mb[0]); 447 vha->hw_err_cnt++; 448 } 449 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019); 450 451 /* Capture FW dump only, if PCI device active */ 452 if (!pci_channel_offline(vha->hw->pdev)) { 453 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); 454 if (w == 0xffff || ictrl == 0xffffffff || 455 (chip_reset != ha->chip_reset)) { 456 /* This is special case if there is unload 457 * of driver happening and if PCI device go 458 * into bad state due to PCI error condition 459 * then only PCI ERR flag would be set. 460 * we will do premature exit for above case. 461 */ 462 spin_lock_irqsave(&ha->hardware_lock, flags); 463 ha->flags.mbox_busy = 0; 464 spin_unlock_irqrestore(&ha->hardware_lock, 465 flags); 466 rval = QLA_FUNCTION_TIMEOUT; 467 goto premature_exit; 468 } 469 470 /* Attempt to capture firmware dump for further 471 * anallysis of the current formware state. we do not 472 * need to do this if we are intentionally generating 473 * a dump 474 */ 475 if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) 476 qla2xxx_dump_fw(vha); 477 rval = QLA_FUNCTION_TIMEOUT; 478 } 479 } 480 spin_lock_irqsave(&ha->hardware_lock, flags); 481 ha->flags.mbox_busy = 0; 482 spin_unlock_irqrestore(&ha->hardware_lock, flags); 483 484 /* Clean up */ 485 ha->mcp = NULL; 486 487 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) { 488 ql_dbg(ql_dbg_mbx, vha, 0x101a, 489 "Checking for additional resp interrupt.\n"); 490 491 /* polling mode for non isp_abort commands. */ 492 qla2x00_poll(ha->rsp_q_map[0]); 493 } 494 495 if (rval == QLA_FUNCTION_TIMEOUT && 496 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { 497 if (!io_lock_on || (mcp->flags & IOCTL_CMD) || 498 ha->flags.eeh_busy) { 499 /* not in dpc. schedule it for dpc to take over. */ 500 ql_dbg(ql_dbg_mbx, vha, 0x101b, 501 "Timeout, schedule isp_abort_needed.\n"); 502 503 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && 504 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && 505 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { 506 if (IS_QLA82XX(ha)) { 507 ql_dbg(ql_dbg_mbx, vha, 0x112a, 508 "disabling pause transmit on port " 509 "0 & 1.\n"); 510 qla82xx_wr_32(ha, 511 QLA82XX_CRB_NIU + 0x98, 512 CRB_NIU_XG_PAUSE_CTL_P0| 513 CRB_NIU_XG_PAUSE_CTL_P1); 514 } 515 ql_log(ql_log_info, base_vha, 0x101c, 516 "Mailbox cmd timeout occurred, cmd=0x%x, " 517 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP " 518 "abort.\n", command, mcp->mb[0], 519 ha->flags.eeh_busy); 520 vha->hw_err_cnt++; 521 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 522 qla2xxx_wake_dpc(vha); 523 } 524 } else if (current == ha->dpc_thread) { 525 /* call abort directly since we are in the DPC thread */ 526 ql_dbg(ql_dbg_mbx, vha, 0x101d, 527 "Timeout, calling abort_isp.\n"); 528 529 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && 530 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && 531 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { 532 if (IS_QLA82XX(ha)) { 533 ql_dbg(ql_dbg_mbx, vha, 0x112b, 534 "disabling pause transmit on port " 535 "0 & 1.\n"); 536 qla82xx_wr_32(ha, 537 QLA82XX_CRB_NIU + 0x98, 538 CRB_NIU_XG_PAUSE_CTL_P0| 539 CRB_NIU_XG_PAUSE_CTL_P1); 540 } 541 ql_log(ql_log_info, base_vha, 0x101e, 542 "Mailbox cmd timeout occurred, cmd=0x%x, " 543 "mb[0]=0x%x. Scheduling ISP abort ", 544 command, mcp->mb[0]); 545 vha->hw_err_cnt++; 546 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); 547 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 548 /* Allow next mbx cmd to come in. */ 549 complete(&ha->mbx_cmd_comp); 550 if (ha->isp_ops->abort_isp(vha) && 551 !ha->flags.eeh_busy) { 552 /* Failed. retry later. */ 553 set_bit(ISP_ABORT_NEEDED, 554 &vha->dpc_flags); 555 } 556 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); 557 ql_dbg(ql_dbg_mbx, vha, 0x101f, 558 "Finished abort_isp.\n"); 559 goto mbx_done; 560 } 561 } 562 } 563 564premature_exit: 565 /* Allow next mbx cmd to come in. */ 566 complete(&ha->mbx_cmd_comp); 567 568mbx_done: 569 if (rval == QLA_ABORTED) { 570 ql_log(ql_log_info, vha, 0xd035, 571 "Chip Reset in progress. Purging Mbox cmd=0x%x.\n", 572 mcp->mb[0]); 573 } else if (rval) { 574 if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) { 575 pr_warn("%s [%s]-%04x:%ld: **** Failed=%x", QL_MSGHDR, 576 dev_name(&ha->pdev->dev), 0x1020+0x800, 577 vha->host_no, rval); 578 mboxes = mcp->in_mb; 579 cnt = 4; 580 for (i = 0; i < ha->mbx_count && cnt; i++, mboxes >>= 1) 581 if (mboxes & BIT_0) { 582 printk(" mb[%u]=%x", i, mcp->mb[i]); 583 cnt--; 584 } 585 pr_warn(" cmd=%x ****\n", command); 586 } 587 if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) { 588 ql_dbg(ql_dbg_mbx, vha, 0x1198, 589 "host_status=%#x intr_ctrl=%#x intr_status=%#x\n", 590 rd_reg_dword(®->isp24.host_status), 591 rd_reg_dword(®->isp24.ictrl), 592 rd_reg_dword(®->isp24.istatus)); 593 } else { 594 ql_dbg(ql_dbg_mbx, vha, 0x1206, 595 "ctrl_status=%#x ictrl=%#x istatus=%#x\n", 596 rd_reg_word(®->isp.ctrl_status), 597 rd_reg_word(®->isp.ictrl), 598 rd_reg_word(®->isp.istatus)); 599 } 600 } else { 601 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); 602 } 603 604 i = 500; 605 while (i && eeh_delay && (ha->pci_error_state < QLA_PCI_SLOT_RESET)) { 606 /* 607 * The caller of this mailbox encounter pci error. 608 * Hold the thread until PCIE link reset complete to make 609 * sure caller does not unmap dma while recovery is 610 * in progress. 611 */ 612 msleep(1); 613 i--; 614 } 615 return rval; 616} 617 618int 619qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, 620 uint32_t risc_code_size) 621{ 622 int rval; 623 struct qla_hw_data *ha = vha->hw; 624 mbx_cmd_t mc; 625 mbx_cmd_t *mcp = &mc; 626 627 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022, 628 "Entered %s.\n", __func__); 629 630 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) { 631 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED; 632 mcp->mb[8] = MSW(risc_addr); 633 mcp->out_mb = MBX_8|MBX_0; 634 } else { 635 mcp->mb[0] = MBC_LOAD_RISC_RAM; 636 mcp->out_mb = MBX_0; 637 } 638 mcp->mb[1] = LSW(risc_addr); 639 mcp->mb[2] = MSW(req_dma); 640 mcp->mb[3] = LSW(req_dma); 641 mcp->mb[6] = MSW(MSD(req_dma)); 642 mcp->mb[7] = LSW(MSD(req_dma)); 643 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1; 644 if (IS_FWI2_CAPABLE(ha)) { 645 mcp->mb[4] = MSW(risc_code_size); 646 mcp->mb[5] = LSW(risc_code_size); 647 mcp->out_mb |= MBX_5|MBX_4; 648 } else { 649 mcp->mb[4] = LSW(risc_code_size); 650 mcp->out_mb |= MBX_4; 651 } 652 653 mcp->in_mb = MBX_1|MBX_0; 654 mcp->tov = MBX_TOV_SECONDS; 655 mcp->flags = 0; 656 rval = qla2x00_mailbox_command(vha, mcp); 657 658 if (rval != QLA_SUCCESS) { 659 ql_dbg(ql_dbg_mbx, vha, 0x1023, 660 "Failed=%x mb[0]=%x mb[1]=%x.\n", 661 rval, mcp->mb[0], mcp->mb[1]); 662 vha->hw_err_cnt++; 663 } else { 664 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024, 665 "Done %s.\n", __func__); 666 } 667 668 return rval; 669} 670 671#define NVME_ENABLE_FLAG BIT_3 672#define EDIF_HW_SUPPORT BIT_10 673 674/* 675 * qla2x00_execute_fw 676 * Start adapter firmware. 677 * 678 * Input: 679 * ha = adapter block pointer. 680 * TARGET_QUEUE_LOCK must be released. 681 * ADAPTER_STATE_LOCK must be released. 682 * 683 * Returns: 684 * qla2x00 local function return status code. 685 * 686 * Context: 687 * Kernel context. 688 */ 689int 690qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) 691{ 692 int rval; 693 struct qla_hw_data *ha = vha->hw; 694 mbx_cmd_t mc; 695 mbx_cmd_t *mcp = &mc; 696 u8 semaphore = 0; 697#define EXE_FW_FORCE_SEMAPHORE BIT_7 698 u8 retry = 5; 699 700 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025, 701 "Entered %s.\n", __func__); 702 703again: 704 mcp->mb[0] = MBC_EXECUTE_FIRMWARE; 705 mcp->out_mb = MBX_0; 706 mcp->in_mb = MBX_0; 707 if (IS_FWI2_CAPABLE(ha)) { 708 mcp->mb[1] = MSW(risc_addr); 709 mcp->mb[2] = LSW(risc_addr); 710 mcp->mb[3] = 0; 711 mcp->mb[4] = 0; 712 mcp->mb[11] = 0; 713 714 /* Enable BPM? */ 715 if (ha->flags.lr_detected) { 716 mcp->mb[4] = BIT_0; 717 if (IS_BPM_RANGE_CAPABLE(ha)) 718 mcp->mb[4] |= 719 ha->lr_distance << LR_DIST_FW_POS; 720 } 721 722 if (ql2xnvmeenable && (IS_QLA27XX(ha) || IS_QLA28XX(ha))) 723 mcp->mb[4] |= NVME_ENABLE_FLAG; 724 725 if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 726 struct nvram_81xx *nv = ha->nvram; 727 /* set minimum speed if specified in nvram */ 728 if (nv->min_supported_speed >= 2 && 729 nv->min_supported_speed <= 5) { 730 mcp->mb[4] |= BIT_4; 731 mcp->mb[11] |= nv->min_supported_speed & 0xF; 732 mcp->out_mb |= MBX_11; 733 mcp->in_mb |= BIT_5; 734 vha->min_supported_speed = 735 nv->min_supported_speed; 736 } 737 738 if (IS_PPCARCH) 739 mcp->mb[11] |= BIT_4; 740 } 741 742 if (ha->flags.exlogins_enabled) 743 mcp->mb[4] |= ENABLE_EXTENDED_LOGIN; 744 745 if (ha->flags.exchoffld_enabled) 746 mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD; 747 748 if (semaphore) 749 mcp->mb[11] |= EXE_FW_FORCE_SEMAPHORE; 750 751 mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11; 752 mcp->in_mb |= MBX_5 | MBX_3 | MBX_2 | MBX_1; 753 } else { 754 mcp->mb[1] = LSW(risc_addr); 755 mcp->out_mb |= MBX_1; 756 if (IS_QLA2322(ha) || IS_QLA6322(ha)) { 757 mcp->mb[2] = 0; 758 mcp->out_mb |= MBX_2; 759 } 760 } 761 762 mcp->tov = MBX_TOV_SECONDS; 763 mcp->flags = 0; 764 rval = qla2x00_mailbox_command(vha, mcp); 765 766 if (rval != QLA_SUCCESS) { 767 if (IS_QLA28XX(ha) && rval == QLA_COMMAND_ERROR && 768 mcp->mb[1] == 0x27 && retry) { 769 semaphore = 1; 770 retry--; 771 ql_dbg(ql_dbg_async, vha, 0x1026, 772 "Exe FW: force semaphore.\n"); 773 goto again; 774 } 775 776 if (retry) { 777 retry--; 778 ql_dbg(ql_dbg_async, vha, 0x509d, 779 "Exe FW retry: mb[0]=%x retry[%d]\n", mcp->mb[0], retry); 780 goto again; 781 } 782 ql_dbg(ql_dbg_mbx, vha, 0x1026, 783 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 784 vha->hw_err_cnt++; 785 return rval; 786 } 787 788 if (!IS_FWI2_CAPABLE(ha)) 789 goto done; 790 791 ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2]; 792 ql_dbg(ql_dbg_mbx, vha, 0x119a, 793 "fw_ability_mask=%x.\n", ha->fw_ability_mask); 794 ql_dbg(ql_dbg_mbx, vha, 0x1027, "exchanges=%x.\n", mcp->mb[1]); 795 if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 796 ha->max_supported_speed = mcp->mb[2] & (BIT_0|BIT_1); 797 ql_dbg(ql_dbg_mbx, vha, 0x119b, "max_supported_speed=%s.\n", 798 ha->max_supported_speed == 0 ? "16Gps" : 799 ha->max_supported_speed == 1 ? "32Gps" : 800 ha->max_supported_speed == 2 ? "64Gps" : "unknown"); 801 if (vha->min_supported_speed) { 802 ha->min_supported_speed = mcp->mb[5] & 803 (BIT_0 | BIT_1 | BIT_2); 804 ql_dbg(ql_dbg_mbx, vha, 0x119c, 805 "min_supported_speed=%s.\n", 806 ha->min_supported_speed == 6 ? "64Gps" : 807 ha->min_supported_speed == 5 ? "32Gps" : 808 ha->min_supported_speed == 4 ? "16Gps" : 809 ha->min_supported_speed == 3 ? "8Gps" : 810 ha->min_supported_speed == 2 ? "4Gps" : "unknown"); 811 } 812 } 813 814 if (IS_QLA28XX(ha) && (mcp->mb[5] & EDIF_HW_SUPPORT)) { 815 ha->flags.edif_hw = 1; 816 ql_log(ql_log_info, vha, 0xffff, 817 "%s: edif HW\n", __func__); 818 } 819 820done: 821 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028, 822 "Done %s.\n", __func__); 823 824 return rval; 825} 826 827/* 828 * qla_get_exlogin_status 829 * Get extended login status 830 * uses the memory offload control/status Mailbox 831 * 832 * Input: 833 * ha: adapter state pointer. 834 * fwopt: firmware options 835 * 836 * Returns: 837 * qla2x00 local function status 838 * 839 * Context: 840 * Kernel context. 841 */ 842#define FETCH_XLOGINS_STAT 0x8 843int 844qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz, 845 uint16_t *ex_logins_cnt) 846{ 847 int rval; 848 mbx_cmd_t mc; 849 mbx_cmd_t *mcp = &mc; 850 851 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f, 852 "Entered %s\n", __func__); 853 854 memset(mcp->mb, 0 , sizeof(mcp->mb)); 855 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT; 856 mcp->mb[1] = FETCH_XLOGINS_STAT; 857 mcp->out_mb = MBX_1|MBX_0; 858 mcp->in_mb = MBX_10|MBX_4|MBX_0; 859 mcp->tov = MBX_TOV_SECONDS; 860 mcp->flags = 0; 861 862 rval = qla2x00_mailbox_command(vha, mcp); 863 if (rval != QLA_SUCCESS) { 864 ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval); 865 } else { 866 *buf_sz = mcp->mb[4]; 867 *ex_logins_cnt = mcp->mb[10]; 868 869 ql_log(ql_log_info, vha, 0x1190, 870 "buffer size 0x%x, exchange login count=%d\n", 871 mcp->mb[4], mcp->mb[10]); 872 873 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116, 874 "Done %s.\n", __func__); 875 } 876 877 return rval; 878} 879 880/* 881 * qla_set_exlogin_mem_cfg 882 * set extended login memory configuration 883 * Mbx needs to be issues before init_cb is set 884 * 885 * Input: 886 * ha: adapter state pointer. 887 * buffer: buffer pointer 888 * phys_addr: physical address of buffer 889 * size: size of buffer 890 * TARGET_QUEUE_LOCK must be released 891 * ADAPTER_STATE_LOCK must be release 892 * 893 * Returns: 894 * qla2x00 local funxtion status code. 895 * 896 * Context: 897 * Kernel context. 898 */ 899#define CONFIG_XLOGINS_MEM 0x9 900int 901qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr) 902{ 903 int rval; 904 mbx_cmd_t mc; 905 mbx_cmd_t *mcp = &mc; 906 struct qla_hw_data *ha = vha->hw; 907 908 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a, 909 "Entered %s.\n", __func__); 910 911 memset(mcp->mb, 0 , sizeof(mcp->mb)); 912 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT; 913 mcp->mb[1] = CONFIG_XLOGINS_MEM; 914 mcp->mb[2] = MSW(phys_addr); 915 mcp->mb[3] = LSW(phys_addr); 916 mcp->mb[6] = MSW(MSD(phys_addr)); 917 mcp->mb[7] = LSW(MSD(phys_addr)); 918 mcp->mb[8] = MSW(ha->exlogin_size); 919 mcp->mb[9] = LSW(ha->exlogin_size); 920 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 921 mcp->in_mb = MBX_11|MBX_0; 922 mcp->tov = MBX_TOV_SECONDS; 923 mcp->flags = 0; 924 rval = qla2x00_mailbox_command(vha, mcp); 925 if (rval != QLA_SUCCESS) { 926 ql_dbg(ql_dbg_mbx, vha, 0x111b, 927 "EXlogin Failed=%x. MB0=%x MB11=%x\n", 928 rval, mcp->mb[0], mcp->mb[11]); 929 } else { 930 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c, 931 "Done %s.\n", __func__); 932 } 933 934 return rval; 935} 936 937/* 938 * qla_get_exchoffld_status 939 * Get exchange offload status 940 * uses the memory offload control/status Mailbox 941 * 942 * Input: 943 * ha: adapter state pointer. 944 * fwopt: firmware options 945 * 946 * Returns: 947 * qla2x00 local function status 948 * 949 * Context: 950 * Kernel context. 951 */ 952#define FETCH_XCHOFFLD_STAT 0x2 953int 954qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz, 955 uint16_t *ex_logins_cnt) 956{ 957 int rval; 958 mbx_cmd_t mc; 959 mbx_cmd_t *mcp = &mc; 960 961 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019, 962 "Entered %s\n", __func__); 963 964 memset(mcp->mb, 0 , sizeof(mcp->mb)); 965 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT; 966 mcp->mb[1] = FETCH_XCHOFFLD_STAT; 967 mcp->out_mb = MBX_1|MBX_0; 968 mcp->in_mb = MBX_10|MBX_4|MBX_0; 969 mcp->tov = MBX_TOV_SECONDS; 970 mcp->flags = 0; 971 972 rval = qla2x00_mailbox_command(vha, mcp); 973 if (rval != QLA_SUCCESS) { 974 ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval); 975 } else { 976 *buf_sz = mcp->mb[4]; 977 *ex_logins_cnt = mcp->mb[10]; 978 979 ql_log(ql_log_info, vha, 0x118e, 980 "buffer size 0x%x, exchange offload count=%d\n", 981 mcp->mb[4], mcp->mb[10]); 982 983 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156, 984 "Done %s.\n", __func__); 985 } 986 987 return rval; 988} 989 990/* 991 * qla_set_exchoffld_mem_cfg 992 * Set exchange offload memory configuration 993 * Mbx needs to be issues before init_cb is set 994 * 995 * Input: 996 * ha: adapter state pointer. 997 * buffer: buffer pointer 998 * phys_addr: physical address of buffer 999 * size: size of buffer 1000 * TARGET_QUEUE_LOCK must be released 1001 * ADAPTER_STATE_LOCK must be release 1002 * 1003 * Returns: 1004 * qla2x00 local funxtion status code. 1005 * 1006 * Context: 1007 * Kernel context. 1008 */ 1009#define CONFIG_XCHOFFLD_MEM 0x3 1010int 1011qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha) 1012{ 1013 int rval; 1014 mbx_cmd_t mc; 1015 mbx_cmd_t *mcp = &mc; 1016 struct qla_hw_data *ha = vha->hw; 1017 1018 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157, 1019 "Entered %s.\n", __func__); 1020 1021 memset(mcp->mb, 0 , sizeof(mcp->mb)); 1022 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT; 1023 mcp->mb[1] = CONFIG_XCHOFFLD_MEM; 1024 mcp->mb[2] = MSW(ha->exchoffld_buf_dma); 1025 mcp->mb[3] = LSW(ha->exchoffld_buf_dma); 1026 mcp->mb[6] = MSW(MSD(ha->exchoffld_buf_dma)); 1027 mcp->mb[7] = LSW(MSD(ha->exchoffld_buf_dma)); 1028 mcp->mb[8] = MSW(ha->exchoffld_size); 1029 mcp->mb[9] = LSW(ha->exchoffld_size); 1030 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1031 mcp->in_mb = MBX_11|MBX_0; 1032 mcp->tov = MBX_TOV_SECONDS; 1033 mcp->flags = 0; 1034 rval = qla2x00_mailbox_command(vha, mcp); 1035 if (rval != QLA_SUCCESS) { 1036 /*EMPTY*/ 1037 ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval); 1038 } else { 1039 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192, 1040 "Done %s.\n", __func__); 1041 } 1042 1043 return rval; 1044} 1045 1046/* 1047 * qla2x00_get_fw_version 1048 * Get firmware version. 1049 * 1050 * Input: 1051 * ha: adapter state pointer. 1052 * major: pointer for major number. 1053 * minor: pointer for minor number. 1054 * subminor: pointer for subminor number. 1055 * 1056 * Returns: 1057 * qla2x00 local function return status code. 1058 * 1059 * Context: 1060 * Kernel context. 1061 */ 1062int 1063qla2x00_get_fw_version(scsi_qla_host_t *vha) 1064{ 1065 int rval; 1066 mbx_cmd_t mc; 1067 mbx_cmd_t *mcp = &mc; 1068 struct qla_hw_data *ha = vha->hw; 1069 1070 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029, 1071 "Entered %s.\n", __func__); 1072 1073 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION; 1074 mcp->out_mb = MBX_0; 1075 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 1076 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha)) 1077 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8; 1078 if (IS_FWI2_CAPABLE(ha)) 1079 mcp->in_mb |= MBX_17|MBX_16|MBX_15; 1080 if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) 1081 mcp->in_mb |= 1082 MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18| 1083 MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7; 1084 1085 mcp->flags = 0; 1086 mcp->tov = MBX_TOV_SECONDS; 1087 rval = qla2x00_mailbox_command(vha, mcp); 1088 if (rval != QLA_SUCCESS) 1089 goto failed; 1090 1091 /* Return mailbox data. */ 1092 ha->fw_major_version = mcp->mb[1]; 1093 ha->fw_minor_version = mcp->mb[2]; 1094 ha->fw_subminor_version = mcp->mb[3]; 1095 ha->fw_attributes = mcp->mb[6]; 1096 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw)) 1097 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */ 1098 else 1099 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4]; 1100 1101 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) { 1102 ha->mpi_version[0] = mcp->mb[10] & 0xff; 1103 ha->mpi_version[1] = mcp->mb[11] >> 8; 1104 ha->mpi_version[2] = mcp->mb[11] & 0xff; 1105 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13]; 1106 ha->phy_version[0] = mcp->mb[8] & 0xff; 1107 ha->phy_version[1] = mcp->mb[9] >> 8; 1108 ha->phy_version[2] = mcp->mb[9] & 0xff; 1109 } 1110 1111 if (IS_FWI2_CAPABLE(ha)) { 1112 ha->fw_attributes_h = mcp->mb[15]; 1113 ha->fw_attributes_ext[0] = mcp->mb[16]; 1114 ha->fw_attributes_ext[1] = mcp->mb[17]; 1115 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139, 1116 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n", 1117 __func__, mcp->mb[15], mcp->mb[6]); 1118 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f, 1119 "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n", 1120 __func__, mcp->mb[17], mcp->mb[16]); 1121 1122 if (ha->fw_attributes_h & 0x4) 1123 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d, 1124 "%s: Firmware supports Extended Login 0x%x\n", 1125 __func__, ha->fw_attributes_h); 1126 1127 if (ha->fw_attributes_h & 0x8) 1128 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191, 1129 "%s: Firmware supports Exchange Offload 0x%x\n", 1130 __func__, ha->fw_attributes_h); 1131 1132 /* 1133 * FW supports nvme and driver load parameter requested nvme. 1134 * BIT 26 of fw_attributes indicates NVMe support. 1135 */ 1136 if ((ha->fw_attributes_h & 1137 (FW_ATTR_H_NVME | FW_ATTR_H_NVME_UPDATED)) && 1138 ql2xnvmeenable) { 1139 if (ha->fw_attributes_h & FW_ATTR_H_NVME_FBURST) 1140 vha->flags.nvme_first_burst = 1; 1141 1142 vha->flags.nvme_enabled = 1; 1143 ql_log(ql_log_info, vha, 0xd302, 1144 "%s: FC-NVMe is Enabled (0x%x)\n", 1145 __func__, ha->fw_attributes_h); 1146 } 1147 1148 /* BIT_13 of Extended FW Attributes informs about NVMe2 support */ 1149 if (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_NVME2) { 1150 ql_log(ql_log_info, vha, 0xd302, 1151 "Firmware supports NVMe2 0x%x\n", 1152 ha->fw_attributes_ext[0]); 1153 vha->flags.nvme2_enabled = 1; 1154 } 1155 1156 if (IS_QLA28XX(ha) && ha->flags.edif_hw && ql2xsecenable && 1157 (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_EDIF)) { 1158 ha->flags.edif_enabled = 1; 1159 ql_log(ql_log_info, vha, 0xffff, 1160 "%s: edif is enabled\n", __func__); 1161 } 1162 } 1163 1164 if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 1165 ha->serdes_version[0] = mcp->mb[7] & 0xff; 1166 ha->serdes_version[1] = mcp->mb[8] >> 8; 1167 ha->serdes_version[2] = mcp->mb[8] & 0xff; 1168 ha->mpi_version[0] = mcp->mb[10] & 0xff; 1169 ha->mpi_version[1] = mcp->mb[11] >> 8; 1170 ha->mpi_version[2] = mcp->mb[11] & 0xff; 1171 ha->pep_version[0] = mcp->mb[13] & 0xff; 1172 ha->pep_version[1] = mcp->mb[14] >> 8; 1173 ha->pep_version[2] = mcp->mb[14] & 0xff; 1174 ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18]; 1175 ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20]; 1176 ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22]; 1177 ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24]; 1178 if (IS_QLA28XX(ha)) { 1179 if (mcp->mb[16] & BIT_10) 1180 ha->flags.secure_fw = 1; 1181 1182 ql_log(ql_log_info, vha, 0xffff, 1183 "Secure Flash Update in FW: %s\n", 1184 (ha->flags.secure_fw) ? "Supported" : 1185 "Not Supported"); 1186 } 1187 1188 if (ha->flags.scm_supported_a && 1189 (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) { 1190 ha->flags.scm_supported_f = 1; 1191 ha->sf_init_cb->flags |= cpu_to_le16(BIT_13); 1192 } 1193 ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n", 1194 (ha->flags.scm_supported_f) ? "Supported" : 1195 "Not Supported"); 1196 1197 if (vha->flags.nvme2_enabled) { 1198 /* set BIT_15 of special feature control block for SLER */ 1199 ha->sf_init_cb->flags |= cpu_to_le16(BIT_15); 1200 /* set BIT_14 of special feature control block for PI CTRL*/ 1201 ha->sf_init_cb->flags |= cpu_to_le16(BIT_14); 1202 } 1203 } 1204 1205failed: 1206 if (rval != QLA_SUCCESS) { 1207 /*EMPTY*/ 1208 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval); 1209 } else { 1210 /*EMPTY*/ 1211 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b, 1212 "Done %s.\n", __func__); 1213 } 1214 return rval; 1215} 1216 1217/* 1218 * qla2x00_get_fw_options 1219 * Set firmware options. 1220 * 1221 * Input: 1222 * ha = adapter block pointer. 1223 * fwopt = pointer for firmware options. 1224 * 1225 * Returns: 1226 * qla2x00 local function return status code. 1227 * 1228 * Context: 1229 * Kernel context. 1230 */ 1231int 1232qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts) 1233{ 1234 int rval; 1235 mbx_cmd_t mc; 1236 mbx_cmd_t *mcp = &mc; 1237 1238 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c, 1239 "Entered %s.\n", __func__); 1240 1241 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; 1242 mcp->out_mb = MBX_0; 1243 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1244 mcp->tov = MBX_TOV_SECONDS; 1245 mcp->flags = 0; 1246 rval = qla2x00_mailbox_command(vha, mcp); 1247 1248 if (rval != QLA_SUCCESS) { 1249 /*EMPTY*/ 1250 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval); 1251 } else { 1252 fwopts[0] = mcp->mb[0]; 1253 fwopts[1] = mcp->mb[1]; 1254 fwopts[2] = mcp->mb[2]; 1255 fwopts[3] = mcp->mb[3]; 1256 1257 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e, 1258 "Done %s.\n", __func__); 1259 } 1260 1261 return rval; 1262} 1263 1264 1265/* 1266 * qla2x00_set_fw_options 1267 * Set firmware options. 1268 * 1269 * Input: 1270 * ha = adapter block pointer. 1271 * fwopt = pointer for firmware options. 1272 * 1273 * Returns: 1274 * qla2x00 local function return status code. 1275 * 1276 * Context: 1277 * Kernel context. 1278 */ 1279int 1280qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts) 1281{ 1282 int rval; 1283 mbx_cmd_t mc; 1284 mbx_cmd_t *mcp = &mc; 1285 1286 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f, 1287 "Entered %s.\n", __func__); 1288 1289 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION; 1290 mcp->mb[1] = fwopts[1]; 1291 mcp->mb[2] = fwopts[2]; 1292 mcp->mb[3] = fwopts[3]; 1293 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1294 mcp->in_mb = MBX_0; 1295 if (IS_FWI2_CAPABLE(vha->hw)) { 1296 mcp->in_mb |= MBX_1; 1297 mcp->mb[10] = fwopts[10]; 1298 mcp->out_mb |= MBX_10; 1299 } else { 1300 mcp->mb[10] = fwopts[10]; 1301 mcp->mb[11] = fwopts[11]; 1302 mcp->mb[12] = 0; /* Undocumented, but used */ 1303 mcp->out_mb |= MBX_12|MBX_11|MBX_10; 1304 } 1305 mcp->tov = MBX_TOV_SECONDS; 1306 mcp->flags = 0; 1307 rval = qla2x00_mailbox_command(vha, mcp); 1308 1309 fwopts[0] = mcp->mb[0]; 1310 1311 if (rval != QLA_SUCCESS) { 1312 /*EMPTY*/ 1313 ql_dbg(ql_dbg_mbx, vha, 0x1030, 1314 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]); 1315 } else { 1316 /*EMPTY*/ 1317 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031, 1318 "Done %s.\n", __func__); 1319 } 1320 1321 return rval; 1322} 1323 1324/* 1325 * qla2x00_mbx_reg_test 1326 * Mailbox register wrap test. 1327 * 1328 * Input: 1329 * ha = adapter block pointer. 1330 * TARGET_QUEUE_LOCK must be released. 1331 * ADAPTER_STATE_LOCK must be released. 1332 * 1333 * Returns: 1334 * qla2x00 local function return status code. 1335 * 1336 * Context: 1337 * Kernel context. 1338 */ 1339int 1340qla2x00_mbx_reg_test(scsi_qla_host_t *vha) 1341{ 1342 int rval; 1343 mbx_cmd_t mc; 1344 mbx_cmd_t *mcp = &mc; 1345 1346 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032, 1347 "Entered %s.\n", __func__); 1348 1349 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; 1350 mcp->mb[1] = 0xAAAA; 1351 mcp->mb[2] = 0x5555; 1352 mcp->mb[3] = 0xAA55; 1353 mcp->mb[4] = 0x55AA; 1354 mcp->mb[5] = 0xA5A5; 1355 mcp->mb[6] = 0x5A5A; 1356 mcp->mb[7] = 0x2525; 1357 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 1358 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 1359 mcp->tov = MBX_TOV_SECONDS; 1360 mcp->flags = 0; 1361 rval = qla2x00_mailbox_command(vha, mcp); 1362 1363 if (rval == QLA_SUCCESS) { 1364 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 || 1365 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA) 1366 rval = QLA_FUNCTION_FAILED; 1367 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || 1368 mcp->mb[7] != 0x2525) 1369 rval = QLA_FUNCTION_FAILED; 1370 } 1371 1372 if (rval != QLA_SUCCESS) { 1373 /*EMPTY*/ 1374 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval); 1375 vha->hw_err_cnt++; 1376 } else { 1377 /*EMPTY*/ 1378 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034, 1379 "Done %s.\n", __func__); 1380 } 1381 1382 return rval; 1383} 1384 1385/* 1386 * qla2x00_verify_checksum 1387 * Verify firmware checksum. 1388 * 1389 * Input: 1390 * ha = adapter block pointer. 1391 * TARGET_QUEUE_LOCK must be released. 1392 * ADAPTER_STATE_LOCK must be released. 1393 * 1394 * Returns: 1395 * qla2x00 local function return status code. 1396 * 1397 * Context: 1398 * Kernel context. 1399 */ 1400int 1401qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr) 1402{ 1403 int rval; 1404 mbx_cmd_t mc; 1405 mbx_cmd_t *mcp = &mc; 1406 1407 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035, 1408 "Entered %s.\n", __func__); 1409 1410 mcp->mb[0] = MBC_VERIFY_CHECKSUM; 1411 mcp->out_mb = MBX_0; 1412 mcp->in_mb = MBX_0; 1413 if (IS_FWI2_CAPABLE(vha->hw)) { 1414 mcp->mb[1] = MSW(risc_addr); 1415 mcp->mb[2] = LSW(risc_addr); 1416 mcp->out_mb |= MBX_2|MBX_1; 1417 mcp->in_mb |= MBX_2|MBX_1; 1418 } else { 1419 mcp->mb[1] = LSW(risc_addr); 1420 mcp->out_mb |= MBX_1; 1421 mcp->in_mb |= MBX_1; 1422 } 1423 1424 mcp->tov = MBX_TOV_SECONDS; 1425 mcp->flags = 0; 1426 rval = qla2x00_mailbox_command(vha, mcp); 1427 1428 if (rval != QLA_SUCCESS) { 1429 ql_dbg(ql_dbg_mbx, vha, 0x1036, 1430 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ? 1431 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]); 1432 } else { 1433 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037, 1434 "Done %s.\n", __func__); 1435 } 1436 1437 return rval; 1438} 1439 1440/* 1441 * qla2x00_issue_iocb 1442 * Issue IOCB using mailbox command 1443 * 1444 * Input: 1445 * ha = adapter state pointer. 1446 * buffer = buffer pointer. 1447 * phys_addr = physical address of buffer. 1448 * size = size of buffer. 1449 * TARGET_QUEUE_LOCK must be released. 1450 * ADAPTER_STATE_LOCK must be released. 1451 * 1452 * Returns: 1453 * qla2x00 local function return status code. 1454 * 1455 * Context: 1456 * Kernel context. 1457 */ 1458int 1459qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer, 1460 dma_addr_t phys_addr, size_t size, uint32_t tov) 1461{ 1462 int rval; 1463 mbx_cmd_t mc; 1464 mbx_cmd_t *mcp = &mc; 1465 1466 if (!vha->hw->flags.fw_started) 1467 return QLA_INVALID_COMMAND; 1468 1469 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038, 1470 "Entered %s.\n", __func__); 1471 1472 mcp->mb[0] = MBC_IOCB_COMMAND_A64; 1473 mcp->mb[1] = 0; 1474 mcp->mb[2] = MSW(LSD(phys_addr)); 1475 mcp->mb[3] = LSW(LSD(phys_addr)); 1476 mcp->mb[6] = MSW(MSD(phys_addr)); 1477 mcp->mb[7] = LSW(MSD(phys_addr)); 1478 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1479 mcp->in_mb = MBX_1|MBX_0; 1480 mcp->tov = tov; 1481 mcp->flags = 0; 1482 rval = qla2x00_mailbox_command(vha, mcp); 1483 1484 if (rval != QLA_SUCCESS) { 1485 /*EMPTY*/ 1486 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval); 1487 } else { 1488 sts_entry_t *sts_entry = buffer; 1489 1490 /* Mask reserved bits. */ 1491 sts_entry->entry_status &= 1492 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK; 1493 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a, 1494 "Done %s (status=%x).\n", __func__, 1495 sts_entry->entry_status); 1496 } 1497 1498 return rval; 1499} 1500 1501int 1502qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr, 1503 size_t size) 1504{ 1505 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size, 1506 MBX_TOV_SECONDS); 1507} 1508 1509/* 1510 * qla2x00_abort_command 1511 * Abort command aborts a specified IOCB. 1512 * 1513 * Input: 1514 * ha = adapter block pointer. 1515 * sp = SB structure pointer. 1516 * 1517 * Returns: 1518 * qla2x00 local function return status code. 1519 * 1520 * Context: 1521 * Kernel context. 1522 */ 1523int 1524qla2x00_abort_command(srb_t *sp) 1525{ 1526 unsigned long flags = 0; 1527 int rval; 1528 uint32_t handle = 0; 1529 mbx_cmd_t mc; 1530 mbx_cmd_t *mcp = &mc; 1531 fc_port_t *fcport = sp->fcport; 1532 scsi_qla_host_t *vha = fcport->vha; 1533 struct qla_hw_data *ha = vha->hw; 1534 struct req_que *req; 1535 struct scsi_cmnd *cmd = GET_CMD_SP(sp); 1536 1537 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b, 1538 "Entered %s.\n", __func__); 1539 1540 if (sp->qpair) 1541 req = sp->qpair->req; 1542 else 1543 req = vha->req; 1544 1545 spin_lock_irqsave(&ha->hardware_lock, flags); 1546 for (handle = 1; handle < req->num_outstanding_cmds; handle++) { 1547 if (req->outstanding_cmds[handle] == sp) 1548 break; 1549 } 1550 spin_unlock_irqrestore(&ha->hardware_lock, flags); 1551 1552 if (handle == req->num_outstanding_cmds) { 1553 /* command not found */ 1554 return QLA_FUNCTION_FAILED; 1555 } 1556 1557 mcp->mb[0] = MBC_ABORT_COMMAND; 1558 if (HAS_EXTENDED_IDS(ha)) 1559 mcp->mb[1] = fcport->loop_id; 1560 else 1561 mcp->mb[1] = fcport->loop_id << 8; 1562 mcp->mb[2] = (uint16_t)handle; 1563 mcp->mb[3] = (uint16_t)(handle >> 16); 1564 mcp->mb[6] = (uint16_t)cmd->device->lun; 1565 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1566 mcp->in_mb = MBX_0; 1567 mcp->tov = MBX_TOV_SECONDS; 1568 mcp->flags = 0; 1569 rval = qla2x00_mailbox_command(vha, mcp); 1570 1571 if (rval != QLA_SUCCESS) { 1572 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval); 1573 } else { 1574 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d, 1575 "Done %s.\n", __func__); 1576 } 1577 1578 return rval; 1579} 1580 1581int 1582qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag) 1583{ 1584 int rval, rval2; 1585 mbx_cmd_t mc; 1586 mbx_cmd_t *mcp = &mc; 1587 scsi_qla_host_t *vha; 1588 1589 vha = fcport->vha; 1590 1591 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e, 1592 "Entered %s.\n", __func__); 1593 1594 mcp->mb[0] = MBC_ABORT_TARGET; 1595 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; 1596 if (HAS_EXTENDED_IDS(vha->hw)) { 1597 mcp->mb[1] = fcport->loop_id; 1598 mcp->mb[10] = 0; 1599 mcp->out_mb |= MBX_10; 1600 } else { 1601 mcp->mb[1] = fcport->loop_id << 8; 1602 } 1603 mcp->mb[2] = vha->hw->loop_reset_delay; 1604 mcp->mb[9] = vha->vp_idx; 1605 1606 mcp->in_mb = MBX_0; 1607 mcp->tov = MBX_TOV_SECONDS; 1608 mcp->flags = 0; 1609 rval = qla2x00_mailbox_command(vha, mcp); 1610 if (rval != QLA_SUCCESS) { 1611 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f, 1612 "Failed=%x.\n", rval); 1613 } 1614 1615 /* Issue marker IOCB. */ 1616 rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, 0, 1617 MK_SYNC_ID); 1618 if (rval2 != QLA_SUCCESS) { 1619 ql_dbg(ql_dbg_mbx, vha, 0x1040, 1620 "Failed to issue marker IOCB (%x).\n", rval2); 1621 } else { 1622 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041, 1623 "Done %s.\n", __func__); 1624 } 1625 1626 return rval; 1627} 1628 1629int 1630qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag) 1631{ 1632 int rval, rval2; 1633 mbx_cmd_t mc; 1634 mbx_cmd_t *mcp = &mc; 1635 scsi_qla_host_t *vha; 1636 1637 vha = fcport->vha; 1638 1639 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042, 1640 "Entered %s.\n", __func__); 1641 1642 mcp->mb[0] = MBC_LUN_RESET; 1643 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; 1644 if (HAS_EXTENDED_IDS(vha->hw)) 1645 mcp->mb[1] = fcport->loop_id; 1646 else 1647 mcp->mb[1] = fcport->loop_id << 8; 1648 mcp->mb[2] = (u32)l; 1649 mcp->mb[3] = 0; 1650 mcp->mb[9] = vha->vp_idx; 1651 1652 mcp->in_mb = MBX_0; 1653 mcp->tov = MBX_TOV_SECONDS; 1654 mcp->flags = 0; 1655 rval = qla2x00_mailbox_command(vha, mcp); 1656 if (rval != QLA_SUCCESS) { 1657 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval); 1658 } 1659 1660 /* Issue marker IOCB. */ 1661 rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, l, 1662 MK_SYNC_ID_LUN); 1663 if (rval2 != QLA_SUCCESS) { 1664 ql_dbg(ql_dbg_mbx, vha, 0x1044, 1665 "Failed to issue marker IOCB (%x).\n", rval2); 1666 } else { 1667 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045, 1668 "Done %s.\n", __func__); 1669 } 1670 1671 return rval; 1672} 1673 1674/* 1675 * qla2x00_get_adapter_id 1676 * Get adapter ID and topology. 1677 * 1678 * Input: 1679 * ha = adapter block pointer. 1680 * id = pointer for loop ID. 1681 * al_pa = pointer for AL_PA. 1682 * area = pointer for area. 1683 * domain = pointer for domain. 1684 * top = pointer for topology. 1685 * TARGET_QUEUE_LOCK must be released. 1686 * ADAPTER_STATE_LOCK must be released. 1687 * 1688 * Returns: 1689 * qla2x00 local function return status code. 1690 * 1691 * Context: 1692 * Kernel context. 1693 */ 1694int 1695qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, 1696 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap) 1697{ 1698 int rval; 1699 mbx_cmd_t mc; 1700 mbx_cmd_t *mcp = &mc; 1701 1702 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046, 1703 "Entered %s.\n", __func__); 1704 1705 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; 1706 mcp->mb[9] = vha->vp_idx; 1707 mcp->out_mb = MBX_9|MBX_0; 1708 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1709 if (IS_CNA_CAPABLE(vha->hw)) 1710 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10; 1711 if (IS_FWI2_CAPABLE(vha->hw)) 1712 mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16; 1713 if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) 1714 mcp->in_mb |= MBX_15|MBX_21|MBX_22|MBX_23; 1715 1716 mcp->tov = MBX_TOV_SECONDS; 1717 mcp->flags = 0; 1718 rval = qla2x00_mailbox_command(vha, mcp); 1719 if (mcp->mb[0] == MBS_COMMAND_ERROR) 1720 rval = QLA_COMMAND_ERROR; 1721 else if (mcp->mb[0] == MBS_INVALID_COMMAND) 1722 rval = QLA_INVALID_COMMAND; 1723 1724 /* Return data. */ 1725 *id = mcp->mb[1]; 1726 *al_pa = LSB(mcp->mb[2]); 1727 *area = MSB(mcp->mb[2]); 1728 *domain = LSB(mcp->mb[3]); 1729 *top = mcp->mb[6]; 1730 *sw_cap = mcp->mb[7]; 1731 1732 if (rval != QLA_SUCCESS) { 1733 /*EMPTY*/ 1734 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval); 1735 } else { 1736 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048, 1737 "Done %s.\n", __func__); 1738 1739 if (IS_CNA_CAPABLE(vha->hw)) { 1740 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff; 1741 vha->fcoe_fcf_idx = mcp->mb[10]; 1742 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8; 1743 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff; 1744 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8; 1745 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff; 1746 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8; 1747 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff; 1748 } 1749 /* If FA-WWN supported */ 1750 if (IS_FAWWN_CAPABLE(vha->hw)) { 1751 if (mcp->mb[7] & BIT_14) { 1752 vha->port_name[0] = MSB(mcp->mb[16]); 1753 vha->port_name[1] = LSB(mcp->mb[16]); 1754 vha->port_name[2] = MSB(mcp->mb[17]); 1755 vha->port_name[3] = LSB(mcp->mb[17]); 1756 vha->port_name[4] = MSB(mcp->mb[18]); 1757 vha->port_name[5] = LSB(mcp->mb[18]); 1758 vha->port_name[6] = MSB(mcp->mb[19]); 1759 vha->port_name[7] = LSB(mcp->mb[19]); 1760 fc_host_port_name(vha->host) = 1761 wwn_to_u64(vha->port_name); 1762 ql_dbg(ql_dbg_mbx, vha, 0x10ca, 1763 "FA-WWN acquired %016llx\n", 1764 wwn_to_u64(vha->port_name)); 1765 } 1766 } 1767 1768 if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) { 1769 vha->bbcr = mcp->mb[15]; 1770 if (mcp->mb[7] & SCM_EDC_ACC_RECEIVED) { 1771 ql_log(ql_log_info, vha, 0x11a4, 1772 "SCM: EDC ELS completed, flags 0x%x\n", 1773 mcp->mb[21]); 1774 } 1775 if (mcp->mb[7] & SCM_RDF_ACC_RECEIVED) { 1776 vha->hw->flags.scm_enabled = 1; 1777 vha->scm_fabric_connection_flags |= 1778 SCM_FLAG_RDF_COMPLETED; 1779 ql_log(ql_log_info, vha, 0x11a5, 1780 "SCM: RDF ELS completed, flags 0x%x\n", 1781 mcp->mb[23]); 1782 } 1783 } 1784 } 1785 1786 return rval; 1787} 1788 1789/* 1790 * qla2x00_get_retry_cnt 1791 * Get current firmware login retry count and delay. 1792 * 1793 * Input: 1794 * ha = adapter block pointer. 1795 * retry_cnt = pointer to login retry count. 1796 * tov = pointer to login timeout value. 1797 * 1798 * Returns: 1799 * qla2x00 local function return status code. 1800 * 1801 * Context: 1802 * Kernel context. 1803 */ 1804int 1805qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov, 1806 uint16_t *r_a_tov) 1807{ 1808 int rval; 1809 uint16_t ratov; 1810 mbx_cmd_t mc; 1811 mbx_cmd_t *mcp = &mc; 1812 1813 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049, 1814 "Entered %s.\n", __func__); 1815 1816 mcp->mb[0] = MBC_GET_RETRY_COUNT; 1817 mcp->out_mb = MBX_0; 1818 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1819 mcp->tov = MBX_TOV_SECONDS; 1820 mcp->flags = 0; 1821 rval = qla2x00_mailbox_command(vha, mcp); 1822 1823 if (rval != QLA_SUCCESS) { 1824 /*EMPTY*/ 1825 ql_dbg(ql_dbg_mbx, vha, 0x104a, 1826 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 1827 } else { 1828 /* Convert returned data and check our values. */ 1829 *r_a_tov = mcp->mb[3] / 2; 1830 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */ 1831 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) { 1832 /* Update to the larger values */ 1833 *retry_cnt = (uint8_t)mcp->mb[1]; 1834 *tov = ratov; 1835 } 1836 1837 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b, 1838 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov); 1839 } 1840 1841 return rval; 1842} 1843 1844/* 1845 * qla2x00_init_firmware 1846 * Initialize adapter firmware. 1847 * 1848 * Input: 1849 * ha = adapter block pointer. 1850 * dptr = Initialization control block pointer. 1851 * size = size of initialization control block. 1852 * TARGET_QUEUE_LOCK must be released. 1853 * ADAPTER_STATE_LOCK must be released. 1854 * 1855 * Returns: 1856 * qla2x00 local function return status code. 1857 * 1858 * Context: 1859 * Kernel context. 1860 */ 1861int 1862qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) 1863{ 1864 int rval; 1865 mbx_cmd_t mc; 1866 mbx_cmd_t *mcp = &mc; 1867 struct qla_hw_data *ha = vha->hw; 1868 1869 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c, 1870 "Entered %s.\n", __func__); 1871 1872 if (IS_P3P_TYPE(ha) && ql2xdbwr) 1873 qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr, 1874 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16))); 1875 1876 if (ha->flags.npiv_supported) 1877 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE; 1878 else 1879 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; 1880 1881 mcp->mb[1] = 0; 1882 mcp->mb[2] = MSW(ha->init_cb_dma); 1883 mcp->mb[3] = LSW(ha->init_cb_dma); 1884 mcp->mb[6] = MSW(MSD(ha->init_cb_dma)); 1885 mcp->mb[7] = LSW(MSD(ha->init_cb_dma)); 1886 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1887 if (ha->ex_init_cb && ha->ex_init_cb->ex_version) { 1888 mcp->mb[1] = BIT_0; 1889 mcp->mb[10] = MSW(ha->ex_init_cb_dma); 1890 mcp->mb[11] = LSW(ha->ex_init_cb_dma); 1891 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma)); 1892 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma)); 1893 mcp->mb[14] = sizeof(*ha->ex_init_cb); 1894 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10; 1895 } 1896 1897 if (ha->flags.scm_supported_f || vha->flags.nvme2_enabled) { 1898 mcp->mb[1] |= BIT_1; 1899 mcp->mb[16] = MSW(ha->sf_init_cb_dma); 1900 mcp->mb[17] = LSW(ha->sf_init_cb_dma); 1901 mcp->mb[18] = MSW(MSD(ha->sf_init_cb_dma)); 1902 mcp->mb[19] = LSW(MSD(ha->sf_init_cb_dma)); 1903 mcp->mb[15] = sizeof(*ha->sf_init_cb); 1904 mcp->out_mb |= MBX_19|MBX_18|MBX_17|MBX_16|MBX_15; 1905 } 1906 1907 /* 1 and 2 should normally be captured. */ 1908 mcp->in_mb = MBX_2|MBX_1|MBX_0; 1909 if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 1910 /* mb3 is additional info about the installed SFP. */ 1911 mcp->in_mb |= MBX_3; 1912 mcp->buf_size = size; 1913 mcp->flags = MBX_DMA_OUT; 1914 mcp->tov = MBX_TOV_SECONDS; 1915 rval = qla2x00_mailbox_command(vha, mcp); 1916 1917 if (rval != QLA_SUCCESS) { 1918 /*EMPTY*/ 1919 ql_dbg(ql_dbg_mbx, vha, 0x104d, 1920 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x.\n", 1921 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]); 1922 if (ha->init_cb) { 1923 ql_dbg(ql_dbg_mbx, vha, 0x104d, "init_cb:\n"); 1924 ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 1925 0x0104d, ha->init_cb, sizeof(*ha->init_cb)); 1926 } 1927 if (ha->ex_init_cb && ha->ex_init_cb->ex_version) { 1928 ql_dbg(ql_dbg_mbx, vha, 0x104d, "ex_init_cb:\n"); 1929 ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 1930 0x0104d, ha->ex_init_cb, sizeof(*ha->ex_init_cb)); 1931 } 1932 } else { 1933 if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 1934 if (mcp->mb[2] == 6 || mcp->mb[3] == 2) 1935 ql_dbg(ql_dbg_mbx, vha, 0x119d, 1936 "Invalid SFP/Validation Failed\n"); 1937 } 1938 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e, 1939 "Done %s.\n", __func__); 1940 } 1941 1942 return rval; 1943} 1944 1945 1946/* 1947 * qla2x00_get_port_database 1948 * Issue normal/enhanced get port database mailbox command 1949 * and copy device name as necessary. 1950 * 1951 * Input: 1952 * ha = adapter state pointer. 1953 * dev = structure pointer. 1954 * opt = enhanced cmd option byte. 1955 * 1956 * Returns: 1957 * qla2x00 local function return status code. 1958 * 1959 * Context: 1960 * Kernel context. 1961 */ 1962int 1963qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt) 1964{ 1965 int rval; 1966 mbx_cmd_t mc; 1967 mbx_cmd_t *mcp = &mc; 1968 port_database_t *pd; 1969 struct port_database_24xx *pd24; 1970 dma_addr_t pd_dma; 1971 struct qla_hw_data *ha = vha->hw; 1972 1973 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f, 1974 "Entered %s.\n", __func__); 1975 1976 pd24 = NULL; 1977 pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); 1978 if (pd == NULL) { 1979 ql_log(ql_log_warn, vha, 0x1050, 1980 "Failed to allocate port database structure.\n"); 1981 fcport->query = 0; 1982 return QLA_MEMORY_ALLOC_FAILED; 1983 } 1984 1985 mcp->mb[0] = MBC_GET_PORT_DATABASE; 1986 if (opt != 0 && !IS_FWI2_CAPABLE(ha)) 1987 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE; 1988 mcp->mb[2] = MSW(pd_dma); 1989 mcp->mb[3] = LSW(pd_dma); 1990 mcp->mb[6] = MSW(MSD(pd_dma)); 1991 mcp->mb[7] = LSW(MSD(pd_dma)); 1992 mcp->mb[9] = vha->vp_idx; 1993 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 1994 mcp->in_mb = MBX_0; 1995 if (IS_FWI2_CAPABLE(ha)) { 1996 mcp->mb[1] = fcport->loop_id; 1997 mcp->mb[10] = opt; 1998 mcp->out_mb |= MBX_10|MBX_1; 1999 mcp->in_mb |= MBX_1; 2000 } else if (HAS_EXTENDED_IDS(ha)) { 2001 mcp->mb[1] = fcport->loop_id; 2002 mcp->mb[10] = opt; 2003 mcp->out_mb |= MBX_10|MBX_1; 2004 } else { 2005 mcp->mb[1] = fcport->loop_id << 8 | opt; 2006 mcp->out_mb |= MBX_1; 2007 } 2008 mcp->buf_size = IS_FWI2_CAPABLE(ha) ? 2009 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE; 2010 mcp->flags = MBX_DMA_IN; 2011 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 2012 rval = qla2x00_mailbox_command(vha, mcp); 2013 if (rval != QLA_SUCCESS) 2014 goto gpd_error_out; 2015 2016 if (IS_FWI2_CAPABLE(ha)) { 2017 uint64_t zero = 0; 2018 u8 current_login_state, last_login_state; 2019 2020 pd24 = (struct port_database_24xx *) pd; 2021 2022 /* Check for logged in state. */ 2023 if (NVME_TARGET(ha, fcport)) { 2024 current_login_state = pd24->current_login_state >> 4; 2025 last_login_state = pd24->last_login_state >> 4; 2026 } else { 2027 current_login_state = pd24->current_login_state & 0xf; 2028 last_login_state = pd24->last_login_state & 0xf; 2029 } 2030 fcport->current_login_state = pd24->current_login_state; 2031 fcport->last_login_state = pd24->last_login_state; 2032 2033 /* Check for logged in state. */ 2034 if (current_login_state != PDS_PRLI_COMPLETE && 2035 last_login_state != PDS_PRLI_COMPLETE) { 2036 ql_dbg(ql_dbg_mbx, vha, 0x119a, 2037 "Unable to verify login-state (%x/%x) for loop_id %x.\n", 2038 current_login_state, last_login_state, 2039 fcport->loop_id); 2040 rval = QLA_FUNCTION_FAILED; 2041 2042 if (!fcport->query) 2043 goto gpd_error_out; 2044 } 2045 2046 if (fcport->loop_id == FC_NO_LOOP_ID || 2047 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && 2048 memcmp(fcport->port_name, pd24->port_name, 8))) { 2049 /* We lost the device mid way. */ 2050 rval = QLA_NOT_LOGGED_IN; 2051 goto gpd_error_out; 2052 } 2053 2054 /* Names are little-endian. */ 2055 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE); 2056 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE); 2057 2058 /* Get port_id of device. */ 2059 fcport->d_id.b.domain = pd24->port_id[0]; 2060 fcport->d_id.b.area = pd24->port_id[1]; 2061 fcport->d_id.b.al_pa = pd24->port_id[2]; 2062 fcport->d_id.b.rsvd_1 = 0; 2063 2064 /* If not target must be initiator or unknown type. */ 2065 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0) 2066 fcport->port_type = FCT_INITIATOR; 2067 else 2068 fcport->port_type = FCT_TARGET; 2069 2070 /* Passback COS information. */ 2071 fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ? 2072 FC_COS_CLASS2 : FC_COS_CLASS3; 2073 2074 if (pd24->prli_svc_param_word_3[0] & BIT_7) 2075 fcport->flags |= FCF_CONF_COMP_SUPPORTED; 2076 } else { 2077 uint64_t zero = 0; 2078 2079 /* Check for logged in state. */ 2080 if (pd->master_state != PD_STATE_PORT_LOGGED_IN && 2081 pd->slave_state != PD_STATE_PORT_LOGGED_IN) { 2082 ql_dbg(ql_dbg_mbx, vha, 0x100a, 2083 "Unable to verify login-state (%x/%x) - " 2084 "portid=%02x%02x%02x.\n", pd->master_state, 2085 pd->slave_state, fcport->d_id.b.domain, 2086 fcport->d_id.b.area, fcport->d_id.b.al_pa); 2087 rval = QLA_FUNCTION_FAILED; 2088 goto gpd_error_out; 2089 } 2090 2091 if (fcport->loop_id == FC_NO_LOOP_ID || 2092 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && 2093 memcmp(fcport->port_name, pd->port_name, 8))) { 2094 /* We lost the device mid way. */ 2095 rval = QLA_NOT_LOGGED_IN; 2096 goto gpd_error_out; 2097 } 2098 2099 /* Names are little-endian. */ 2100 memcpy(fcport->node_name, pd->node_name, WWN_SIZE); 2101 memcpy(fcport->port_name, pd->port_name, WWN_SIZE); 2102 2103 /* Get port_id of device. */ 2104 fcport->d_id.b.domain = pd->port_id[0]; 2105 fcport->d_id.b.area = pd->port_id[3]; 2106 fcport->d_id.b.al_pa = pd->port_id[2]; 2107 fcport->d_id.b.rsvd_1 = 0; 2108 2109 /* If not target must be initiator or unknown type. */ 2110 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 2111 fcport->port_type = FCT_INITIATOR; 2112 else 2113 fcport->port_type = FCT_TARGET; 2114 2115 /* Passback COS information. */ 2116 fcport->supported_classes = (pd->options & BIT_4) ? 2117 FC_COS_CLASS2 : FC_COS_CLASS3; 2118 } 2119 2120gpd_error_out: 2121 dma_pool_free(ha->s_dma_pool, pd, pd_dma); 2122 fcport->query = 0; 2123 2124 if (rval != QLA_SUCCESS) { 2125 ql_dbg(ql_dbg_mbx, vha, 0x1052, 2126 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, 2127 mcp->mb[0], mcp->mb[1]); 2128 } else { 2129 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053, 2130 "Done %s.\n", __func__); 2131 } 2132 2133 return rval; 2134} 2135 2136int 2137qla24xx_get_port_database(scsi_qla_host_t *vha, u16 nport_handle, 2138 struct port_database_24xx *pdb) 2139{ 2140 mbx_cmd_t mc; 2141 mbx_cmd_t *mcp = &mc; 2142 dma_addr_t pdb_dma; 2143 int rval; 2144 2145 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1115, 2146 "Entered %s.\n", __func__); 2147 2148 memset(pdb, 0, sizeof(*pdb)); 2149 2150 pdb_dma = dma_map_single(&vha->hw->pdev->dev, pdb, 2151 sizeof(*pdb), DMA_FROM_DEVICE); 2152 if (dma_mapping_error(&vha->hw->pdev->dev, pdb_dma)) { 2153 ql_log(ql_log_warn, vha, 0x1116, "Failed to map dma buffer.\n"); 2154 return QLA_MEMORY_ALLOC_FAILED; 2155 } 2156 2157 mcp->mb[0] = MBC_GET_PORT_DATABASE; 2158 mcp->mb[1] = nport_handle; 2159 mcp->mb[2] = MSW(LSD(pdb_dma)); 2160 mcp->mb[3] = LSW(LSD(pdb_dma)); 2161 mcp->mb[6] = MSW(MSD(pdb_dma)); 2162 mcp->mb[7] = LSW(MSD(pdb_dma)); 2163 mcp->mb[9] = 0; 2164 mcp->mb[10] = 0; 2165 mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2166 mcp->in_mb = MBX_1|MBX_0; 2167 mcp->buf_size = sizeof(*pdb); 2168 mcp->flags = MBX_DMA_IN; 2169 mcp->tov = vha->hw->login_timeout * 2; 2170 rval = qla2x00_mailbox_command(vha, mcp); 2171 2172 if (rval != QLA_SUCCESS) { 2173 ql_dbg(ql_dbg_mbx, vha, 0x111a, 2174 "Failed=%x mb[0]=%x mb[1]=%x.\n", 2175 rval, mcp->mb[0], mcp->mb[1]); 2176 } else { 2177 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111b, 2178 "Done %s.\n", __func__); 2179 } 2180 2181 dma_unmap_single(&vha->hw->pdev->dev, pdb_dma, 2182 sizeof(*pdb), DMA_FROM_DEVICE); 2183 2184 return rval; 2185} 2186 2187/* 2188 * qla2x00_get_firmware_state 2189 * Get adapter firmware state. 2190 * 2191 * Input: 2192 * ha = adapter block pointer. 2193 * dptr = pointer for firmware state. 2194 * TARGET_QUEUE_LOCK must be released. 2195 * ADAPTER_STATE_LOCK must be released. 2196 * 2197 * Returns: 2198 * qla2x00 local function return status code. 2199 * 2200 * Context: 2201 * Kernel context. 2202 */ 2203int 2204qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states) 2205{ 2206 int rval; 2207 mbx_cmd_t mc; 2208 mbx_cmd_t *mcp = &mc; 2209 struct qla_hw_data *ha = vha->hw; 2210 2211 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054, 2212 "Entered %s.\n", __func__); 2213 2214 if (!ha->flags.fw_started) 2215 return QLA_FUNCTION_FAILED; 2216 2217 mcp->mb[0] = MBC_GET_FIRMWARE_STATE; 2218 mcp->out_mb = MBX_0; 2219 if (IS_FWI2_CAPABLE(vha->hw)) 2220 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 2221 else 2222 mcp->in_mb = MBX_1|MBX_0; 2223 mcp->tov = MBX_TOV_SECONDS; 2224 mcp->flags = 0; 2225 rval = qla2x00_mailbox_command(vha, mcp); 2226 2227 /* Return firmware states. */ 2228 states[0] = mcp->mb[1]; 2229 if (IS_FWI2_CAPABLE(vha->hw)) { 2230 states[1] = mcp->mb[2]; 2231 states[2] = mcp->mb[3]; /* SFP info */ 2232 states[3] = mcp->mb[4]; 2233 states[4] = mcp->mb[5]; 2234 states[5] = mcp->mb[6]; /* DPORT status */ 2235 } 2236 2237 if (rval != QLA_SUCCESS) { 2238 /*EMPTY*/ 2239 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval); 2240 } else { 2241 if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 2242 if (mcp->mb[2] == 6 || mcp->mb[3] == 2) 2243 ql_dbg(ql_dbg_mbx, vha, 0x119e, 2244 "Invalid SFP/Validation Failed\n"); 2245 } 2246 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056, 2247 "Done %s.\n", __func__); 2248 } 2249 2250 return rval; 2251} 2252 2253/* 2254 * qla2x00_get_port_name 2255 * Issue get port name mailbox command. 2256 * Returned name is in big endian format. 2257 * 2258 * Input: 2259 * ha = adapter block pointer. 2260 * loop_id = loop ID of device. 2261 * name = pointer for name. 2262 * TARGET_QUEUE_LOCK must be released. 2263 * ADAPTER_STATE_LOCK must be released. 2264 * 2265 * Returns: 2266 * qla2x00 local function return status code. 2267 * 2268 * Context: 2269 * Kernel context. 2270 */ 2271int 2272qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name, 2273 uint8_t opt) 2274{ 2275 int rval; 2276 mbx_cmd_t mc; 2277 mbx_cmd_t *mcp = &mc; 2278 2279 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057, 2280 "Entered %s.\n", __func__); 2281 2282 mcp->mb[0] = MBC_GET_PORT_NAME; 2283 mcp->mb[9] = vha->vp_idx; 2284 mcp->out_mb = MBX_9|MBX_1|MBX_0; 2285 if (HAS_EXTENDED_IDS(vha->hw)) { 2286 mcp->mb[1] = loop_id; 2287 mcp->mb[10] = opt; 2288 mcp->out_mb |= MBX_10; 2289 } else { 2290 mcp->mb[1] = loop_id << 8 | opt; 2291 } 2292 2293 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2294 mcp->tov = MBX_TOV_SECONDS; 2295 mcp->flags = 0; 2296 rval = qla2x00_mailbox_command(vha, mcp); 2297 2298 if (rval != QLA_SUCCESS) { 2299 /*EMPTY*/ 2300 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval); 2301 } else { 2302 if (name != NULL) { 2303 /* This function returns name in big endian. */ 2304 name[0] = MSB(mcp->mb[2]); 2305 name[1] = LSB(mcp->mb[2]); 2306 name[2] = MSB(mcp->mb[3]); 2307 name[3] = LSB(mcp->mb[3]); 2308 name[4] = MSB(mcp->mb[6]); 2309 name[5] = LSB(mcp->mb[6]); 2310 name[6] = MSB(mcp->mb[7]); 2311 name[7] = LSB(mcp->mb[7]); 2312 } 2313 2314 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059, 2315 "Done %s.\n", __func__); 2316 } 2317 2318 return rval; 2319} 2320 2321/* 2322 * qla24xx_link_initialization 2323 * Issue link initialization mailbox command. 2324 * 2325 * Input: 2326 * ha = adapter block pointer. 2327 * TARGET_QUEUE_LOCK must be released. 2328 * ADAPTER_STATE_LOCK must be released. 2329 * 2330 * Returns: 2331 * qla2x00 local function return status code. 2332 * 2333 * Context: 2334 * Kernel context. 2335 */ 2336int 2337qla24xx_link_initialize(scsi_qla_host_t *vha) 2338{ 2339 int rval; 2340 mbx_cmd_t mc; 2341 mbx_cmd_t *mcp = &mc; 2342 2343 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152, 2344 "Entered %s.\n", __func__); 2345 2346 if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw)) 2347 return QLA_FUNCTION_FAILED; 2348 2349 mcp->mb[0] = MBC_LINK_INITIALIZATION; 2350 mcp->mb[1] = BIT_4; 2351 if (vha->hw->operating_mode == LOOP) 2352 mcp->mb[1] |= BIT_6; 2353 else 2354 mcp->mb[1] |= BIT_5; 2355 mcp->mb[2] = 0; 2356 mcp->mb[3] = 0; 2357 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2358 mcp->in_mb = MBX_0; 2359 mcp->tov = MBX_TOV_SECONDS; 2360 mcp->flags = 0; 2361 rval = qla2x00_mailbox_command(vha, mcp); 2362 2363 if (rval != QLA_SUCCESS) { 2364 ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval); 2365 } else { 2366 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154, 2367 "Done %s.\n", __func__); 2368 } 2369 2370 return rval; 2371} 2372 2373/* 2374 * qla2x00_lip_reset 2375 * Issue LIP reset mailbox command. 2376 * 2377 * Input: 2378 * ha = adapter block pointer. 2379 * TARGET_QUEUE_LOCK must be released. 2380 * ADAPTER_STATE_LOCK must be released. 2381 * 2382 * Returns: 2383 * qla2x00 local function return status code. 2384 * 2385 * Context: 2386 * Kernel context. 2387 */ 2388int 2389qla2x00_lip_reset(scsi_qla_host_t *vha) 2390{ 2391 int rval; 2392 mbx_cmd_t mc; 2393 mbx_cmd_t *mcp = &mc; 2394 2395 ql_dbg(ql_dbg_disc, vha, 0x105a, 2396 "Entered %s.\n", __func__); 2397 2398 if (IS_CNA_CAPABLE(vha->hw)) { 2399 /* Logout across all FCFs. */ 2400 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2401 mcp->mb[1] = BIT_1; 2402 mcp->mb[2] = 0; 2403 mcp->out_mb = MBX_2|MBX_1|MBX_0; 2404 } else if (IS_FWI2_CAPABLE(vha->hw)) { 2405 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2406 mcp->mb[1] = BIT_4; 2407 mcp->mb[2] = 0; 2408 mcp->mb[3] = vha->hw->loop_reset_delay; 2409 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2410 } else { 2411 mcp->mb[0] = MBC_LIP_RESET; 2412 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2413 if (HAS_EXTENDED_IDS(vha->hw)) { 2414 mcp->mb[1] = 0x00ff; 2415 mcp->mb[10] = 0; 2416 mcp->out_mb |= MBX_10; 2417 } else { 2418 mcp->mb[1] = 0xff00; 2419 } 2420 mcp->mb[2] = vha->hw->loop_reset_delay; 2421 mcp->mb[3] = 0; 2422 } 2423 mcp->in_mb = MBX_0; 2424 mcp->tov = MBX_TOV_SECONDS; 2425 mcp->flags = 0; 2426 rval = qla2x00_mailbox_command(vha, mcp); 2427 2428 if (rval != QLA_SUCCESS) { 2429 /*EMPTY*/ 2430 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval); 2431 } else { 2432 /*EMPTY*/ 2433 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c, 2434 "Done %s.\n", __func__); 2435 } 2436 2437 return rval; 2438} 2439 2440/* 2441 * qla2x00_send_sns 2442 * Send SNS command. 2443 * 2444 * Input: 2445 * ha = adapter block pointer. 2446 * sns = pointer for command. 2447 * cmd_size = command size. 2448 * buf_size = response/command size. 2449 * TARGET_QUEUE_LOCK must be released. 2450 * ADAPTER_STATE_LOCK must be released. 2451 * 2452 * Returns: 2453 * qla2x00 local function return status code. 2454 * 2455 * Context: 2456 * Kernel context. 2457 */ 2458int 2459qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address, 2460 uint16_t cmd_size, size_t buf_size) 2461{ 2462 int rval; 2463 mbx_cmd_t mc; 2464 mbx_cmd_t *mcp = &mc; 2465 2466 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d, 2467 "Entered %s.\n", __func__); 2468 2469 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e, 2470 "Retry cnt=%d ratov=%d total tov=%d.\n", 2471 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov); 2472 2473 mcp->mb[0] = MBC_SEND_SNS_COMMAND; 2474 mcp->mb[1] = cmd_size; 2475 mcp->mb[2] = MSW(sns_phys_address); 2476 mcp->mb[3] = LSW(sns_phys_address); 2477 mcp->mb[6] = MSW(MSD(sns_phys_address)); 2478 mcp->mb[7] = LSW(MSD(sns_phys_address)); 2479 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2480 mcp->in_mb = MBX_0|MBX_1; 2481 mcp->buf_size = buf_size; 2482 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN; 2483 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2); 2484 rval = qla2x00_mailbox_command(vha, mcp); 2485 2486 if (rval != QLA_SUCCESS) { 2487 /*EMPTY*/ 2488 ql_dbg(ql_dbg_mbx, vha, 0x105f, 2489 "Failed=%x mb[0]=%x mb[1]=%x.\n", 2490 rval, mcp->mb[0], mcp->mb[1]); 2491 } else { 2492 /*EMPTY*/ 2493 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060, 2494 "Done %s.\n", __func__); 2495 } 2496 2497 return rval; 2498} 2499 2500int 2501qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, 2502 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt) 2503{ 2504 int rval; 2505 2506 struct logio_entry_24xx *lg; 2507 dma_addr_t lg_dma; 2508 uint32_t iop[2]; 2509 struct qla_hw_data *ha = vha->hw; 2510 struct req_que *req; 2511 2512 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061, 2513 "Entered %s.\n", __func__); 2514 2515 if (vha->vp_idx && vha->qpair) 2516 req = vha->qpair->req; 2517 else 2518 req = ha->req_q_map[0]; 2519 2520 lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); 2521 if (lg == NULL) { 2522 ql_log(ql_log_warn, vha, 0x1062, 2523 "Failed to allocate login IOCB.\n"); 2524 return QLA_MEMORY_ALLOC_FAILED; 2525 } 2526 2527 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE; 2528 lg->entry_count = 1; 2529 lg->handle = make_handle(req->id, lg->handle); 2530 lg->nport_handle = cpu_to_le16(loop_id); 2531 lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI); 2532 if (opt & BIT_0) 2533 lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI); 2534 if (opt & BIT_1) 2535 lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI); 2536 lg->port_id[0] = al_pa; 2537 lg->port_id[1] = area; 2538 lg->port_id[2] = domain; 2539 lg->vp_index = vha->vp_idx; 2540 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0, 2541 (ha->r_a_tov / 10 * 2) + 2); 2542 if (rval != QLA_SUCCESS) { 2543 ql_dbg(ql_dbg_mbx, vha, 0x1063, 2544 "Failed to issue login IOCB (%x).\n", rval); 2545 } else if (lg->entry_status != 0) { 2546 ql_dbg(ql_dbg_mbx, vha, 0x1064, 2547 "Failed to complete IOCB -- error status (%x).\n", 2548 lg->entry_status); 2549 rval = QLA_FUNCTION_FAILED; 2550 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) { 2551 iop[0] = le32_to_cpu(lg->io_parameter[0]); 2552 iop[1] = le32_to_cpu(lg->io_parameter[1]); 2553 2554 ql_dbg(ql_dbg_mbx, vha, 0x1065, 2555 "Failed to complete IOCB -- completion status (%x) " 2556 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status), 2557 iop[0], iop[1]); 2558 2559 switch (iop[0]) { 2560 case LSC_SCODE_PORTID_USED: 2561 mb[0] = MBS_PORT_ID_USED; 2562 mb[1] = LSW(iop[1]); 2563 break; 2564 case LSC_SCODE_NPORT_USED: 2565 mb[0] = MBS_LOOP_ID_USED; 2566 break; 2567 case LSC_SCODE_NOLINK: 2568 case LSC_SCODE_NOIOCB: 2569 case LSC_SCODE_NOXCB: 2570 case LSC_SCODE_CMD_FAILED: 2571 case LSC_SCODE_NOFABRIC: 2572 case LSC_SCODE_FW_NOT_READY: 2573 case LSC_SCODE_NOT_LOGGED_IN: 2574 case LSC_SCODE_NOPCB: 2575 case LSC_SCODE_ELS_REJECT: 2576 case LSC_SCODE_CMD_PARAM_ERR: 2577 case LSC_SCODE_NONPORT: 2578 case LSC_SCODE_LOGGED_IN: 2579 case LSC_SCODE_NOFLOGI_ACC: 2580 default: 2581 mb[0] = MBS_COMMAND_ERROR; 2582 break; 2583 } 2584 } else { 2585 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066, 2586 "Done %s.\n", __func__); 2587 2588 iop[0] = le32_to_cpu(lg->io_parameter[0]); 2589 2590 mb[0] = MBS_COMMAND_COMPLETE; 2591 mb[1] = 0; 2592 if (iop[0] & BIT_4) { 2593 if (iop[0] & BIT_8) 2594 mb[1] |= BIT_1; 2595 } else 2596 mb[1] = BIT_0; 2597 2598 /* Passback COS information. */ 2599 mb[10] = 0; 2600 if (lg->io_parameter[7] || lg->io_parameter[8]) 2601 mb[10] |= BIT_0; /* Class 2. */ 2602 if (lg->io_parameter[9] || lg->io_parameter[10]) 2603 mb[10] |= BIT_1; /* Class 3. */ 2604 if (lg->io_parameter[0] & cpu_to_le32(BIT_7)) 2605 mb[10] |= BIT_7; /* Confirmed Completion 2606 * Allowed 2607 */ 2608 } 2609 2610 dma_pool_free(ha->s_dma_pool, lg, lg_dma); 2611 2612 return rval; 2613} 2614 2615/* 2616 * qla2x00_login_fabric 2617 * Issue login fabric port mailbox command. 2618 * 2619 * Input: 2620 * ha = adapter block pointer. 2621 * loop_id = device loop ID. 2622 * domain = device domain. 2623 * area = device area. 2624 * al_pa = device AL_PA. 2625 * status = pointer for return status. 2626 * opt = command options. 2627 * TARGET_QUEUE_LOCK must be released. 2628 * ADAPTER_STATE_LOCK must be released. 2629 * 2630 * Returns: 2631 * qla2x00 local function return status code. 2632 * 2633 * Context: 2634 * Kernel context. 2635 */ 2636int 2637qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, 2638 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt) 2639{ 2640 int rval; 2641 mbx_cmd_t mc; 2642 mbx_cmd_t *mcp = &mc; 2643 struct qla_hw_data *ha = vha->hw; 2644 2645 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067, 2646 "Entered %s.\n", __func__); 2647 2648 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; 2649 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2650 if (HAS_EXTENDED_IDS(ha)) { 2651 mcp->mb[1] = loop_id; 2652 mcp->mb[10] = opt; 2653 mcp->out_mb |= MBX_10; 2654 } else { 2655 mcp->mb[1] = (loop_id << 8) | opt; 2656 } 2657 mcp->mb[2] = domain; 2658 mcp->mb[3] = area << 8 | al_pa; 2659 2660 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 2661 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 2662 mcp->flags = 0; 2663 rval = qla2x00_mailbox_command(vha, mcp); 2664 2665 /* Return mailbox statuses. */ 2666 if (mb != NULL) { 2667 mb[0] = mcp->mb[0]; 2668 mb[1] = mcp->mb[1]; 2669 mb[2] = mcp->mb[2]; 2670 mb[6] = mcp->mb[6]; 2671 mb[7] = mcp->mb[7]; 2672 /* COS retrieved from Get-Port-Database mailbox command. */ 2673 mb[10] = 0; 2674 } 2675 2676 if (rval != QLA_SUCCESS) { 2677 /* RLU tmp code: need to change main mailbox_command function to 2678 * return ok even when the mailbox completion value is not 2679 * SUCCESS. The caller needs to be responsible to interpret 2680 * the return values of this mailbox command if we're not 2681 * to change too much of the existing code. 2682 */ 2683 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 || 2684 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 || 2685 mcp->mb[0] == 0x4006) 2686 rval = QLA_SUCCESS; 2687 2688 /*EMPTY*/ 2689 ql_dbg(ql_dbg_mbx, vha, 0x1068, 2690 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 2691 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 2692 } else { 2693 /*EMPTY*/ 2694 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069, 2695 "Done %s.\n", __func__); 2696 } 2697 2698 return rval; 2699} 2700 2701/* 2702 * qla2x00_login_local_device 2703 * Issue login loop port mailbox command. 2704 * 2705 * Input: 2706 * ha = adapter block pointer. 2707 * loop_id = device loop ID. 2708 * opt = command options. 2709 * 2710 * Returns: 2711 * Return status code. 2712 * 2713 * Context: 2714 * Kernel context. 2715 * 2716 */ 2717int 2718qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport, 2719 uint16_t *mb_ret, uint8_t opt) 2720{ 2721 int rval; 2722 mbx_cmd_t mc; 2723 mbx_cmd_t *mcp = &mc; 2724 struct qla_hw_data *ha = vha->hw; 2725 2726 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a, 2727 "Entered %s.\n", __func__); 2728 2729 if (IS_FWI2_CAPABLE(ha)) 2730 return qla24xx_login_fabric(vha, fcport->loop_id, 2731 fcport->d_id.b.domain, fcport->d_id.b.area, 2732 fcport->d_id.b.al_pa, mb_ret, opt); 2733 2734 mcp->mb[0] = MBC_LOGIN_LOOP_PORT; 2735 if (HAS_EXTENDED_IDS(ha)) 2736 mcp->mb[1] = fcport->loop_id; 2737 else 2738 mcp->mb[1] = fcport->loop_id << 8; 2739 mcp->mb[2] = opt; 2740 mcp->out_mb = MBX_2|MBX_1|MBX_0; 2741 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0; 2742 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 2743 mcp->flags = 0; 2744 rval = qla2x00_mailbox_command(vha, mcp); 2745 2746 /* Return mailbox statuses. */ 2747 if (mb_ret != NULL) { 2748 mb_ret[0] = mcp->mb[0]; 2749 mb_ret[1] = mcp->mb[1]; 2750 mb_ret[6] = mcp->mb[6]; 2751 mb_ret[7] = mcp->mb[7]; 2752 } 2753 2754 if (rval != QLA_SUCCESS) { 2755 /* AV tmp code: need to change main mailbox_command function to 2756 * return ok even when the mailbox completion value is not 2757 * SUCCESS. The caller needs to be responsible to interpret 2758 * the return values of this mailbox command if we're not 2759 * to change too much of the existing code. 2760 */ 2761 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006) 2762 rval = QLA_SUCCESS; 2763 2764 ql_dbg(ql_dbg_mbx, vha, 0x106b, 2765 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n", 2766 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]); 2767 } else { 2768 /*EMPTY*/ 2769 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c, 2770 "Done %s.\n", __func__); 2771 } 2772 2773 return (rval); 2774} 2775 2776int 2777qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, 2778 uint8_t area, uint8_t al_pa) 2779{ 2780 int rval; 2781 struct logio_entry_24xx *lg; 2782 dma_addr_t lg_dma; 2783 struct qla_hw_data *ha = vha->hw; 2784 struct req_que *req; 2785 2786 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d, 2787 "Entered %s.\n", __func__); 2788 2789 lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); 2790 if (lg == NULL) { 2791 ql_log(ql_log_warn, vha, 0x106e, 2792 "Failed to allocate logout IOCB.\n"); 2793 return QLA_MEMORY_ALLOC_FAILED; 2794 } 2795 2796 req = vha->req; 2797 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE; 2798 lg->entry_count = 1; 2799 lg->handle = make_handle(req->id, lg->handle); 2800 lg->nport_handle = cpu_to_le16(loop_id); 2801 lg->control_flags = 2802 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO| 2803 LCF_FREE_NPORT); 2804 lg->port_id[0] = al_pa; 2805 lg->port_id[1] = area; 2806 lg->port_id[2] = domain; 2807 lg->vp_index = vha->vp_idx; 2808 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0, 2809 (ha->r_a_tov / 10 * 2) + 2); 2810 if (rval != QLA_SUCCESS) { 2811 ql_dbg(ql_dbg_mbx, vha, 0x106f, 2812 "Failed to issue logout IOCB (%x).\n", rval); 2813 } else if (lg->entry_status != 0) { 2814 ql_dbg(ql_dbg_mbx, vha, 0x1070, 2815 "Failed to complete IOCB -- error status (%x).\n", 2816 lg->entry_status); 2817 rval = QLA_FUNCTION_FAILED; 2818 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) { 2819 ql_dbg(ql_dbg_mbx, vha, 0x1071, 2820 "Failed to complete IOCB -- completion status (%x) " 2821 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status), 2822 le32_to_cpu(lg->io_parameter[0]), 2823 le32_to_cpu(lg->io_parameter[1])); 2824 } else { 2825 /*EMPTY*/ 2826 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072, 2827 "Done %s.\n", __func__); 2828 } 2829 2830 dma_pool_free(ha->s_dma_pool, lg, lg_dma); 2831 2832 return rval; 2833} 2834 2835/* 2836 * qla2x00_fabric_logout 2837 * Issue logout fabric port mailbox command. 2838 * 2839 * Input: 2840 * ha = adapter block pointer. 2841 * loop_id = device loop ID. 2842 * TARGET_QUEUE_LOCK must be released. 2843 * ADAPTER_STATE_LOCK must be released. 2844 * 2845 * Returns: 2846 * qla2x00 local function return status code. 2847 * 2848 * Context: 2849 * Kernel context. 2850 */ 2851int 2852qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, 2853 uint8_t area, uint8_t al_pa) 2854{ 2855 int rval; 2856 mbx_cmd_t mc; 2857 mbx_cmd_t *mcp = &mc; 2858 2859 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073, 2860 "Entered %s.\n", __func__); 2861 2862 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; 2863 mcp->out_mb = MBX_1|MBX_0; 2864 if (HAS_EXTENDED_IDS(vha->hw)) { 2865 mcp->mb[1] = loop_id; 2866 mcp->mb[10] = 0; 2867 mcp->out_mb |= MBX_10; 2868 } else { 2869 mcp->mb[1] = loop_id << 8; 2870 } 2871 2872 mcp->in_mb = MBX_1|MBX_0; 2873 mcp->tov = MBX_TOV_SECONDS; 2874 mcp->flags = 0; 2875 rval = qla2x00_mailbox_command(vha, mcp); 2876 2877 if (rval != QLA_SUCCESS) { 2878 /*EMPTY*/ 2879 ql_dbg(ql_dbg_mbx, vha, 0x1074, 2880 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]); 2881 } else { 2882 /*EMPTY*/ 2883 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075, 2884 "Done %s.\n", __func__); 2885 } 2886 2887 return rval; 2888} 2889 2890/* 2891 * qla2x00_full_login_lip 2892 * Issue full login LIP mailbox command. 2893 * 2894 * Input: 2895 * ha = adapter block pointer. 2896 * TARGET_QUEUE_LOCK must be released. 2897 * ADAPTER_STATE_LOCK must be released. 2898 * 2899 * Returns: 2900 * qla2x00 local function return status code. 2901 * 2902 * Context: 2903 * Kernel context. 2904 */ 2905int 2906qla2x00_full_login_lip(scsi_qla_host_t *vha) 2907{ 2908 int rval; 2909 mbx_cmd_t mc; 2910 mbx_cmd_t *mcp = &mc; 2911 2912 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076, 2913 "Entered %s.\n", __func__); 2914 2915 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2916 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_4 : 0; 2917 mcp->mb[2] = 0; 2918 mcp->mb[3] = 0; 2919 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 2920 mcp->in_mb = MBX_0; 2921 mcp->tov = MBX_TOV_SECONDS; 2922 mcp->flags = 0; 2923 rval = qla2x00_mailbox_command(vha, mcp); 2924 2925 if (rval != QLA_SUCCESS) { 2926 /*EMPTY*/ 2927 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval); 2928 } else { 2929 /*EMPTY*/ 2930 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078, 2931 "Done %s.\n", __func__); 2932 } 2933 2934 return rval; 2935} 2936 2937/* 2938 * qla2x00_get_id_list 2939 * 2940 * Input: 2941 * ha = adapter block pointer. 2942 * 2943 * Returns: 2944 * qla2x00 local function return status code. 2945 * 2946 * Context: 2947 * Kernel context. 2948 */ 2949int 2950qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma, 2951 uint16_t *entries) 2952{ 2953 int rval; 2954 mbx_cmd_t mc; 2955 mbx_cmd_t *mcp = &mc; 2956 2957 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079, 2958 "Entered %s.\n", __func__); 2959 2960 if (id_list == NULL) 2961 return QLA_FUNCTION_FAILED; 2962 2963 mcp->mb[0] = MBC_GET_ID_LIST; 2964 mcp->out_mb = MBX_0; 2965 if (IS_FWI2_CAPABLE(vha->hw)) { 2966 mcp->mb[2] = MSW(id_list_dma); 2967 mcp->mb[3] = LSW(id_list_dma); 2968 mcp->mb[6] = MSW(MSD(id_list_dma)); 2969 mcp->mb[7] = LSW(MSD(id_list_dma)); 2970 mcp->mb[8] = 0; 2971 mcp->mb[9] = vha->vp_idx; 2972 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2; 2973 } else { 2974 mcp->mb[1] = MSW(id_list_dma); 2975 mcp->mb[2] = LSW(id_list_dma); 2976 mcp->mb[3] = MSW(MSD(id_list_dma)); 2977 mcp->mb[6] = LSW(MSD(id_list_dma)); 2978 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; 2979 } 2980 mcp->in_mb = MBX_1|MBX_0; 2981 mcp->tov = MBX_TOV_SECONDS; 2982 mcp->flags = 0; 2983 rval = qla2x00_mailbox_command(vha, mcp); 2984 2985 if (rval != QLA_SUCCESS) { 2986 /*EMPTY*/ 2987 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval); 2988 } else { 2989 *entries = mcp->mb[1]; 2990 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b, 2991 "Done %s.\n", __func__); 2992 } 2993 2994 return rval; 2995} 2996 2997/* 2998 * qla2x00_get_resource_cnts 2999 * Get current firmware resource counts. 3000 * 3001 * Input: 3002 * ha = adapter block pointer. 3003 * 3004 * Returns: 3005 * qla2x00 local function return status code. 3006 * 3007 * Context: 3008 * Kernel context. 3009 */ 3010int 3011qla2x00_get_resource_cnts(scsi_qla_host_t *vha) 3012{ 3013 struct qla_hw_data *ha = vha->hw; 3014 int rval; 3015 mbx_cmd_t mc; 3016 mbx_cmd_t *mcp = &mc; 3017 3018 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c, 3019 "Entered %s.\n", __func__); 3020 3021 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; 3022 mcp->out_mb = MBX_0; 3023 mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 3024 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || 3025 IS_QLA27XX(ha) || IS_QLA28XX(ha)) 3026 mcp->in_mb |= MBX_12; 3027 mcp->tov = MBX_TOV_SECONDS; 3028 mcp->flags = 0; 3029 rval = qla2x00_mailbox_command(vha, mcp); 3030 3031 if (rval != QLA_SUCCESS) { 3032 /*EMPTY*/ 3033 ql_dbg(ql_dbg_mbx, vha, 0x107d, 3034 "Failed mb[0]=%x.\n", mcp->mb[0]); 3035 } else { 3036 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e, 3037 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x " 3038 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2], 3039 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10], 3040 mcp->mb[11], mcp->mb[12]); 3041 3042 ha->orig_fw_tgt_xcb_count = mcp->mb[1]; 3043 ha->cur_fw_tgt_xcb_count = mcp->mb[2]; 3044 ha->cur_fw_xcb_count = mcp->mb[3]; 3045 ha->orig_fw_xcb_count = mcp->mb[6]; 3046 ha->cur_fw_iocb_count = mcp->mb[7]; 3047 ha->orig_fw_iocb_count = mcp->mb[10]; 3048 if (ha->flags.npiv_supported) 3049 ha->max_npiv_vports = mcp->mb[11]; 3050 if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) 3051 ha->fw_max_fcf_count = mcp->mb[12]; 3052 } 3053 3054 return (rval); 3055} 3056 3057/* 3058 * qla2x00_get_fcal_position_map 3059 * Get FCAL (LILP) position map using mailbox command 3060 * 3061 * Input: 3062 * ha = adapter state pointer. 3063 * pos_map = buffer pointer (can be NULL). 3064 * 3065 * Returns: 3066 * qla2x00 local function return status code. 3067 * 3068 * Context: 3069 * Kernel context. 3070 */ 3071int 3072qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map, 3073 u8 *num_entries) 3074{ 3075 int rval; 3076 mbx_cmd_t mc; 3077 mbx_cmd_t *mcp = &mc; 3078 char *pmap; 3079 dma_addr_t pmap_dma; 3080 struct qla_hw_data *ha = vha->hw; 3081 3082 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f, 3083 "Entered %s.\n", __func__); 3084 3085 pmap = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma); 3086 if (pmap == NULL) { 3087 ql_log(ql_log_warn, vha, 0x1080, 3088 "Memory alloc failed.\n"); 3089 return QLA_MEMORY_ALLOC_FAILED; 3090 } 3091 3092 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP; 3093 mcp->mb[2] = MSW(pmap_dma); 3094 mcp->mb[3] = LSW(pmap_dma); 3095 mcp->mb[6] = MSW(MSD(pmap_dma)); 3096 mcp->mb[7] = LSW(MSD(pmap_dma)); 3097 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 3098 mcp->in_mb = MBX_1|MBX_0; 3099 mcp->buf_size = FCAL_MAP_SIZE; 3100 mcp->flags = MBX_DMA_IN; 3101 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 3102 rval = qla2x00_mailbox_command(vha, mcp); 3103 3104 if (rval == QLA_SUCCESS) { 3105 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081, 3106 "mb0/mb1=%x/%X FC/AL position map size (%x).\n", 3107 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]); 3108 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d, 3109 pmap, pmap[0] + 1); 3110 3111 if (pos_map) 3112 memcpy(pos_map, pmap, FCAL_MAP_SIZE); 3113 if (num_entries) 3114 *num_entries = pmap[0]; 3115 } 3116 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma); 3117 3118 if (rval != QLA_SUCCESS) { 3119 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval); 3120 } else { 3121 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083, 3122 "Done %s.\n", __func__); 3123 } 3124 3125 return rval; 3126} 3127 3128/* 3129 * qla2x00_get_link_status 3130 * 3131 * Input: 3132 * ha = adapter block pointer. 3133 * loop_id = device loop ID. 3134 * ret_buf = pointer to link status return buffer. 3135 * 3136 * Returns: 3137 * 0 = success. 3138 * BIT_0 = mem alloc error. 3139 * BIT_1 = mailbox error. 3140 */ 3141int 3142qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id, 3143 struct link_statistics *stats, dma_addr_t stats_dma) 3144{ 3145 int rval; 3146 mbx_cmd_t mc; 3147 mbx_cmd_t *mcp = &mc; 3148 uint32_t *iter = (uint32_t *)stats; 3149 ushort dwords = offsetof(typeof(*stats), link_up_cnt)/sizeof(*iter); 3150 struct qla_hw_data *ha = vha->hw; 3151 3152 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084, 3153 "Entered %s.\n", __func__); 3154 3155 mcp->mb[0] = MBC_GET_LINK_STATUS; 3156 mcp->mb[2] = MSW(LSD(stats_dma)); 3157 mcp->mb[3] = LSW(LSD(stats_dma)); 3158 mcp->mb[6] = MSW(MSD(stats_dma)); 3159 mcp->mb[7] = LSW(MSD(stats_dma)); 3160 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 3161 mcp->in_mb = MBX_0; 3162 if (IS_FWI2_CAPABLE(ha)) { 3163 mcp->mb[1] = loop_id; 3164 mcp->mb[4] = 0; 3165 mcp->mb[10] = 0; 3166 mcp->out_mb |= MBX_10|MBX_4|MBX_1; 3167 mcp->in_mb |= MBX_1; 3168 } else if (HAS_EXTENDED_IDS(ha)) { 3169 mcp->mb[1] = loop_id; 3170 mcp->mb[10] = 0; 3171 mcp->out_mb |= MBX_10|MBX_1; 3172 } else { 3173 mcp->mb[1] = loop_id << 8; 3174 mcp->out_mb |= MBX_1; 3175 } 3176 mcp->tov = MBX_TOV_SECONDS; 3177 mcp->flags = IOCTL_CMD; 3178 rval = qla2x00_mailbox_command(vha, mcp); 3179 3180 if (rval == QLA_SUCCESS) { 3181 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { 3182 ql_dbg(ql_dbg_mbx, vha, 0x1085, 3183 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3184 rval = QLA_FUNCTION_FAILED; 3185 } else { 3186 /* Re-endianize - firmware data is le32. */ 3187 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086, 3188 "Done %s.\n", __func__); 3189 for ( ; dwords--; iter++) 3190 le32_to_cpus(iter); 3191 } 3192 } else { 3193 /* Failed. */ 3194 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval); 3195 } 3196 3197 return rval; 3198} 3199 3200int 3201qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats, 3202 dma_addr_t stats_dma, uint16_t options) 3203{ 3204 int rval; 3205 mbx_cmd_t mc; 3206 mbx_cmd_t *mcp = &mc; 3207 uint32_t *iter = (uint32_t *)stats; 3208 ushort dwords = sizeof(*stats)/sizeof(*iter); 3209 3210 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088, 3211 "Entered %s.\n", __func__); 3212 3213 memset(&mc, 0, sizeof(mc)); 3214 mc.mb[0] = MBC_GET_LINK_PRIV_STATS; 3215 mc.mb[2] = MSW(LSD(stats_dma)); 3216 mc.mb[3] = LSW(LSD(stats_dma)); 3217 mc.mb[6] = MSW(MSD(stats_dma)); 3218 mc.mb[7] = LSW(MSD(stats_dma)); 3219 mc.mb[8] = dwords; 3220 mc.mb[9] = vha->vp_idx; 3221 mc.mb[10] = options; 3222 3223 rval = qla24xx_send_mb_cmd(vha, &mc); 3224 3225 if (rval == QLA_SUCCESS) { 3226 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { 3227 ql_dbg(ql_dbg_mbx, vha, 0x1089, 3228 "Failed mb[0]=%x.\n", mcp->mb[0]); 3229 rval = QLA_FUNCTION_FAILED; 3230 } else { 3231 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a, 3232 "Done %s.\n", __func__); 3233 /* Re-endianize - firmware data is le32. */ 3234 for ( ; dwords--; iter++) 3235 le32_to_cpus(iter); 3236 } 3237 } else { 3238 /* Failed. */ 3239 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval); 3240 } 3241 3242 return rval; 3243} 3244 3245int 3246qla24xx_abort_command(srb_t *sp) 3247{ 3248 int rval; 3249 unsigned long flags = 0; 3250 3251 struct abort_entry_24xx *abt; 3252 dma_addr_t abt_dma; 3253 uint32_t handle; 3254 fc_port_t *fcport = sp->fcport; 3255 struct scsi_qla_host *vha = fcport->vha; 3256 struct qla_hw_data *ha = vha->hw; 3257 struct req_que *req; 3258 struct qla_qpair *qpair = sp->qpair; 3259 3260 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c, 3261 "Entered %s.\n", __func__); 3262 3263 if (sp->qpair) 3264 req = sp->qpair->req; 3265 else 3266 return QLA_ERR_NO_QPAIR; 3267 3268 if (ql2xasynctmfenable) 3269 return qla24xx_async_abort_command(sp); 3270 3271 spin_lock_irqsave(qpair->qp_lock_ptr, flags); 3272 for (handle = 1; handle < req->num_outstanding_cmds; handle++) { 3273 if (req->outstanding_cmds[handle] == sp) 3274 break; 3275 } 3276 spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 3277 if (handle == req->num_outstanding_cmds) { 3278 /* Command not found. */ 3279 return QLA_ERR_NOT_FOUND; 3280 } 3281 3282 abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma); 3283 if (abt == NULL) { 3284 ql_log(ql_log_warn, vha, 0x108d, 3285 "Failed to allocate abort IOCB.\n"); 3286 return QLA_MEMORY_ALLOC_FAILED; 3287 } 3288 3289 abt->entry_type = ABORT_IOCB_TYPE; 3290 abt->entry_count = 1; 3291 abt->handle = make_handle(req->id, abt->handle); 3292 abt->nport_handle = cpu_to_le16(fcport->loop_id); 3293 abt->handle_to_abort = make_handle(req->id, handle); 3294 abt->port_id[0] = fcport->d_id.b.al_pa; 3295 abt->port_id[1] = fcport->d_id.b.area; 3296 abt->port_id[2] = fcport->d_id.b.domain; 3297 abt->vp_index = fcport->vha->vp_idx; 3298 3299 abt->req_que_no = cpu_to_le16(req->id); 3300 /* Need to pass original sp */ 3301 qla_nvme_abort_set_option(abt, sp); 3302 3303 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0); 3304 if (rval != QLA_SUCCESS) { 3305 ql_dbg(ql_dbg_mbx, vha, 0x108e, 3306 "Failed to issue IOCB (%x).\n", rval); 3307 } else if (abt->entry_status != 0) { 3308 ql_dbg(ql_dbg_mbx, vha, 0x108f, 3309 "Failed to complete IOCB -- error status (%x).\n", 3310 abt->entry_status); 3311 rval = QLA_FUNCTION_FAILED; 3312 } else if (abt->nport_handle != cpu_to_le16(0)) { 3313 ql_dbg(ql_dbg_mbx, vha, 0x1090, 3314 "Failed to complete IOCB -- completion status (%x).\n", 3315 le16_to_cpu(abt->nport_handle)); 3316 if (abt->nport_handle == cpu_to_le16(CS_IOCB_ERROR)) 3317 rval = QLA_FUNCTION_PARAMETER_ERROR; 3318 else 3319 rval = QLA_FUNCTION_FAILED; 3320 } else { 3321 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091, 3322 "Done %s.\n", __func__); 3323 } 3324 if (rval == QLA_SUCCESS) 3325 qla_nvme_abort_process_comp_status(abt, sp); 3326 3327 qla_wait_nvme_release_cmd_kref(sp); 3328 3329 dma_pool_free(ha->s_dma_pool, abt, abt_dma); 3330 3331 return rval; 3332} 3333 3334struct tsk_mgmt_cmd { 3335 union { 3336 struct tsk_mgmt_entry tsk; 3337 struct sts_entry_24xx sts; 3338 } p; 3339}; 3340 3341static int 3342__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, 3343 uint64_t l, int tag) 3344{ 3345 int rval, rval2; 3346 struct tsk_mgmt_cmd *tsk; 3347 struct sts_entry_24xx *sts; 3348 dma_addr_t tsk_dma; 3349 scsi_qla_host_t *vha; 3350 struct qla_hw_data *ha; 3351 struct req_que *req; 3352 struct qla_qpair *qpair; 3353 3354 vha = fcport->vha; 3355 ha = vha->hw; 3356 req = vha->req; 3357 3358 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092, 3359 "Entered %s.\n", __func__); 3360 3361 if (vha->vp_idx && vha->qpair) { 3362 /* NPIV port */ 3363 qpair = vha->qpair; 3364 req = qpair->req; 3365 } 3366 3367 tsk = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); 3368 if (tsk == NULL) { 3369 ql_log(ql_log_warn, vha, 0x1093, 3370 "Failed to allocate task management IOCB.\n"); 3371 return QLA_MEMORY_ALLOC_FAILED; 3372 } 3373 3374 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE; 3375 tsk->p.tsk.entry_count = 1; 3376 tsk->p.tsk.handle = make_handle(req->id, tsk->p.tsk.handle); 3377 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); 3378 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 3379 tsk->p.tsk.control_flags = cpu_to_le32(type); 3380 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; 3381 tsk->p.tsk.port_id[1] = fcport->d_id.b.area; 3382 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; 3383 tsk->p.tsk.vp_index = fcport->vha->vp_idx; 3384 if (type == TCF_LUN_RESET) { 3385 int_to_scsilun(l, &tsk->p.tsk.lun); 3386 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, 3387 sizeof(tsk->p.tsk.lun)); 3388 } 3389 3390 sts = &tsk->p.sts; 3391 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0); 3392 if (rval != QLA_SUCCESS) { 3393 ql_dbg(ql_dbg_mbx, vha, 0x1094, 3394 "Failed to issue %s reset IOCB (%x).\n", name, rval); 3395 } else if (sts->entry_status != 0) { 3396 ql_dbg(ql_dbg_mbx, vha, 0x1095, 3397 "Failed to complete IOCB -- error status (%x).\n", 3398 sts->entry_status); 3399 rval = QLA_FUNCTION_FAILED; 3400 } else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) { 3401 ql_dbg(ql_dbg_mbx, vha, 0x1096, 3402 "Failed to complete IOCB -- completion status (%x).\n", 3403 le16_to_cpu(sts->comp_status)); 3404 rval = QLA_FUNCTION_FAILED; 3405 } else if (le16_to_cpu(sts->scsi_status) & 3406 SS_RESPONSE_INFO_LEN_VALID) { 3407 if (le32_to_cpu(sts->rsp_data_len) < 4) { 3408 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097, 3409 "Ignoring inconsistent data length -- not enough " 3410 "response info (%d).\n", 3411 le32_to_cpu(sts->rsp_data_len)); 3412 } else if (sts->data[3]) { 3413 ql_dbg(ql_dbg_mbx, vha, 0x1098, 3414 "Failed to complete IOCB -- response (%x).\n", 3415 sts->data[3]); 3416 rval = QLA_FUNCTION_FAILED; 3417 } 3418 } 3419 3420 /* Issue marker IOCB. */ 3421 rval2 = qla2x00_marker(vha, ha->base_qpair, fcport->loop_id, l, 3422 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID); 3423 if (rval2 != QLA_SUCCESS) { 3424 ql_dbg(ql_dbg_mbx, vha, 0x1099, 3425 "Failed to issue marker IOCB (%x).\n", rval2); 3426 } else { 3427 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a, 3428 "Done %s.\n", __func__); 3429 } 3430 3431 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma); 3432 3433 return rval; 3434} 3435 3436int 3437qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag) 3438{ 3439 struct qla_hw_data *ha = fcport->vha->hw; 3440 3441 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha)) 3442 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag); 3443 3444 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag); 3445} 3446 3447int 3448qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag) 3449{ 3450 struct qla_hw_data *ha = fcport->vha->hw; 3451 3452 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha)) 3453 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag); 3454 3455 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag); 3456} 3457 3458int 3459qla2x00_system_error(scsi_qla_host_t *vha) 3460{ 3461 int rval; 3462 mbx_cmd_t mc; 3463 mbx_cmd_t *mcp = &mc; 3464 struct qla_hw_data *ha = vha->hw; 3465 3466 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha)) 3467 return QLA_FUNCTION_FAILED; 3468 3469 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b, 3470 "Entered %s.\n", __func__); 3471 3472 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR; 3473 mcp->out_mb = MBX_0; 3474 mcp->in_mb = MBX_0; 3475 mcp->tov = 5; 3476 mcp->flags = 0; 3477 rval = qla2x00_mailbox_command(vha, mcp); 3478 3479 if (rval != QLA_SUCCESS) { 3480 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval); 3481 } else { 3482 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d, 3483 "Done %s.\n", __func__); 3484 } 3485 3486 return rval; 3487} 3488 3489int 3490qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data) 3491{ 3492 int rval; 3493 mbx_cmd_t mc; 3494 mbx_cmd_t *mcp = &mc; 3495 3496 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) && 3497 !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 3498 return QLA_FUNCTION_FAILED; 3499 3500 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182, 3501 "Entered %s.\n", __func__); 3502 3503 mcp->mb[0] = MBC_WRITE_SERDES; 3504 mcp->mb[1] = addr; 3505 if (IS_QLA2031(vha->hw)) 3506 mcp->mb[2] = data & 0xff; 3507 else 3508 mcp->mb[2] = data; 3509 3510 mcp->mb[3] = 0; 3511 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 3512 mcp->in_mb = MBX_0; 3513 mcp->tov = MBX_TOV_SECONDS; 3514 mcp->flags = 0; 3515 rval = qla2x00_mailbox_command(vha, mcp); 3516 3517 if (rval != QLA_SUCCESS) { 3518 ql_dbg(ql_dbg_mbx, vha, 0x1183, 3519 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3520 } else { 3521 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184, 3522 "Done %s.\n", __func__); 3523 } 3524 3525 return rval; 3526} 3527 3528int 3529qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data) 3530{ 3531 int rval; 3532 mbx_cmd_t mc; 3533 mbx_cmd_t *mcp = &mc; 3534 3535 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) && 3536 !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 3537 return QLA_FUNCTION_FAILED; 3538 3539 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185, 3540 "Entered %s.\n", __func__); 3541 3542 mcp->mb[0] = MBC_READ_SERDES; 3543 mcp->mb[1] = addr; 3544 mcp->mb[3] = 0; 3545 mcp->out_mb = MBX_3|MBX_1|MBX_0; 3546 mcp->in_mb = MBX_1|MBX_0; 3547 mcp->tov = MBX_TOV_SECONDS; 3548 mcp->flags = 0; 3549 rval = qla2x00_mailbox_command(vha, mcp); 3550 3551 if (IS_QLA2031(vha->hw)) 3552 *data = mcp->mb[1] & 0xff; 3553 else 3554 *data = mcp->mb[1]; 3555 3556 if (rval != QLA_SUCCESS) { 3557 ql_dbg(ql_dbg_mbx, vha, 0x1186, 3558 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3559 } else { 3560 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187, 3561 "Done %s.\n", __func__); 3562 } 3563 3564 return rval; 3565} 3566 3567int 3568qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data) 3569{ 3570 int rval; 3571 mbx_cmd_t mc; 3572 mbx_cmd_t *mcp = &mc; 3573 3574 if (!IS_QLA8044(vha->hw)) 3575 return QLA_FUNCTION_FAILED; 3576 3577 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x11a0, 3578 "Entered %s.\n", __func__); 3579 3580 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG; 3581 mcp->mb[1] = HCS_WRITE_SERDES; 3582 mcp->mb[3] = LSW(addr); 3583 mcp->mb[4] = MSW(addr); 3584 mcp->mb[5] = LSW(data); 3585 mcp->mb[6] = MSW(data); 3586 mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; 3587 mcp->in_mb = MBX_0; 3588 mcp->tov = MBX_TOV_SECONDS; 3589 mcp->flags = 0; 3590 rval = qla2x00_mailbox_command(vha, mcp); 3591 3592 if (rval != QLA_SUCCESS) { 3593 ql_dbg(ql_dbg_mbx, vha, 0x11a1, 3594 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3595 } else { 3596 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188, 3597 "Done %s.\n", __func__); 3598 } 3599 3600 return rval; 3601} 3602 3603int 3604qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data) 3605{ 3606 int rval; 3607 mbx_cmd_t mc; 3608 mbx_cmd_t *mcp = &mc; 3609 3610 if (!IS_QLA8044(vha->hw)) 3611 return QLA_FUNCTION_FAILED; 3612 3613 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189, 3614 "Entered %s.\n", __func__); 3615 3616 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG; 3617 mcp->mb[1] = HCS_READ_SERDES; 3618 mcp->mb[3] = LSW(addr); 3619 mcp->mb[4] = MSW(addr); 3620 mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0; 3621 mcp->in_mb = MBX_2|MBX_1|MBX_0; 3622 mcp->tov = MBX_TOV_SECONDS; 3623 mcp->flags = 0; 3624 rval = qla2x00_mailbox_command(vha, mcp); 3625 3626 *data = mcp->mb[2] << 16 | mcp->mb[1]; 3627 3628 if (rval != QLA_SUCCESS) { 3629 ql_dbg(ql_dbg_mbx, vha, 0x118a, 3630 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3631 } else { 3632 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b, 3633 "Done %s.\n", __func__); 3634 } 3635 3636 return rval; 3637} 3638 3639/** 3640 * qla2x00_set_serdes_params() - 3641 * @vha: HA context 3642 * @sw_em_1g: serial link options 3643 * @sw_em_2g: serial link options 3644 * @sw_em_4g: serial link options 3645 * 3646 * Returns 3647 */ 3648int 3649qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g, 3650 uint16_t sw_em_2g, uint16_t sw_em_4g) 3651{ 3652 int rval; 3653 mbx_cmd_t mc; 3654 mbx_cmd_t *mcp = &mc; 3655 3656 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e, 3657 "Entered %s.\n", __func__); 3658 3659 mcp->mb[0] = MBC_SERDES_PARAMS; 3660 mcp->mb[1] = BIT_0; 3661 mcp->mb[2] = sw_em_1g | BIT_15; 3662 mcp->mb[3] = sw_em_2g | BIT_15; 3663 mcp->mb[4] = sw_em_4g | BIT_15; 3664 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3665 mcp->in_mb = MBX_0; 3666 mcp->tov = MBX_TOV_SECONDS; 3667 mcp->flags = 0; 3668 rval = qla2x00_mailbox_command(vha, mcp); 3669 3670 if (rval != QLA_SUCCESS) { 3671 /*EMPTY*/ 3672 ql_dbg(ql_dbg_mbx, vha, 0x109f, 3673 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3674 } else { 3675 /*EMPTY*/ 3676 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0, 3677 "Done %s.\n", __func__); 3678 } 3679 3680 return rval; 3681} 3682 3683int 3684qla2x00_stop_firmware(scsi_qla_host_t *vha) 3685{ 3686 int rval; 3687 mbx_cmd_t mc; 3688 mbx_cmd_t *mcp = &mc; 3689 3690 if (!IS_FWI2_CAPABLE(vha->hw)) 3691 return QLA_FUNCTION_FAILED; 3692 3693 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1, 3694 "Entered %s.\n", __func__); 3695 3696 mcp->mb[0] = MBC_STOP_FIRMWARE; 3697 mcp->mb[1] = 0; 3698 mcp->out_mb = MBX_1|MBX_0; 3699 mcp->in_mb = MBX_0; 3700 mcp->tov = 5; 3701 mcp->flags = 0; 3702 rval = qla2x00_mailbox_command(vha, mcp); 3703 3704 if (rval != QLA_SUCCESS) { 3705 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval); 3706 if (mcp->mb[0] == MBS_INVALID_COMMAND) 3707 rval = QLA_INVALID_COMMAND; 3708 } else { 3709 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3, 3710 "Done %s.\n", __func__); 3711 } 3712 3713 return rval; 3714} 3715 3716int 3717qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma, 3718 uint16_t buffers) 3719{ 3720 int rval; 3721 mbx_cmd_t mc; 3722 mbx_cmd_t *mcp = &mc; 3723 3724 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4, 3725 "Entered %s.\n", __func__); 3726 3727 if (!IS_FWI2_CAPABLE(vha->hw)) 3728 return QLA_FUNCTION_FAILED; 3729 3730 if (unlikely(pci_channel_offline(vha->hw->pdev))) 3731 return QLA_FUNCTION_FAILED; 3732 3733 mcp->mb[0] = MBC_TRACE_CONTROL; 3734 mcp->mb[1] = TC_EFT_ENABLE; 3735 mcp->mb[2] = LSW(eft_dma); 3736 mcp->mb[3] = MSW(eft_dma); 3737 mcp->mb[4] = LSW(MSD(eft_dma)); 3738 mcp->mb[5] = MSW(MSD(eft_dma)); 3739 mcp->mb[6] = buffers; 3740 mcp->mb[7] = TC_AEN_DISABLE; 3741 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3742 mcp->in_mb = MBX_1|MBX_0; 3743 mcp->tov = MBX_TOV_SECONDS; 3744 mcp->flags = 0; 3745 rval = qla2x00_mailbox_command(vha, mcp); 3746 if (rval != QLA_SUCCESS) { 3747 ql_dbg(ql_dbg_mbx, vha, 0x10a5, 3748 "Failed=%x mb[0]=%x mb[1]=%x.\n", 3749 rval, mcp->mb[0], mcp->mb[1]); 3750 } else { 3751 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6, 3752 "Done %s.\n", __func__); 3753 } 3754 3755 return rval; 3756} 3757 3758int 3759qla2x00_disable_eft_trace(scsi_qla_host_t *vha) 3760{ 3761 int rval; 3762 mbx_cmd_t mc; 3763 mbx_cmd_t *mcp = &mc; 3764 3765 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7, 3766 "Entered %s.\n", __func__); 3767 3768 if (!IS_FWI2_CAPABLE(vha->hw)) 3769 return QLA_FUNCTION_FAILED; 3770 3771 if (unlikely(pci_channel_offline(vha->hw->pdev))) 3772 return QLA_FUNCTION_FAILED; 3773 3774 mcp->mb[0] = MBC_TRACE_CONTROL; 3775 mcp->mb[1] = TC_EFT_DISABLE; 3776 mcp->out_mb = MBX_1|MBX_0; 3777 mcp->in_mb = MBX_1|MBX_0; 3778 mcp->tov = MBX_TOV_SECONDS; 3779 mcp->flags = 0; 3780 rval = qla2x00_mailbox_command(vha, mcp); 3781 if (rval != QLA_SUCCESS) { 3782 ql_dbg(ql_dbg_mbx, vha, 0x10a8, 3783 "Failed=%x mb[0]=%x mb[1]=%x.\n", 3784 rval, mcp->mb[0], mcp->mb[1]); 3785 } else { 3786 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9, 3787 "Done %s.\n", __func__); 3788 } 3789 3790 return rval; 3791} 3792 3793int 3794qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, 3795 uint16_t buffers, uint16_t *mb, uint32_t *dwords) 3796{ 3797 int rval; 3798 mbx_cmd_t mc; 3799 mbx_cmd_t *mcp = &mc; 3800 3801 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa, 3802 "Entered %s.\n", __func__); 3803 3804 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) && 3805 !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && 3806 !IS_QLA28XX(vha->hw)) 3807 return QLA_FUNCTION_FAILED; 3808 3809 if (unlikely(pci_channel_offline(vha->hw->pdev))) 3810 return QLA_FUNCTION_FAILED; 3811 3812 mcp->mb[0] = MBC_TRACE_CONTROL; 3813 mcp->mb[1] = TC_FCE_ENABLE; 3814 mcp->mb[2] = LSW(fce_dma); 3815 mcp->mb[3] = MSW(fce_dma); 3816 mcp->mb[4] = LSW(MSD(fce_dma)); 3817 mcp->mb[5] = MSW(MSD(fce_dma)); 3818 mcp->mb[6] = buffers; 3819 mcp->mb[7] = TC_AEN_DISABLE; 3820 mcp->mb[8] = 0; 3821 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE; 3822 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE; 3823 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| 3824 MBX_1|MBX_0; 3825 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 3826 mcp->tov = MBX_TOV_SECONDS; 3827 mcp->flags = 0; 3828 rval = qla2x00_mailbox_command(vha, mcp); 3829 if (rval != QLA_SUCCESS) { 3830 ql_dbg(ql_dbg_mbx, vha, 0x10ab, 3831 "Failed=%x mb[0]=%x mb[1]=%x.\n", 3832 rval, mcp->mb[0], mcp->mb[1]); 3833 } else { 3834 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac, 3835 "Done %s.\n", __func__); 3836 3837 if (mb) 3838 memcpy(mb, mcp->mb, 8 * sizeof(*mb)); 3839 if (dwords) 3840 *dwords = buffers; 3841 } 3842 3843 return rval; 3844} 3845 3846int 3847qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd) 3848{ 3849 int rval; 3850 mbx_cmd_t mc; 3851 mbx_cmd_t *mcp = &mc; 3852 3853 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad, 3854 "Entered %s.\n", __func__); 3855 3856 if (!IS_FWI2_CAPABLE(vha->hw)) 3857 return QLA_FUNCTION_FAILED; 3858 3859 if (unlikely(pci_channel_offline(vha->hw->pdev))) 3860 return QLA_FUNCTION_FAILED; 3861 3862 mcp->mb[0] = MBC_TRACE_CONTROL; 3863 mcp->mb[1] = TC_FCE_DISABLE; 3864 mcp->mb[2] = TC_FCE_DISABLE_TRACE; 3865 mcp->out_mb = MBX_2|MBX_1|MBX_0; 3866 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| 3867 MBX_1|MBX_0; 3868 mcp->tov = MBX_TOV_SECONDS; 3869 mcp->flags = 0; 3870 rval = qla2x00_mailbox_command(vha, mcp); 3871 if (rval != QLA_SUCCESS) { 3872 ql_dbg(ql_dbg_mbx, vha, 0x10ae, 3873 "Failed=%x mb[0]=%x mb[1]=%x.\n", 3874 rval, mcp->mb[0], mcp->mb[1]); 3875 } else { 3876 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af, 3877 "Done %s.\n", __func__); 3878 3879 if (wr) 3880 *wr = (uint64_t) mcp->mb[5] << 48 | 3881 (uint64_t) mcp->mb[4] << 32 | 3882 (uint64_t) mcp->mb[3] << 16 | 3883 (uint64_t) mcp->mb[2]; 3884 if (rd) 3885 *rd = (uint64_t) mcp->mb[9] << 48 | 3886 (uint64_t) mcp->mb[8] << 32 | 3887 (uint64_t) mcp->mb[7] << 16 | 3888 (uint64_t) mcp->mb[6]; 3889 } 3890 3891 return rval; 3892} 3893 3894int 3895qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, 3896 uint16_t *port_speed, uint16_t *mb) 3897{ 3898 int rval; 3899 mbx_cmd_t mc; 3900 mbx_cmd_t *mcp = &mc; 3901 3902 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0, 3903 "Entered %s.\n", __func__); 3904 3905 if (!IS_IIDMA_CAPABLE(vha->hw)) 3906 return QLA_FUNCTION_FAILED; 3907 3908 mcp->mb[0] = MBC_PORT_PARAMS; 3909 mcp->mb[1] = loop_id; 3910 mcp->mb[2] = mcp->mb[3] = 0; 3911 mcp->mb[9] = vha->vp_idx; 3912 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; 3913 mcp->in_mb = MBX_3|MBX_1|MBX_0; 3914 mcp->tov = MBX_TOV_SECONDS; 3915 mcp->flags = 0; 3916 rval = qla2x00_mailbox_command(vha, mcp); 3917 3918 /* Return mailbox statuses. */ 3919 if (mb) { 3920 mb[0] = mcp->mb[0]; 3921 mb[1] = mcp->mb[1]; 3922 mb[3] = mcp->mb[3]; 3923 } 3924 3925 if (rval != QLA_SUCCESS) { 3926 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval); 3927 } else { 3928 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2, 3929 "Done %s.\n", __func__); 3930 if (port_speed) 3931 *port_speed = mcp->mb[3]; 3932 } 3933 3934 return rval; 3935} 3936 3937int 3938qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, 3939 uint16_t port_speed, uint16_t *mb) 3940{ 3941 int rval; 3942 mbx_cmd_t mc; 3943 mbx_cmd_t *mcp = &mc; 3944 3945 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3, 3946 "Entered %s.\n", __func__); 3947 3948 if (!IS_IIDMA_CAPABLE(vha->hw)) 3949 return QLA_FUNCTION_FAILED; 3950 3951 mcp->mb[0] = MBC_PORT_PARAMS; 3952 mcp->mb[1] = loop_id; 3953 mcp->mb[2] = BIT_0; 3954 mcp->mb[3] = port_speed & 0x3F; 3955 mcp->mb[9] = vha->vp_idx; 3956 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; 3957 mcp->in_mb = MBX_3|MBX_1|MBX_0; 3958 mcp->tov = MBX_TOV_SECONDS; 3959 mcp->flags = 0; 3960 rval = qla2x00_mailbox_command(vha, mcp); 3961 3962 /* Return mailbox statuses. */ 3963 if (mb) { 3964 mb[0] = mcp->mb[0]; 3965 mb[1] = mcp->mb[1]; 3966 mb[3] = mcp->mb[3]; 3967 } 3968 3969 if (rval != QLA_SUCCESS) { 3970 ql_dbg(ql_dbg_mbx, vha, 0x10b4, 3971 "Failed=%x.\n", rval); 3972 } else { 3973 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5, 3974 "Done %s.\n", __func__); 3975 } 3976 3977 return rval; 3978} 3979 3980void 3981qla24xx_report_id_acquisition(scsi_qla_host_t *vha, 3982 struct vp_rpt_id_entry_24xx *rptid_entry) 3983{ 3984 struct qla_hw_data *ha = vha->hw; 3985 scsi_qla_host_t *vp = NULL; 3986 unsigned long flags; 3987 int found; 3988 port_id_t id; 3989 struct fc_port *fcport; 3990 3991 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6, 3992 "Entered %s.\n", __func__); 3993 3994 if (rptid_entry->entry_status != 0) 3995 return; 3996 3997 id.b.domain = rptid_entry->port_id[2]; 3998 id.b.area = rptid_entry->port_id[1]; 3999 id.b.al_pa = rptid_entry->port_id[0]; 4000 id.b.rsvd_1 = 0; 4001 ha->flags.n2n_ae = 0; 4002 4003 if (rptid_entry->format == 0) { 4004 /* loop */ 4005 ql_dbg(ql_dbg_async, vha, 0x10b7, 4006 "Format 0 : Number of VPs setup %d, number of " 4007 "VPs acquired %d.\n", rptid_entry->vp_setup, 4008 rptid_entry->vp_acquired); 4009 ql_dbg(ql_dbg_async, vha, 0x10b8, 4010 "Primary port id %02x%02x%02x.\n", 4011 rptid_entry->port_id[2], rptid_entry->port_id[1], 4012 rptid_entry->port_id[0]); 4013 ha->current_topology = ISP_CFG_NL; 4014 qla_update_host_map(vha, id); 4015 4016 } else if (rptid_entry->format == 1) { 4017 /* fabric */ 4018 ql_dbg(ql_dbg_async, vha, 0x10b9, 4019 "Format 1: VP[%d] enabled - status %d - with " 4020 "port id %02x%02x%02x.\n", rptid_entry->vp_idx, 4021 rptid_entry->vp_status, 4022 rptid_entry->port_id[2], rptid_entry->port_id[1], 4023 rptid_entry->port_id[0]); 4024 ql_dbg(ql_dbg_async, vha, 0x5075, 4025 "Format 1: Remote WWPN %8phC.\n", 4026 rptid_entry->u.f1.port_name); 4027 4028 ql_dbg(ql_dbg_async, vha, 0x5075, 4029 "Format 1: WWPN %8phC.\n", 4030 vha->port_name); 4031 4032 switch (rptid_entry->u.f1.flags & TOPO_MASK) { 4033 case TOPO_N2N: 4034 ha->current_topology = ISP_CFG_N; 4035 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); 4036 list_for_each_entry(fcport, &vha->vp_fcports, list) { 4037 fcport->scan_state = QLA_FCPORT_SCAN; 4038 fcport->n2n_flag = 0; 4039 } 4040 id.b24 = 0; 4041 if (wwn_to_u64(vha->port_name) > 4042 wwn_to_u64(rptid_entry->u.f1.port_name)) { 4043 vha->d_id.b24 = 0; 4044 vha->d_id.b.al_pa = 1; 4045 ha->flags.n2n_bigger = 1; 4046 4047 id.b.al_pa = 2; 4048 ql_dbg(ql_dbg_async, vha, 0x5075, 4049 "Format 1: assign local id %x remote id %x\n", 4050 vha->d_id.b24, id.b24); 4051 } else { 4052 ql_dbg(ql_dbg_async, vha, 0x5075, 4053 "Format 1: Remote login - Waiting for WWPN %8phC.\n", 4054 rptid_entry->u.f1.port_name); 4055 ha->flags.n2n_bigger = 0; 4056 } 4057 4058 fcport = qla2x00_find_fcport_by_wwpn(vha, 4059 rptid_entry->u.f1.port_name, 1); 4060 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 4061 4062 4063 if (fcport) { 4064 fcport->plogi_nack_done_deadline = jiffies + HZ; 4065 fcport->dm_login_expire = jiffies + 4066 QLA_N2N_WAIT_TIME * HZ; 4067 fcport->scan_state = QLA_FCPORT_FOUND; 4068 fcport->n2n_flag = 1; 4069 fcport->keep_nport_handle = 1; 4070 fcport->login_retry = vha->hw->login_retry_count; 4071 fcport->fc4_type = FS_FC4TYPE_FCP; 4072 if (vha->flags.nvme_enabled) 4073 fcport->fc4_type |= FS_FC4TYPE_NVME; 4074 4075 if (wwn_to_u64(vha->port_name) > 4076 wwn_to_u64(fcport->port_name)) { 4077 fcport->d_id = id; 4078 } 4079 4080 switch (fcport->disc_state) { 4081 case DSC_DELETED: 4082 set_bit(RELOGIN_NEEDED, 4083 &vha->dpc_flags); 4084 break; 4085 case DSC_DELETE_PEND: 4086 break; 4087 default: 4088 qlt_schedule_sess_for_deletion(fcport); 4089 break; 4090 } 4091 } else { 4092 qla24xx_post_newsess_work(vha, &id, 4093 rptid_entry->u.f1.port_name, 4094 rptid_entry->u.f1.node_name, 4095 NULL, 4096 FS_FCP_IS_N2N); 4097 } 4098 4099 /* if our portname is higher then initiate N2N login */ 4100 4101 set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); 4102 return; 4103 case TOPO_FL: 4104 ha->current_topology = ISP_CFG_FL; 4105 break; 4106 case TOPO_F: 4107 ha->current_topology = ISP_CFG_F; 4108 break; 4109 default: 4110 break; 4111 } 4112 4113 ha->flags.gpsc_supported = 1; 4114 ha->current_topology = ISP_CFG_F; 4115 /* buffer to buffer credit flag */ 4116 vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0; 4117 4118 if (rptid_entry->vp_idx == 0) { 4119 if (rptid_entry->vp_status == VP_STAT_COMPL) { 4120 /* FA-WWN is only for physical port */ 4121 if (qla_ini_mode_enabled(vha) && 4122 ha->flags.fawwpn_enabled && 4123 (rptid_entry->u.f1.flags & 4124 BIT_6)) { 4125 memcpy(vha->port_name, 4126 rptid_entry->u.f1.port_name, 4127 WWN_SIZE); 4128 } 4129 4130 qla_update_host_map(vha, id); 4131 } 4132 4133 set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); 4134 set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); 4135 } else { 4136 if (rptid_entry->vp_status != VP_STAT_COMPL && 4137 rptid_entry->vp_status != VP_STAT_ID_CHG) { 4138 ql_dbg(ql_dbg_mbx, vha, 0x10ba, 4139 "Could not acquire ID for VP[%d].\n", 4140 rptid_entry->vp_idx); 4141 return; 4142 } 4143 4144 found = 0; 4145 spin_lock_irqsave(&ha->vport_slock, flags); 4146 list_for_each_entry(vp, &ha->vp_list, list) { 4147 if (rptid_entry->vp_idx == vp->vp_idx) { 4148 found = 1; 4149 break; 4150 } 4151 } 4152 spin_unlock_irqrestore(&ha->vport_slock, flags); 4153 4154 if (!found) 4155 return; 4156 4157 qla_update_host_map(vp, id); 4158 4159 /* 4160 * Cannot configure here as we are still sitting on the 4161 * response queue. Handle it in dpc context. 4162 */ 4163 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags); 4164 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags); 4165 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags); 4166 } 4167 set_bit(VP_DPC_NEEDED, &vha->dpc_flags); 4168 qla2xxx_wake_dpc(vha); 4169 } else if (rptid_entry->format == 2) { 4170 ql_dbg(ql_dbg_async, vha, 0x505f, 4171 "RIDA: format 2/N2N Primary port id %02x%02x%02x.\n", 4172 rptid_entry->port_id[2], rptid_entry->port_id[1], 4173 rptid_entry->port_id[0]); 4174 4175 ql_dbg(ql_dbg_async, vha, 0x5075, 4176 "N2N: Remote WWPN %8phC.\n", 4177 rptid_entry->u.f2.port_name); 4178 4179 /* N2N. direct connect */ 4180 ha->current_topology = ISP_CFG_N; 4181 ha->flags.rida_fmt2 = 1; 4182 vha->d_id.b.domain = rptid_entry->port_id[2]; 4183 vha->d_id.b.area = rptid_entry->port_id[1]; 4184 vha->d_id.b.al_pa = rptid_entry->port_id[0]; 4185 4186 ha->flags.n2n_ae = 1; 4187 spin_lock_irqsave(&ha->vport_slock, flags); 4188 qla_update_vp_map(vha, SET_AL_PA); 4189 spin_unlock_irqrestore(&ha->vport_slock, flags); 4190 4191 list_for_each_entry(fcport, &vha->vp_fcports, list) { 4192 fcport->scan_state = QLA_FCPORT_SCAN; 4193 fcport->n2n_flag = 0; 4194 } 4195 4196 fcport = qla2x00_find_fcport_by_wwpn(vha, 4197 rptid_entry->u.f2.port_name, 1); 4198 4199 if (fcport) { 4200 fcport->login_retry = vha->hw->login_retry_count; 4201 fcport->plogi_nack_done_deadline = jiffies + HZ; 4202 fcport->scan_state = QLA_FCPORT_FOUND; 4203 fcport->keep_nport_handle = 1; 4204 fcport->n2n_flag = 1; 4205 fcport->d_id.b.domain = 4206 rptid_entry->u.f2.remote_nport_id[2]; 4207 fcport->d_id.b.area = 4208 rptid_entry->u.f2.remote_nport_id[1]; 4209 fcport->d_id.b.al_pa = 4210 rptid_entry->u.f2.remote_nport_id[0]; 4211 4212 /* 4213 * For the case where remote port sending PRLO, FW 4214 * sends up RIDA Format 2 as an indication of session 4215 * loss. In other word, FW state change from PRLI 4216 * complete back to PLOGI complete. Delete the 4217 * session and let relogin drive the reconnect. 4218 */ 4219 if (atomic_read(&fcport->state) == FCS_ONLINE) 4220 qlt_schedule_sess_for_deletion(fcport); 4221 } 4222 } 4223} 4224 4225/* 4226 * qla24xx_modify_vp_config 4227 * Change VP configuration for vha 4228 * 4229 * Input: 4230 * vha = adapter block pointer. 4231 * 4232 * Returns: 4233 * qla2xxx local function return status code. 4234 * 4235 * Context: 4236 * Kernel context. 4237 */ 4238int 4239qla24xx_modify_vp_config(scsi_qla_host_t *vha) 4240{ 4241 int rval; 4242 struct vp_config_entry_24xx *vpmod; 4243 dma_addr_t vpmod_dma; 4244 struct qla_hw_data *ha = vha->hw; 4245 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 4246 4247 /* This can be called by the parent */ 4248 4249 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb, 4250 "Entered %s.\n", __func__); 4251 4252 vpmod = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma); 4253 if (!vpmod) { 4254 ql_log(ql_log_warn, vha, 0x10bc, 4255 "Failed to allocate modify VP IOCB.\n"); 4256 return QLA_MEMORY_ALLOC_FAILED; 4257 } 4258 4259 vpmod->entry_type = VP_CONFIG_IOCB_TYPE; 4260 vpmod->entry_count = 1; 4261 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS; 4262 vpmod->vp_count = 1; 4263 vpmod->vp_index1 = vha->vp_idx; 4264 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5; 4265 4266 qlt_modify_vp_config(vha, vpmod); 4267 4268 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE); 4269 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE); 4270 vpmod->entry_count = 1; 4271 4272 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0); 4273 if (rval != QLA_SUCCESS) { 4274 ql_dbg(ql_dbg_mbx, vha, 0x10bd, 4275 "Failed to issue VP config IOCB (%x).\n", rval); 4276 } else if (vpmod->comp_status != 0) { 4277 ql_dbg(ql_dbg_mbx, vha, 0x10be, 4278 "Failed to complete IOCB -- error status (%x).\n", 4279 vpmod->comp_status); 4280 rval = QLA_FUNCTION_FAILED; 4281 } else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) { 4282 ql_dbg(ql_dbg_mbx, vha, 0x10bf, 4283 "Failed to complete IOCB -- completion status (%x).\n", 4284 le16_to_cpu(vpmod->comp_status)); 4285 rval = QLA_FUNCTION_FAILED; 4286 } else { 4287 /* EMPTY */ 4288 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0, 4289 "Done %s.\n", __func__); 4290 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING); 4291 } 4292 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma); 4293 4294 return rval; 4295} 4296 4297/* 4298 * qla2x00_send_change_request 4299 * Receive or disable RSCN request from fabric controller 4300 * 4301 * Input: 4302 * ha = adapter block pointer 4303 * format = registration format: 4304 * 0 - Reserved 4305 * 1 - Fabric detected registration 4306 * 2 - N_port detected registration 4307 * 3 - Full registration 4308 * FF - clear registration 4309 * vp_idx = Virtual port index 4310 * 4311 * Returns: 4312 * qla2x00 local function return status code. 4313 * 4314 * Context: 4315 * Kernel Context 4316 */ 4317 4318int 4319qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format, 4320 uint16_t vp_idx) 4321{ 4322 int rval; 4323 mbx_cmd_t mc; 4324 mbx_cmd_t *mcp = &mc; 4325 4326 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7, 4327 "Entered %s.\n", __func__); 4328 4329 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST; 4330 mcp->mb[1] = format; 4331 mcp->mb[9] = vp_idx; 4332 mcp->out_mb = MBX_9|MBX_1|MBX_0; 4333 mcp->in_mb = MBX_0|MBX_1; 4334 mcp->tov = MBX_TOV_SECONDS; 4335 mcp->flags = 0; 4336 rval = qla2x00_mailbox_command(vha, mcp); 4337 4338 if (rval == QLA_SUCCESS) { 4339 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { 4340 rval = BIT_1; 4341 } 4342 } else 4343 rval = BIT_1; 4344 4345 return rval; 4346} 4347 4348int 4349qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr, 4350 uint32_t size) 4351{ 4352 int rval; 4353 mbx_cmd_t mc; 4354 mbx_cmd_t *mcp = &mc; 4355 4356 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009, 4357 "Entered %s.\n", __func__); 4358 4359 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) { 4360 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED; 4361 mcp->mb[8] = MSW(addr); 4362 mcp->mb[10] = 0; 4363 mcp->out_mb = MBX_10|MBX_8|MBX_0; 4364 } else { 4365 mcp->mb[0] = MBC_DUMP_RISC_RAM; 4366 mcp->out_mb = MBX_0; 4367 } 4368 mcp->mb[1] = LSW(addr); 4369 mcp->mb[2] = MSW(req_dma); 4370 mcp->mb[3] = LSW(req_dma); 4371 mcp->mb[6] = MSW(MSD(req_dma)); 4372 mcp->mb[7] = LSW(MSD(req_dma)); 4373 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1; 4374 if (IS_FWI2_CAPABLE(vha->hw)) { 4375 mcp->mb[4] = MSW(size); 4376 mcp->mb[5] = LSW(size); 4377 mcp->out_mb |= MBX_5|MBX_4; 4378 } else { 4379 mcp->mb[4] = LSW(size); 4380 mcp->out_mb |= MBX_4; 4381 } 4382 4383 mcp->in_mb = MBX_0; 4384 mcp->tov = MBX_TOV_SECONDS; 4385 mcp->flags = 0; 4386 rval = qla2x00_mailbox_command(vha, mcp); 4387 4388 if (rval != QLA_SUCCESS) { 4389 ql_dbg(ql_dbg_mbx, vha, 0x1008, 4390 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4391 } else { 4392 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007, 4393 "Done %s.\n", __func__); 4394 } 4395 4396 return rval; 4397} 4398/* 84XX Support **************************************************************/ 4399 4400struct cs84xx_mgmt_cmd { 4401 union { 4402 struct verify_chip_entry_84xx req; 4403 struct verify_chip_rsp_84xx rsp; 4404 } p; 4405}; 4406 4407int 4408qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status) 4409{ 4410 int rval, retry; 4411 struct cs84xx_mgmt_cmd *mn; 4412 dma_addr_t mn_dma; 4413 uint16_t options; 4414 unsigned long flags; 4415 struct qla_hw_data *ha = vha->hw; 4416 4417 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8, 4418 "Entered %s.\n", __func__); 4419 4420 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); 4421 if (mn == NULL) { 4422 return QLA_MEMORY_ALLOC_FAILED; 4423 } 4424 4425 /* Force Update? */ 4426 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0; 4427 /* Diagnostic firmware? */ 4428 /* options |= MENLO_DIAG_FW; */ 4429 /* We update the firmware with only one data sequence. */ 4430 options |= VCO_END_OF_DATA; 4431 4432 do { 4433 retry = 0; 4434 memset(mn, 0, sizeof(*mn)); 4435 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE; 4436 mn->p.req.entry_count = 1; 4437 mn->p.req.options = cpu_to_le16(options); 4438 4439 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c, 4440 "Dump of Verify Request.\n"); 4441 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e, 4442 mn, sizeof(*mn)); 4443 4444 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120); 4445 if (rval != QLA_SUCCESS) { 4446 ql_dbg(ql_dbg_mbx, vha, 0x10cb, 4447 "Failed to issue verify IOCB (%x).\n", rval); 4448 goto verify_done; 4449 } 4450 4451 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110, 4452 "Dump of Verify Response.\n"); 4453 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118, 4454 mn, sizeof(*mn)); 4455 4456 status[0] = le16_to_cpu(mn->p.rsp.comp_status); 4457 status[1] = status[0] == CS_VCS_CHIP_FAILURE ? 4458 le16_to_cpu(mn->p.rsp.failure_code) : 0; 4459 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce, 4460 "cs=%x fc=%x.\n", status[0], status[1]); 4461 4462 if (status[0] != CS_COMPLETE) { 4463 rval = QLA_FUNCTION_FAILED; 4464 if (!(options & VCO_DONT_UPDATE_FW)) { 4465 ql_dbg(ql_dbg_mbx, vha, 0x10cf, 4466 "Firmware update failed. Retrying " 4467 "without update firmware.\n"); 4468 options |= VCO_DONT_UPDATE_FW; 4469 options &= ~VCO_FORCE_UPDATE; 4470 retry = 1; 4471 } 4472 } else { 4473 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0, 4474 "Firmware updated to %x.\n", 4475 le32_to_cpu(mn->p.rsp.fw_ver)); 4476 4477 /* NOTE: we only update OP firmware. */ 4478 spin_lock_irqsave(&ha->cs84xx->access_lock, flags); 4479 ha->cs84xx->op_fw_version = 4480 le32_to_cpu(mn->p.rsp.fw_ver); 4481 spin_unlock_irqrestore(&ha->cs84xx->access_lock, 4482 flags); 4483 } 4484 } while (retry); 4485 4486verify_done: 4487 dma_pool_free(ha->s_dma_pool, mn, mn_dma); 4488 4489 if (rval != QLA_SUCCESS) { 4490 ql_dbg(ql_dbg_mbx, vha, 0x10d1, 4491 "Failed=%x.\n", rval); 4492 } else { 4493 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2, 4494 "Done %s.\n", __func__); 4495 } 4496 4497 return rval; 4498} 4499 4500int 4501qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) 4502{ 4503 int rval; 4504 unsigned long flags; 4505 mbx_cmd_t mc; 4506 mbx_cmd_t *mcp = &mc; 4507 struct qla_hw_data *ha = vha->hw; 4508 4509 if (!ha->flags.fw_started) 4510 return QLA_SUCCESS; 4511 4512 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3, 4513 "Entered %s.\n", __func__); 4514 4515 if (IS_SHADOW_REG_CAPABLE(ha)) 4516 req->options |= BIT_13; 4517 4518 mcp->mb[0] = MBC_INITIALIZE_MULTIQ; 4519 mcp->mb[1] = req->options; 4520 mcp->mb[2] = MSW(LSD(req->dma)); 4521 mcp->mb[3] = LSW(LSD(req->dma)); 4522 mcp->mb[6] = MSW(MSD(req->dma)); 4523 mcp->mb[7] = LSW(MSD(req->dma)); 4524 mcp->mb[5] = req->length; 4525 if (req->rsp) 4526 mcp->mb[10] = req->rsp->id; 4527 mcp->mb[12] = req->qos; 4528 mcp->mb[11] = req->vp_idx; 4529 mcp->mb[13] = req->rid; 4530 if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 4531 mcp->mb[15] = 0; 4532 4533 mcp->mb[4] = req->id; 4534 /* que in ptr index */ 4535 mcp->mb[8] = 0; 4536 /* que out ptr index */ 4537 mcp->mb[9] = *req->out_ptr = 0; 4538 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7| 4539 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4540 mcp->in_mb = MBX_0; 4541 mcp->flags = MBX_DMA_OUT; 4542 mcp->tov = MBX_TOV_SECONDS * 2; 4543 4544 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || 4545 IS_QLA28XX(ha)) 4546 mcp->in_mb |= MBX_1; 4547 if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 4548 mcp->out_mb |= MBX_15; 4549 /* debug q create issue in SR-IOV */ 4550 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; 4551 } 4552 4553 spin_lock_irqsave(&ha->hardware_lock, flags); 4554 if (!(req->options & BIT_0)) { 4555 wrt_reg_dword(req->req_q_in, 0); 4556 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 4557 wrt_reg_dword(req->req_q_out, 0); 4558 } 4559 spin_unlock_irqrestore(&ha->hardware_lock, flags); 4560 4561 rval = qla2x00_mailbox_command(vha, mcp); 4562 if (rval != QLA_SUCCESS) { 4563 ql_dbg(ql_dbg_mbx, vha, 0x10d4, 4564 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4565 } else { 4566 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5, 4567 "Done %s.\n", __func__); 4568 } 4569 4570 return rval; 4571} 4572 4573int 4574qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) 4575{ 4576 int rval; 4577 unsigned long flags; 4578 mbx_cmd_t mc; 4579 mbx_cmd_t *mcp = &mc; 4580 struct qla_hw_data *ha = vha->hw; 4581 4582 if (!ha->flags.fw_started) 4583 return QLA_SUCCESS; 4584 4585 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6, 4586 "Entered %s.\n", __func__); 4587 4588 if (IS_SHADOW_REG_CAPABLE(ha)) 4589 rsp->options |= BIT_13; 4590 4591 mcp->mb[0] = MBC_INITIALIZE_MULTIQ; 4592 mcp->mb[1] = rsp->options; 4593 mcp->mb[2] = MSW(LSD(rsp->dma)); 4594 mcp->mb[3] = LSW(LSD(rsp->dma)); 4595 mcp->mb[6] = MSW(MSD(rsp->dma)); 4596 mcp->mb[7] = LSW(MSD(rsp->dma)); 4597 mcp->mb[5] = rsp->length; 4598 mcp->mb[14] = rsp->msix->entry; 4599 mcp->mb[13] = rsp->rid; 4600 if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 4601 mcp->mb[15] = 0; 4602 4603 mcp->mb[4] = rsp->id; 4604 /* que in ptr index */ 4605 mcp->mb[8] = *rsp->in_ptr = 0; 4606 /* que out ptr index */ 4607 mcp->mb[9] = 0; 4608 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7 4609 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4610 mcp->in_mb = MBX_0; 4611 mcp->flags = MBX_DMA_OUT; 4612 mcp->tov = MBX_TOV_SECONDS * 2; 4613 4614 if (IS_QLA81XX(ha)) { 4615 mcp->out_mb |= MBX_12|MBX_11|MBX_10; 4616 mcp->in_mb |= MBX_1; 4617 } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 4618 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10; 4619 mcp->in_mb |= MBX_1; 4620 /* debug q create issue in SR-IOV */ 4621 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; 4622 } 4623 4624 spin_lock_irqsave(&ha->hardware_lock, flags); 4625 if (!(rsp->options & BIT_0)) { 4626 wrt_reg_dword(rsp->rsp_q_out, 0); 4627 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 4628 wrt_reg_dword(rsp->rsp_q_in, 0); 4629 } 4630 4631 spin_unlock_irqrestore(&ha->hardware_lock, flags); 4632 4633 rval = qla2x00_mailbox_command(vha, mcp); 4634 if (rval != QLA_SUCCESS) { 4635 ql_dbg(ql_dbg_mbx, vha, 0x10d7, 4636 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4637 } else { 4638 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8, 4639 "Done %s.\n", __func__); 4640 } 4641 4642 return rval; 4643} 4644 4645int 4646qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb) 4647{ 4648 int rval; 4649 mbx_cmd_t mc; 4650 mbx_cmd_t *mcp = &mc; 4651 4652 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9, 4653 "Entered %s.\n", __func__); 4654 4655 mcp->mb[0] = MBC_IDC_ACK; 4656 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); 4657 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4658 mcp->in_mb = MBX_0; 4659 mcp->tov = MBX_TOV_SECONDS; 4660 mcp->flags = 0; 4661 rval = qla2x00_mailbox_command(vha, mcp); 4662 4663 if (rval != QLA_SUCCESS) { 4664 ql_dbg(ql_dbg_mbx, vha, 0x10da, 4665 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4666 } else { 4667 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db, 4668 "Done %s.\n", __func__); 4669 } 4670 4671 return rval; 4672} 4673 4674int 4675qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size) 4676{ 4677 int rval; 4678 mbx_cmd_t mc; 4679 mbx_cmd_t *mcp = &mc; 4680 4681 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc, 4682 "Entered %s.\n", __func__); 4683 4684 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && 4685 !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 4686 return QLA_FUNCTION_FAILED; 4687 4688 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 4689 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE; 4690 mcp->out_mb = MBX_1|MBX_0; 4691 mcp->in_mb = MBX_1|MBX_0; 4692 mcp->tov = MBX_TOV_SECONDS; 4693 mcp->flags = 0; 4694 rval = qla2x00_mailbox_command(vha, mcp); 4695 4696 if (rval != QLA_SUCCESS) { 4697 ql_dbg(ql_dbg_mbx, vha, 0x10dd, 4698 "Failed=%x mb[0]=%x mb[1]=%x.\n", 4699 rval, mcp->mb[0], mcp->mb[1]); 4700 } else { 4701 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de, 4702 "Done %s.\n", __func__); 4703 *sector_size = mcp->mb[1]; 4704 } 4705 4706 return rval; 4707} 4708 4709int 4710qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable) 4711{ 4712 int rval; 4713 mbx_cmd_t mc; 4714 mbx_cmd_t *mcp = &mc; 4715 4716 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && 4717 !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 4718 return QLA_FUNCTION_FAILED; 4719 4720 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df, 4721 "Entered %s.\n", __func__); 4722 4723 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 4724 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE : 4725 FAC_OPT_CMD_WRITE_PROTECT; 4726 mcp->out_mb = MBX_1|MBX_0; 4727 mcp->in_mb = MBX_1|MBX_0; 4728 mcp->tov = MBX_TOV_SECONDS; 4729 mcp->flags = 0; 4730 rval = qla2x00_mailbox_command(vha, mcp); 4731 4732 if (rval != QLA_SUCCESS) { 4733 ql_dbg(ql_dbg_mbx, vha, 0x10e0, 4734 "Failed=%x mb[0]=%x mb[1]=%x.\n", 4735 rval, mcp->mb[0], mcp->mb[1]); 4736 } else { 4737 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1, 4738 "Done %s.\n", __func__); 4739 } 4740 4741 return rval; 4742} 4743 4744int 4745qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish) 4746{ 4747 int rval; 4748 mbx_cmd_t mc; 4749 mbx_cmd_t *mcp = &mc; 4750 4751 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && 4752 !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) 4753 return QLA_FUNCTION_FAILED; 4754 4755 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, 4756 "Entered %s.\n", __func__); 4757 4758 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 4759 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR; 4760 mcp->mb[2] = LSW(start); 4761 mcp->mb[3] = MSW(start); 4762 mcp->mb[4] = LSW(finish); 4763 mcp->mb[5] = MSW(finish); 4764 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4765 mcp->in_mb = MBX_2|MBX_1|MBX_0; 4766 mcp->tov = MBX_TOV_SECONDS; 4767 mcp->flags = 0; 4768 rval = qla2x00_mailbox_command(vha, mcp); 4769 4770 if (rval != QLA_SUCCESS) { 4771 ql_dbg(ql_dbg_mbx, vha, 0x10e3, 4772 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 4773 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 4774 } else { 4775 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4, 4776 "Done %s.\n", __func__); 4777 } 4778 4779 return rval; 4780} 4781 4782int 4783qla81xx_fac_semaphore_access(scsi_qla_host_t *vha, int lock) 4784{ 4785 int rval = QLA_SUCCESS; 4786 mbx_cmd_t mc; 4787 mbx_cmd_t *mcp = &mc; 4788 struct qla_hw_data *ha = vha->hw; 4789 4790 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && 4791 !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 4792 return rval; 4793 4794 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, 4795 "Entered %s.\n", __func__); 4796 4797 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 4798 mcp->mb[1] = (lock ? FAC_OPT_CMD_LOCK_SEMAPHORE : 4799 FAC_OPT_CMD_UNLOCK_SEMAPHORE); 4800 mcp->out_mb = MBX_1|MBX_0; 4801 mcp->in_mb = MBX_1|MBX_0; 4802 mcp->tov = MBX_TOV_SECONDS; 4803 mcp->flags = 0; 4804 rval = qla2x00_mailbox_command(vha, mcp); 4805 4806 if (rval != QLA_SUCCESS) { 4807 ql_dbg(ql_dbg_mbx, vha, 0x10e3, 4808 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 4809 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 4810 } else { 4811 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4, 4812 "Done %s.\n", __func__); 4813 } 4814 4815 return rval; 4816} 4817 4818int 4819qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) 4820{ 4821 int rval = 0; 4822 mbx_cmd_t mc; 4823 mbx_cmd_t *mcp = &mc; 4824 4825 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5, 4826 "Entered %s.\n", __func__); 4827 4828 mcp->mb[0] = MBC_RESTART_MPI_FW; 4829 mcp->out_mb = MBX_0; 4830 mcp->in_mb = MBX_0|MBX_1; 4831 mcp->tov = MBX_TOV_SECONDS; 4832 mcp->flags = 0; 4833 rval = qla2x00_mailbox_command(vha, mcp); 4834 4835 if (rval != QLA_SUCCESS) { 4836 ql_dbg(ql_dbg_mbx, vha, 0x10e6, 4837 "Failed=%x mb[0]=%x mb[1]=%x.\n", 4838 rval, mcp->mb[0], mcp->mb[1]); 4839 } else { 4840 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7, 4841 "Done %s.\n", __func__); 4842 } 4843 4844 return rval; 4845} 4846 4847int 4848qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version) 4849{ 4850 int rval; 4851 mbx_cmd_t mc; 4852 mbx_cmd_t *mcp = &mc; 4853 int i; 4854 int len; 4855 __le16 *str; 4856 struct qla_hw_data *ha = vha->hw; 4857 4858 if (!IS_P3P_TYPE(ha)) 4859 return QLA_FUNCTION_FAILED; 4860 4861 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b, 4862 "Entered %s.\n", __func__); 4863 4864 str = (__force __le16 *)version; 4865 len = strlen(version); 4866 4867 mcp->mb[0] = MBC_SET_RNID_PARAMS; 4868 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8; 4869 mcp->out_mb = MBX_1|MBX_0; 4870 for (i = 4; i < 16 && len; i++, str++, len -= 2) { 4871 mcp->mb[i] = le16_to_cpup(str); 4872 mcp->out_mb |= 1<<i; 4873 } 4874 for (; i < 16; i++) { 4875 mcp->mb[i] = 0; 4876 mcp->out_mb |= 1<<i; 4877 } 4878 mcp->in_mb = MBX_1|MBX_0; 4879 mcp->tov = MBX_TOV_SECONDS; 4880 mcp->flags = 0; 4881 rval = qla2x00_mailbox_command(vha, mcp); 4882 4883 if (rval != QLA_SUCCESS) { 4884 ql_dbg(ql_dbg_mbx, vha, 0x117c, 4885 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); 4886 } else { 4887 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d, 4888 "Done %s.\n", __func__); 4889 } 4890 4891 return rval; 4892} 4893 4894int 4895qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version) 4896{ 4897 int rval; 4898 mbx_cmd_t mc; 4899 mbx_cmd_t *mcp = &mc; 4900 int len; 4901 uint16_t dwlen; 4902 uint8_t *str; 4903 dma_addr_t str_dma; 4904 struct qla_hw_data *ha = vha->hw; 4905 4906 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) || 4907 IS_P3P_TYPE(ha)) 4908 return QLA_FUNCTION_FAILED; 4909 4910 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e, 4911 "Entered %s.\n", __func__); 4912 4913 str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma); 4914 if (!str) { 4915 ql_log(ql_log_warn, vha, 0x117f, 4916 "Failed to allocate driver version param.\n"); 4917 return QLA_MEMORY_ALLOC_FAILED; 4918 } 4919 4920 memcpy(str, "\x7\x3\x11\x0", 4); 4921 dwlen = str[0]; 4922 len = dwlen * 4 - 4; 4923 memset(str + 4, 0, len); 4924 if (len > strlen(version)) 4925 len = strlen(version); 4926 memcpy(str + 4, version, len); 4927 4928 mcp->mb[0] = MBC_SET_RNID_PARAMS; 4929 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen; 4930 mcp->mb[2] = MSW(LSD(str_dma)); 4931 mcp->mb[3] = LSW(LSD(str_dma)); 4932 mcp->mb[6] = MSW(MSD(str_dma)); 4933 mcp->mb[7] = LSW(MSD(str_dma)); 4934 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 4935 mcp->in_mb = MBX_1|MBX_0; 4936 mcp->tov = MBX_TOV_SECONDS; 4937 mcp->flags = 0; 4938 rval = qla2x00_mailbox_command(vha, mcp); 4939 4940 if (rval != QLA_SUCCESS) { 4941 ql_dbg(ql_dbg_mbx, vha, 0x1180, 4942 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); 4943 } else { 4944 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181, 4945 "Done %s.\n", __func__); 4946 } 4947 4948 dma_pool_free(ha->s_dma_pool, str, str_dma); 4949 4950 return rval; 4951} 4952 4953int 4954qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma, 4955 void *buf, uint16_t bufsiz) 4956{ 4957 int rval, i; 4958 mbx_cmd_t mc; 4959 mbx_cmd_t *mcp = &mc; 4960 uint32_t *bp; 4961 4962 if (!IS_FWI2_CAPABLE(vha->hw)) 4963 return QLA_FUNCTION_FAILED; 4964 4965 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159, 4966 "Entered %s.\n", __func__); 4967 4968 mcp->mb[0] = MBC_GET_RNID_PARAMS; 4969 mcp->mb[1] = RNID_TYPE_PORT_LOGIN << 8; 4970 mcp->mb[2] = MSW(buf_dma); 4971 mcp->mb[3] = LSW(buf_dma); 4972 mcp->mb[6] = MSW(MSD(buf_dma)); 4973 mcp->mb[7] = LSW(MSD(buf_dma)); 4974 mcp->mb[8] = bufsiz/4; 4975 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 4976 mcp->in_mb = MBX_1|MBX_0; 4977 mcp->tov = MBX_TOV_SECONDS; 4978 mcp->flags = 0; 4979 rval = qla2x00_mailbox_command(vha, mcp); 4980 4981 if (rval != QLA_SUCCESS) { 4982 ql_dbg(ql_dbg_mbx, vha, 0x115a, 4983 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); 4984 } else { 4985 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b, 4986 "Done %s.\n", __func__); 4987 bp = (uint32_t *) buf; 4988 for (i = 0; i < (bufsiz-4)/4; i++, bp++) 4989 *bp = le32_to_cpu((__force __le32)*bp); 4990 } 4991 4992 return rval; 4993} 4994 4995#define PUREX_CMD_COUNT 4 4996int 4997qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha) 4998{ 4999 int rval; 5000 mbx_cmd_t mc; 5001 mbx_cmd_t *mcp = &mc; 5002 uint8_t *els_cmd_map; 5003 uint8_t active_cnt = 0; 5004 dma_addr_t els_cmd_map_dma; 5005 uint8_t cmd_opcode[PUREX_CMD_COUNT]; 5006 uint8_t i, index, purex_bit; 5007 struct qla_hw_data *ha = vha->hw; 5008 5009 if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) && 5010 !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 5011 return QLA_SUCCESS; 5012 5013 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197, 5014 "Entered %s.\n", __func__); 5015 5016 els_cmd_map = dma_alloc_coherent(&ha->pdev->dev, ELS_CMD_MAP_SIZE, 5017 &els_cmd_map_dma, GFP_KERNEL); 5018 if (!els_cmd_map) { 5019 ql_log(ql_log_warn, vha, 0x7101, 5020 "Failed to allocate RDP els command param.\n"); 5021 return QLA_MEMORY_ALLOC_FAILED; 5022 } 5023 5024 /* List of Purex ELS */ 5025 if (ql2xrdpenable) { 5026 cmd_opcode[active_cnt] = ELS_RDP; 5027 active_cnt++; 5028 } 5029 if (ha->flags.scm_supported_f) { 5030 cmd_opcode[active_cnt] = ELS_FPIN; 5031 active_cnt++; 5032 } 5033 if (ha->flags.edif_enabled) { 5034 cmd_opcode[active_cnt] = ELS_AUTH_ELS; 5035 active_cnt++; 5036 } 5037 5038 for (i = 0; i < active_cnt; i++) { 5039 index = cmd_opcode[i] / 8; 5040 purex_bit = cmd_opcode[i] % 8; 5041 els_cmd_map[index] |= 1 << purex_bit; 5042 } 5043 5044 mcp->mb[0] = MBC_SET_RNID_PARAMS; 5045 mcp->mb[1] = RNID_TYPE_ELS_CMD << 8; 5046 mcp->mb[2] = MSW(LSD(els_cmd_map_dma)); 5047 mcp->mb[3] = LSW(LSD(els_cmd_map_dma)); 5048 mcp->mb[6] = MSW(MSD(els_cmd_map_dma)); 5049 mcp->mb[7] = LSW(MSD(els_cmd_map_dma)); 5050 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 5051 mcp->in_mb = MBX_1|MBX_0; 5052 mcp->tov = MBX_TOV_SECONDS; 5053 mcp->flags = MBX_DMA_OUT; 5054 mcp->buf_size = ELS_CMD_MAP_SIZE; 5055 rval = qla2x00_mailbox_command(vha, mcp); 5056 5057 if (rval != QLA_SUCCESS) { 5058 ql_dbg(ql_dbg_mbx, vha, 0x118d, 5059 "Failed=%x (%x,%x).\n", rval, mcp->mb[0], mcp->mb[1]); 5060 } else { 5061 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c, 5062 "Done %s.\n", __func__); 5063 } 5064 5065 dma_free_coherent(&ha->pdev->dev, ELS_CMD_MAP_SIZE, 5066 els_cmd_map, els_cmd_map_dma); 5067 5068 return rval; 5069} 5070 5071static int 5072qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp) 5073{ 5074 int rval; 5075 mbx_cmd_t mc; 5076 mbx_cmd_t *mcp = &mc; 5077 5078 if (!IS_FWI2_CAPABLE(vha->hw)) 5079 return QLA_FUNCTION_FAILED; 5080 5081 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159, 5082 "Entered %s.\n", __func__); 5083 5084 mcp->mb[0] = MBC_GET_RNID_PARAMS; 5085 mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8; 5086 mcp->out_mb = MBX_1|MBX_0; 5087 mcp->in_mb = MBX_1|MBX_0; 5088 mcp->tov = MBX_TOV_SECONDS; 5089 mcp->flags = 0; 5090 rval = qla2x00_mailbox_command(vha, mcp); 5091 *temp = mcp->mb[1]; 5092 5093 if (rval != QLA_SUCCESS) { 5094 ql_dbg(ql_dbg_mbx, vha, 0x115a, 5095 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); 5096 } else { 5097 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b, 5098 "Done %s.\n", __func__); 5099 } 5100 5101 return rval; 5102} 5103 5104int 5105qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, 5106 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt) 5107{ 5108 int rval; 5109 mbx_cmd_t mc; 5110 mbx_cmd_t *mcp = &mc; 5111 struct qla_hw_data *ha = vha->hw; 5112 5113 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, 5114 "Entered %s.\n", __func__); 5115 5116 if (!IS_FWI2_CAPABLE(ha)) 5117 return QLA_FUNCTION_FAILED; 5118 5119 if (len == 1) 5120 opt |= BIT_0; 5121 5122 mcp->mb[0] = MBC_READ_SFP; 5123 mcp->mb[1] = dev; 5124 mcp->mb[2] = MSW(LSD(sfp_dma)); 5125 mcp->mb[3] = LSW(LSD(sfp_dma)); 5126 mcp->mb[6] = MSW(MSD(sfp_dma)); 5127 mcp->mb[7] = LSW(MSD(sfp_dma)); 5128 mcp->mb[8] = len; 5129 mcp->mb[9] = off; 5130 mcp->mb[10] = opt; 5131 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 5132 mcp->in_mb = MBX_1|MBX_0; 5133 mcp->tov = MBX_TOV_SECONDS; 5134 mcp->flags = 0; 5135 rval = qla2x00_mailbox_command(vha, mcp); 5136 5137 if (opt & BIT_0) 5138 *sfp = mcp->mb[1]; 5139 5140 if (rval != QLA_SUCCESS) { 5141 ql_dbg(ql_dbg_mbx, vha, 0x10e9, 5142 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 5143 if (mcp->mb[0] == MBS_COMMAND_ERROR && mcp->mb[1] == 0x22) { 5144 /* sfp is not there */ 5145 rval = QLA_INTERFACE_ERROR; 5146 } 5147 } else { 5148 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, 5149 "Done %s.\n", __func__); 5150 } 5151 5152 return rval; 5153} 5154 5155int 5156qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, 5157 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt) 5158{ 5159 int rval; 5160 mbx_cmd_t mc; 5161 mbx_cmd_t *mcp = &mc; 5162 struct qla_hw_data *ha = vha->hw; 5163 5164 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb, 5165 "Entered %s.\n", __func__); 5166 5167 if (!IS_FWI2_CAPABLE(ha)) 5168 return QLA_FUNCTION_FAILED; 5169 5170 if (len == 1) 5171 opt |= BIT_0; 5172 5173 if (opt & BIT_0) 5174 len = *sfp; 5175 5176 mcp->mb[0] = MBC_WRITE_SFP; 5177 mcp->mb[1] = dev; 5178 mcp->mb[2] = MSW(LSD(sfp_dma)); 5179 mcp->mb[3] = LSW(LSD(sfp_dma)); 5180 mcp->mb[6] = MSW(MSD(sfp_dma)); 5181 mcp->mb[7] = LSW(MSD(sfp_dma)); 5182 mcp->mb[8] = len; 5183 mcp->mb[9] = off; 5184 mcp->mb[10] = opt; 5185 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 5186 mcp->in_mb = MBX_1|MBX_0; 5187 mcp->tov = MBX_TOV_SECONDS; 5188 mcp->flags = 0; 5189 rval = qla2x00_mailbox_command(vha, mcp); 5190 5191 if (rval != QLA_SUCCESS) { 5192 ql_dbg(ql_dbg_mbx, vha, 0x10ec, 5193 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 5194 } else { 5195 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed, 5196 "Done %s.\n", __func__); 5197 } 5198 5199 return rval; 5200} 5201 5202int 5203qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma, 5204 uint16_t size_in_bytes, uint16_t *actual_size) 5205{ 5206 int rval; 5207 mbx_cmd_t mc; 5208 mbx_cmd_t *mcp = &mc; 5209 5210 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee, 5211 "Entered %s.\n", __func__); 5212 5213 if (!IS_CNA_CAPABLE(vha->hw)) 5214 return QLA_FUNCTION_FAILED; 5215 5216 mcp->mb[0] = MBC_GET_XGMAC_STATS; 5217 mcp->mb[2] = MSW(stats_dma); 5218 mcp->mb[3] = LSW(stats_dma); 5219 mcp->mb[6] = MSW(MSD(stats_dma)); 5220 mcp->mb[7] = LSW(MSD(stats_dma)); 5221 mcp->mb[8] = size_in_bytes >> 2; 5222 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 5223 mcp->in_mb = MBX_2|MBX_1|MBX_0; 5224 mcp->tov = MBX_TOV_SECONDS; 5225 mcp->flags = 0; 5226 rval = qla2x00_mailbox_command(vha, mcp); 5227 5228 if (rval != QLA_SUCCESS) { 5229 ql_dbg(ql_dbg_mbx, vha, 0x10ef, 5230 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 5231 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 5232 } else { 5233 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0, 5234 "Done %s.\n", __func__); 5235 5236 5237 *actual_size = mcp->mb[2] << 2; 5238 } 5239 5240 return rval; 5241} 5242 5243int 5244qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma, 5245 uint16_t size) 5246{ 5247 int rval; 5248 mbx_cmd_t mc; 5249 mbx_cmd_t *mcp = &mc; 5250 5251 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1, 5252 "Entered %s.\n", __func__); 5253 5254 if (!IS_CNA_CAPABLE(vha->hw)) 5255 return QLA_FUNCTION_FAILED; 5256 5257 mcp->mb[0] = MBC_GET_DCBX_PARAMS; 5258 mcp->mb[1] = 0; 5259 mcp->mb[2] = MSW(tlv_dma); 5260 mcp->mb[3] = LSW(tlv_dma); 5261 mcp->mb[6] = MSW(MSD(tlv_dma)); 5262 mcp->mb[7] = LSW(MSD(tlv_dma)); 5263 mcp->mb[8] = size; 5264 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 5265 mcp->in_mb = MBX_2|MBX_1|MBX_0; 5266 mcp->tov = MBX_TOV_SECONDS; 5267 mcp->flags = 0; 5268 rval = qla2x00_mailbox_command(vha, mcp); 5269 5270 if (rval != QLA_SUCCESS) { 5271 ql_dbg(ql_dbg_mbx, vha, 0x10f2, 5272 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 5273 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 5274 } else { 5275 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3, 5276 "Done %s.\n", __func__); 5277 } 5278 5279 return rval; 5280} 5281 5282int 5283qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data) 5284{ 5285 int rval; 5286 mbx_cmd_t mc; 5287 mbx_cmd_t *mcp = &mc; 5288 5289 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4, 5290 "Entered %s.\n", __func__); 5291 5292 if (!IS_FWI2_CAPABLE(vha->hw)) 5293 return QLA_FUNCTION_FAILED; 5294 5295 mcp->mb[0] = MBC_READ_RAM_EXTENDED; 5296 mcp->mb[1] = LSW(risc_addr); 5297 mcp->mb[8] = MSW(risc_addr); 5298 mcp->out_mb = MBX_8|MBX_1|MBX_0; 5299 mcp->in_mb = MBX_3|MBX_2|MBX_0; 5300 mcp->tov = MBX_TOV_SECONDS; 5301 mcp->flags = 0; 5302 rval = qla2x00_mailbox_command(vha, mcp); 5303 if (rval != QLA_SUCCESS) { 5304 ql_dbg(ql_dbg_mbx, vha, 0x10f5, 5305 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 5306 } else { 5307 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6, 5308 "Done %s.\n", __func__); 5309 *data = mcp->mb[3] << 16 | mcp->mb[2]; 5310 } 5311 5312 return rval; 5313} 5314 5315int 5316qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, 5317 uint16_t *mresp) 5318{ 5319 int rval; 5320 mbx_cmd_t mc; 5321 mbx_cmd_t *mcp = &mc; 5322 5323 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7, 5324 "Entered %s.\n", __func__); 5325 5326 memset(mcp->mb, 0 , sizeof(mcp->mb)); 5327 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; 5328 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing 5329 5330 /* transfer count */ 5331 mcp->mb[10] = LSW(mreq->transfer_size); 5332 mcp->mb[11] = MSW(mreq->transfer_size); 5333 5334 /* send data address */ 5335 mcp->mb[14] = LSW(mreq->send_dma); 5336 mcp->mb[15] = MSW(mreq->send_dma); 5337 mcp->mb[20] = LSW(MSD(mreq->send_dma)); 5338 mcp->mb[21] = MSW(MSD(mreq->send_dma)); 5339 5340 /* receive data address */ 5341 mcp->mb[16] = LSW(mreq->rcv_dma); 5342 mcp->mb[17] = MSW(mreq->rcv_dma); 5343 mcp->mb[6] = LSW(MSD(mreq->rcv_dma)); 5344 mcp->mb[7] = MSW(MSD(mreq->rcv_dma)); 5345 5346 /* Iteration count */ 5347 mcp->mb[18] = LSW(mreq->iteration_count); 5348 mcp->mb[19] = MSW(mreq->iteration_count); 5349 5350 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| 5351 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; 5352 if (IS_CNA_CAPABLE(vha->hw)) 5353 mcp->out_mb |= MBX_2; 5354 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; 5355 5356 mcp->buf_size = mreq->transfer_size; 5357 mcp->tov = MBX_TOV_SECONDS; 5358 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 5359 5360 rval = qla2x00_mailbox_command(vha, mcp); 5361 5362 if (rval != QLA_SUCCESS) { 5363 ql_dbg(ql_dbg_mbx, vha, 0x10f8, 5364 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x " 5365 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], 5366 mcp->mb[3], mcp->mb[18], mcp->mb[19]); 5367 } else { 5368 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9, 5369 "Done %s.\n", __func__); 5370 } 5371 5372 /* Copy mailbox information */ 5373 memcpy( mresp, mcp->mb, 64); 5374 return rval; 5375} 5376 5377int 5378qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, 5379 uint16_t *mresp) 5380{ 5381 int rval; 5382 mbx_cmd_t mc; 5383 mbx_cmd_t *mcp = &mc; 5384 struct qla_hw_data *ha = vha->hw; 5385 5386 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa, 5387 "Entered %s.\n", __func__); 5388 5389 memset(mcp->mb, 0 , sizeof(mcp->mb)); 5390 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO; 5391 /* BIT_6 specifies 64bit address */ 5392 mcp->mb[1] = mreq->options | BIT_15 | BIT_6; 5393 if (IS_CNA_CAPABLE(ha)) { 5394 mcp->mb[2] = vha->fcoe_fcf_idx; 5395 } 5396 mcp->mb[16] = LSW(mreq->rcv_dma); 5397 mcp->mb[17] = MSW(mreq->rcv_dma); 5398 mcp->mb[6] = LSW(MSD(mreq->rcv_dma)); 5399 mcp->mb[7] = MSW(MSD(mreq->rcv_dma)); 5400 5401 mcp->mb[10] = LSW(mreq->transfer_size); 5402 5403 mcp->mb[14] = LSW(mreq->send_dma); 5404 mcp->mb[15] = MSW(mreq->send_dma); 5405 mcp->mb[20] = LSW(MSD(mreq->send_dma)); 5406 mcp->mb[21] = MSW(MSD(mreq->send_dma)); 5407 5408 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15| 5409 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; 5410 if (IS_CNA_CAPABLE(ha)) 5411 mcp->out_mb |= MBX_2; 5412 5413 mcp->in_mb = MBX_0; 5414 if (IS_CNA_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || 5415 IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 5416 mcp->in_mb |= MBX_1; 5417 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || 5418 IS_QLA28XX(ha)) 5419 mcp->in_mb |= MBX_3; 5420 5421 mcp->tov = MBX_TOV_SECONDS; 5422 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 5423 mcp->buf_size = mreq->transfer_size; 5424 5425 rval = qla2x00_mailbox_command(vha, mcp); 5426 5427 if (rval != QLA_SUCCESS) { 5428 ql_dbg(ql_dbg_mbx, vha, 0x10fb, 5429 "Failed=%x mb[0]=%x mb[1]=%x.\n", 5430 rval, mcp->mb[0], mcp->mb[1]); 5431 } else { 5432 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc, 5433 "Done %s.\n", __func__); 5434 } 5435 5436 /* Copy mailbox information */ 5437 memcpy(mresp, mcp->mb, 64); 5438 return rval; 5439} 5440 5441int 5442qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic) 5443{ 5444 int rval; 5445 mbx_cmd_t mc; 5446 mbx_cmd_t *mcp = &mc; 5447 5448 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd, 5449 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic); 5450 5451 mcp->mb[0] = MBC_ISP84XX_RESET; 5452 mcp->mb[1] = enable_diagnostic; 5453 mcp->out_mb = MBX_1|MBX_0; 5454 mcp->in_mb = MBX_1|MBX_0; 5455 mcp->tov = MBX_TOV_SECONDS; 5456 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 5457 rval = qla2x00_mailbox_command(vha, mcp); 5458 5459 if (rval != QLA_SUCCESS) 5460 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval); 5461 else 5462 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff, 5463 "Done %s.\n", __func__); 5464 5465 return rval; 5466} 5467 5468int 5469qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) 5470{ 5471 int rval; 5472 mbx_cmd_t mc; 5473 mbx_cmd_t *mcp = &mc; 5474 5475 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100, 5476 "Entered %s.\n", __func__); 5477 5478 if (!IS_FWI2_CAPABLE(vha->hw)) 5479 return QLA_FUNCTION_FAILED; 5480 5481 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED; 5482 mcp->mb[1] = LSW(risc_addr); 5483 mcp->mb[2] = LSW(data); 5484 mcp->mb[3] = MSW(data); 5485 mcp->mb[8] = MSW(risc_addr); 5486 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0; 5487 mcp->in_mb = MBX_1|MBX_0; 5488 mcp->tov = MBX_TOV_SECONDS; 5489 mcp->flags = 0; 5490 rval = qla2x00_mailbox_command(vha, mcp); 5491 if (rval != QLA_SUCCESS) { 5492 ql_dbg(ql_dbg_mbx, vha, 0x1101, 5493 "Failed=%x mb[0]=%x mb[1]=%x.\n", 5494 rval, mcp->mb[0], mcp->mb[1]); 5495 } else { 5496 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102, 5497 "Done %s.\n", __func__); 5498 } 5499 5500 return rval; 5501} 5502 5503int 5504qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb) 5505{ 5506 int rval; 5507 uint32_t stat, timer; 5508 uint16_t mb0 = 0; 5509 struct qla_hw_data *ha = vha->hw; 5510 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 5511 5512 rval = QLA_SUCCESS; 5513 5514 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103, 5515 "Entered %s.\n", __func__); 5516 5517 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 5518 5519 /* Write the MBC data to the registers */ 5520 wrt_reg_word(®->mailbox0, MBC_WRITE_MPI_REGISTER); 5521 wrt_reg_word(®->mailbox1, mb[0]); 5522 wrt_reg_word(®->mailbox2, mb[1]); 5523 wrt_reg_word(®->mailbox3, mb[2]); 5524 wrt_reg_word(®->mailbox4, mb[3]); 5525 5526 wrt_reg_dword(®->hccr, HCCRX_SET_HOST_INT); 5527 5528 /* Poll for MBC interrupt */ 5529 for (timer = 6000000; timer; timer--) { 5530 /* Check for pending interrupts. */ 5531 stat = rd_reg_dword(®->host_status); 5532 if (stat & HSRX_RISC_INT) { 5533 stat &= 0xff; 5534 5535 if (stat == 0x1 || stat == 0x2 || 5536 stat == 0x10 || stat == 0x11) { 5537 set_bit(MBX_INTERRUPT, 5538 &ha->mbx_cmd_flags); 5539 mb0 = rd_reg_word(®->mailbox0); 5540 wrt_reg_dword(®->hccr, 5541 HCCRX_CLR_RISC_INT); 5542 rd_reg_dword(®->hccr); 5543 break; 5544 } 5545 } 5546 udelay(5); 5547 } 5548 5549 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) 5550 rval = mb0 & MBS_MASK; 5551 else 5552 rval = QLA_FUNCTION_FAILED; 5553 5554 if (rval != QLA_SUCCESS) { 5555 ql_dbg(ql_dbg_mbx, vha, 0x1104, 5556 "Failed=%x mb[0]=%x.\n", rval, mb[0]); 5557 } else { 5558 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105, 5559 "Done %s.\n", __func__); 5560 } 5561 5562 return rval; 5563} 5564 5565/* Set the specified data rate */ 5566int 5567qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode) 5568{ 5569 int rval; 5570 mbx_cmd_t mc; 5571 mbx_cmd_t *mcp = &mc; 5572 struct qla_hw_data *ha = vha->hw; 5573 uint16_t val; 5574 5575 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106, 5576 "Entered %s speed:0x%x mode:0x%x.\n", __func__, ha->set_data_rate, 5577 mode); 5578 5579 if (!IS_FWI2_CAPABLE(ha)) 5580 return QLA_FUNCTION_FAILED; 5581 5582 memset(mcp, 0, sizeof(*mcp)); 5583 switch (ha->set_data_rate) { 5584 case PORT_SPEED_AUTO: 5585 case PORT_SPEED_4GB: 5586 case PORT_SPEED_8GB: 5587 case PORT_SPEED_16GB: 5588 case PORT_SPEED_32GB: 5589 val = ha->set_data_rate; 5590 break; 5591 default: 5592 ql_log(ql_log_warn, vha, 0x1199, 5593 "Unrecognized speed setting:%d. Setting Autoneg\n", 5594 ha->set_data_rate); 5595 val = ha->set_data_rate = PORT_SPEED_AUTO; 5596 break; 5597 } 5598 5599 mcp->mb[0] = MBC_DATA_RATE; 5600 mcp->mb[1] = mode; 5601 mcp->mb[2] = val; 5602 5603 mcp->out_mb = MBX_2|MBX_1|MBX_0; 5604 mcp->in_mb = MBX_2|MBX_1|MBX_0; 5605 if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 5606 mcp->in_mb |= MBX_4|MBX_3; 5607 mcp->tov = MBX_TOV_SECONDS; 5608 mcp->flags = 0; 5609 rval = qla2x00_mailbox_command(vha, mcp); 5610 if (rval != QLA_SUCCESS) { 5611 ql_dbg(ql_dbg_mbx, vha, 0x1107, 5612 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 5613 } else { 5614 if (mcp->mb[1] != 0x7) 5615 ql_dbg(ql_dbg_mbx, vha, 0x1179, 5616 "Speed set:0x%x\n", mcp->mb[1]); 5617 5618 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108, 5619 "Done %s.\n", __func__); 5620 } 5621 5622 return rval; 5623} 5624 5625int 5626qla2x00_get_data_rate(scsi_qla_host_t *vha) 5627{ 5628 int rval; 5629 mbx_cmd_t mc; 5630 mbx_cmd_t *mcp = &mc; 5631 struct qla_hw_data *ha = vha->hw; 5632 5633 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106, 5634 "Entered %s.\n", __func__); 5635 5636 if (!IS_FWI2_CAPABLE(ha)) 5637 return QLA_FUNCTION_FAILED; 5638 5639 mcp->mb[0] = MBC_DATA_RATE; 5640 mcp->mb[1] = QLA_GET_DATA_RATE; 5641 mcp->out_mb = MBX_1|MBX_0; 5642 mcp->in_mb = MBX_2|MBX_1|MBX_0; 5643 if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) 5644 mcp->in_mb |= MBX_4|MBX_3; 5645 mcp->tov = MBX_TOV_SECONDS; 5646 mcp->flags = 0; 5647 rval = qla2x00_mailbox_command(vha, mcp); 5648 if (rval != QLA_SUCCESS) { 5649 ql_dbg(ql_dbg_mbx, vha, 0x1107, 5650 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 5651 } else { 5652 if (mcp->mb[1] != 0x7) 5653 ha->link_data_rate = mcp->mb[1]; 5654 5655 if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 5656 if (mcp->mb[4] & BIT_0) 5657 ql_log(ql_log_info, vha, 0x11a2, 5658 "FEC=enabled (data rate).\n"); 5659 } 5660 5661 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108, 5662 "Done %s.\n", __func__); 5663 if (mcp->mb[1] != 0x7) 5664 ha->link_data_rate = mcp->mb[1]; 5665 } 5666 5667 return rval; 5668} 5669 5670int 5671qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb) 5672{ 5673 int rval; 5674 mbx_cmd_t mc; 5675 mbx_cmd_t *mcp = &mc; 5676 struct qla_hw_data *ha = vha->hw; 5677 5678 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109, 5679 "Entered %s.\n", __func__); 5680 5681 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) && 5682 !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 5683 return QLA_FUNCTION_FAILED; 5684 mcp->mb[0] = MBC_GET_PORT_CONFIG; 5685 mcp->out_mb = MBX_0; 5686 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 5687 mcp->tov = MBX_TOV_SECONDS; 5688 mcp->flags = 0; 5689 5690 rval = qla2x00_mailbox_command(vha, mcp); 5691 5692 if (rval != QLA_SUCCESS) { 5693 ql_dbg(ql_dbg_mbx, vha, 0x110a, 5694 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 5695 } else { 5696 /* Copy all bits to preserve original value */ 5697 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4); 5698 5699 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b, 5700 "Done %s.\n", __func__); 5701 } 5702 return rval; 5703} 5704 5705int 5706qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb) 5707{ 5708 int rval; 5709 mbx_cmd_t mc; 5710 mbx_cmd_t *mcp = &mc; 5711 5712 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c, 5713 "Entered %s.\n", __func__); 5714 5715 mcp->mb[0] = MBC_SET_PORT_CONFIG; 5716 /* Copy all bits to preserve original setting */ 5717 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4); 5718 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 5719 mcp->in_mb = MBX_0; 5720 mcp->tov = MBX_TOV_SECONDS; 5721 mcp->flags = 0; 5722 rval = qla2x00_mailbox_command(vha, mcp); 5723 5724 if (rval != QLA_SUCCESS) { 5725 ql_dbg(ql_dbg_mbx, vha, 0x110d, 5726 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 5727 } else 5728 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e, 5729 "Done %s.\n", __func__); 5730 5731 return rval; 5732} 5733 5734 5735int 5736qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority, 5737 uint16_t *mb) 5738{ 5739 int rval; 5740 mbx_cmd_t mc; 5741 mbx_cmd_t *mcp = &mc; 5742 struct qla_hw_data *ha = vha->hw; 5743 5744 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f, 5745 "Entered %s.\n", __func__); 5746 5747 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) 5748 return QLA_FUNCTION_FAILED; 5749 5750 mcp->mb[0] = MBC_PORT_PARAMS; 5751 mcp->mb[1] = loop_id; 5752 if (ha->flags.fcp_prio_enabled) 5753 mcp->mb[2] = BIT_1; 5754 else 5755 mcp->mb[2] = BIT_2; 5756 mcp->mb[4] = priority & 0xf; 5757 mcp->mb[9] = vha->vp_idx; 5758 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 5759 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0; 5760 mcp->tov = MBX_TOV_SECONDS; 5761 mcp->flags = 0; 5762 rval = qla2x00_mailbox_command(vha, mcp); 5763 if (mb != NULL) { 5764 mb[0] = mcp->mb[0]; 5765 mb[1] = mcp->mb[1]; 5766 mb[3] = mcp->mb[3]; 5767 mb[4] = mcp->mb[4]; 5768 } 5769 5770 if (rval != QLA_SUCCESS) { 5771 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval); 5772 } else { 5773 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc, 5774 "Done %s.\n", __func__); 5775 } 5776 5777 return rval; 5778} 5779 5780int 5781qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp) 5782{ 5783 int rval = QLA_FUNCTION_FAILED; 5784 struct qla_hw_data *ha = vha->hw; 5785 uint8_t byte; 5786 5787 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) { 5788 ql_dbg(ql_dbg_mbx, vha, 0x1150, 5789 "Thermal not supported by this card.\n"); 5790 return rval; 5791 } 5792 5793 if (IS_QLA25XX(ha)) { 5794 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && 5795 ha->pdev->subsystem_device == 0x0175) { 5796 rval = qla2x00_read_sfp(vha, 0, &byte, 5797 0x98, 0x1, 1, BIT_13|BIT_0); 5798 *temp = byte; 5799 return rval; 5800 } 5801 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && 5802 ha->pdev->subsystem_device == 0x338e) { 5803 rval = qla2x00_read_sfp(vha, 0, &byte, 5804 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0); 5805 *temp = byte; 5806 return rval; 5807 } 5808 ql_dbg(ql_dbg_mbx, vha, 0x10c9, 5809 "Thermal not supported by this card.\n"); 5810 return rval; 5811 } 5812 5813 if (IS_QLA82XX(ha)) { 5814 *temp = qla82xx_read_temperature(vha); 5815 rval = QLA_SUCCESS; 5816 return rval; 5817 } else if (IS_QLA8044(ha)) { 5818 *temp = qla8044_read_temperature(vha); 5819 rval = QLA_SUCCESS; 5820 return rval; 5821 } 5822 5823 rval = qla2x00_read_asic_temperature(vha, temp); 5824 return rval; 5825} 5826 5827int 5828qla82xx_mbx_intr_enable(scsi_qla_host_t *vha) 5829{ 5830 int rval; 5831 struct qla_hw_data *ha = vha->hw; 5832 mbx_cmd_t mc; 5833 mbx_cmd_t *mcp = &mc; 5834 5835 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017, 5836 "Entered %s.\n", __func__); 5837 5838 if (!IS_FWI2_CAPABLE(ha)) 5839 return QLA_FUNCTION_FAILED; 5840 5841 memset(mcp, 0, sizeof(mbx_cmd_t)); 5842 mcp->mb[0] = MBC_TOGGLE_INTERRUPT; 5843 mcp->mb[1] = 1; 5844 5845 mcp->out_mb = MBX_1|MBX_0; 5846 mcp->in_mb = MBX_0; 5847 mcp->tov = MBX_TOV_SECONDS; 5848 mcp->flags = 0; 5849 5850 rval = qla2x00_mailbox_command(vha, mcp); 5851 if (rval != QLA_SUCCESS) { 5852 ql_dbg(ql_dbg_mbx, vha, 0x1016, 5853 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 5854 } else { 5855 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e, 5856 "Done %s.\n", __func__); 5857 } 5858 5859 return rval; 5860} 5861 5862int 5863qla82xx_mbx_intr_disable(scsi_qla_host_t *vha) 5864{ 5865 int rval; 5866 struct qla_hw_data *ha = vha->hw; 5867 mbx_cmd_t mc; 5868 mbx_cmd_t *mcp = &mc; 5869 5870 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d, 5871 "Entered %s.\n", __func__); 5872 5873 if (!IS_P3P_TYPE(ha)) 5874 return QLA_FUNCTION_FAILED; 5875 5876 memset(mcp, 0, sizeof(mbx_cmd_t)); 5877 mcp->mb[0] = MBC_TOGGLE_INTERRUPT; 5878 mcp->mb[1] = 0; 5879 5880 mcp->out_mb = MBX_1|MBX_0; 5881 mcp->in_mb = MBX_0; 5882 mcp->tov = MBX_TOV_SECONDS; 5883 mcp->flags = 0; 5884 5885 rval = qla2x00_mailbox_command(vha, mcp); 5886 if (rval != QLA_SUCCESS) { 5887 ql_dbg(ql_dbg_mbx, vha, 0x100c, 5888 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 5889 } else { 5890 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b, 5891 "Done %s.\n", __func__); 5892 } 5893 5894 return rval; 5895} 5896 5897int 5898qla82xx_md_get_template_size(scsi_qla_host_t *vha) 5899{ 5900 struct qla_hw_data *ha = vha->hw; 5901 mbx_cmd_t mc; 5902 mbx_cmd_t *mcp = &mc; 5903 int rval = QLA_FUNCTION_FAILED; 5904 5905 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f, 5906 "Entered %s.\n", __func__); 5907 5908 memset(mcp->mb, 0 , sizeof(mcp->mb)); 5909 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 5910 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 5911 mcp->mb[2] = LSW(RQST_TMPLT_SIZE); 5912 mcp->mb[3] = MSW(RQST_TMPLT_SIZE); 5913 5914 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 5915 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8| 5916 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 5917 5918 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 5919 mcp->tov = MBX_TOV_SECONDS; 5920 rval = qla2x00_mailbox_command(vha, mcp); 5921 5922 /* Always copy back return mailbox values. */ 5923 if (rval != QLA_SUCCESS) { 5924 ql_dbg(ql_dbg_mbx, vha, 0x1120, 5925 "mailbox command FAILED=0x%x, subcode=%x.\n", 5926 (mcp->mb[1] << 16) | mcp->mb[0], 5927 (mcp->mb[3] << 16) | mcp->mb[2]); 5928 } else { 5929 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121, 5930 "Done %s.\n", __func__); 5931 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]); 5932 if (!ha->md_template_size) { 5933 ql_dbg(ql_dbg_mbx, vha, 0x1122, 5934 "Null template size obtained.\n"); 5935 rval = QLA_FUNCTION_FAILED; 5936 } 5937 } 5938 return rval; 5939} 5940 5941int 5942qla82xx_md_get_template(scsi_qla_host_t *vha) 5943{ 5944 struct qla_hw_data *ha = vha->hw; 5945 mbx_cmd_t mc; 5946 mbx_cmd_t *mcp = &mc; 5947 int rval = QLA_FUNCTION_FAILED; 5948 5949 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123, 5950 "Entered %s.\n", __func__); 5951 5952 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev, 5953 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL); 5954 if (!ha->md_tmplt_hdr) { 5955 ql_log(ql_log_warn, vha, 0x1124, 5956 "Unable to allocate memory for Minidump template.\n"); 5957 return rval; 5958 } 5959 5960 memset(mcp->mb, 0 , sizeof(mcp->mb)); 5961 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 5962 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 5963 mcp->mb[2] = LSW(RQST_TMPLT); 5964 mcp->mb[3] = MSW(RQST_TMPLT); 5965 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma)); 5966 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma)); 5967 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma)); 5968 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma)); 5969 mcp->mb[8] = LSW(ha->md_template_size); 5970 mcp->mb[9] = MSW(ha->md_template_size); 5971 5972 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 5973 mcp->tov = MBX_TOV_SECONDS; 5974 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8| 5975 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 5976 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 5977 rval = qla2x00_mailbox_command(vha, mcp); 5978 5979 if (rval != QLA_SUCCESS) { 5980 ql_dbg(ql_dbg_mbx, vha, 0x1125, 5981 "mailbox command FAILED=0x%x, subcode=%x.\n", 5982 ((mcp->mb[1] << 16) | mcp->mb[0]), 5983 ((mcp->mb[3] << 16) | mcp->mb[2])); 5984 } else 5985 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126, 5986 "Done %s.\n", __func__); 5987 return rval; 5988} 5989 5990int 5991qla8044_md_get_template(scsi_qla_host_t *vha) 5992{ 5993 struct qla_hw_data *ha = vha->hw; 5994 mbx_cmd_t mc; 5995 mbx_cmd_t *mcp = &mc; 5996 int rval = QLA_FUNCTION_FAILED; 5997 int offset = 0, size = MINIDUMP_SIZE_36K; 5998 5999 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f, 6000 "Entered %s.\n", __func__); 6001 6002 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev, 6003 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL); 6004 if (!ha->md_tmplt_hdr) { 6005 ql_log(ql_log_warn, vha, 0xb11b, 6006 "Unable to allocate memory for Minidump template.\n"); 6007 return rval; 6008 } 6009 6010 memset(mcp->mb, 0 , sizeof(mcp->mb)); 6011 while (offset < ha->md_template_size) { 6012 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 6013 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); 6014 mcp->mb[2] = LSW(RQST_TMPLT); 6015 mcp->mb[3] = MSW(RQST_TMPLT); 6016 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset)); 6017 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset)); 6018 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset)); 6019 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset)); 6020 mcp->mb[8] = LSW(size); 6021 mcp->mb[9] = MSW(size); 6022 mcp->mb[10] = offset & 0x0000FFFF; 6023 mcp->mb[11] = offset & 0xFFFF0000; 6024 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD; 6025 mcp->tov = MBX_TOV_SECONDS; 6026 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8| 6027 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 6028 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 6029 rval = qla2x00_mailbox_command(vha, mcp); 6030 6031 if (rval != QLA_SUCCESS) { 6032 ql_dbg(ql_dbg_mbx, vha, 0xb11c, 6033 "mailbox command FAILED=0x%x, subcode=%x.\n", 6034 ((mcp->mb[1] << 16) | mcp->mb[0]), 6035 ((mcp->mb[3] << 16) | mcp->mb[2])); 6036 return rval; 6037 } else 6038 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d, 6039 "Done %s.\n", __func__); 6040 offset = offset + size; 6041 } 6042 return rval; 6043} 6044 6045int 6046qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg) 6047{ 6048 int rval; 6049 struct qla_hw_data *ha = vha->hw; 6050 mbx_cmd_t mc; 6051 mbx_cmd_t *mcp = &mc; 6052 6053 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 6054 return QLA_FUNCTION_FAILED; 6055 6056 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133, 6057 "Entered %s.\n", __func__); 6058 6059 memset(mcp, 0, sizeof(mbx_cmd_t)); 6060 mcp->mb[0] = MBC_SET_LED_CONFIG; 6061 mcp->mb[1] = led_cfg[0]; 6062 mcp->mb[2] = led_cfg[1]; 6063 if (IS_QLA8031(ha)) { 6064 mcp->mb[3] = led_cfg[2]; 6065 mcp->mb[4] = led_cfg[3]; 6066 mcp->mb[5] = led_cfg[4]; 6067 mcp->mb[6] = led_cfg[5]; 6068 } 6069 6070 mcp->out_mb = MBX_2|MBX_1|MBX_0; 6071 if (IS_QLA8031(ha)) 6072 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3; 6073 mcp->in_mb = MBX_0; 6074 mcp->tov = MBX_TOV_SECONDS; 6075 mcp->flags = 0; 6076 6077 rval = qla2x00_mailbox_command(vha, mcp); 6078 if (rval != QLA_SUCCESS) { 6079 ql_dbg(ql_dbg_mbx, vha, 0x1134, 6080 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 6081 } else { 6082 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135, 6083 "Done %s.\n", __func__); 6084 } 6085 6086 return rval; 6087} 6088 6089int 6090qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg) 6091{ 6092 int rval; 6093 struct qla_hw_data *ha = vha->hw; 6094 mbx_cmd_t mc; 6095 mbx_cmd_t *mcp = &mc; 6096 6097 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 6098 return QLA_FUNCTION_FAILED; 6099 6100 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136, 6101 "Entered %s.\n", __func__); 6102 6103 memset(mcp, 0, sizeof(mbx_cmd_t)); 6104 mcp->mb[0] = MBC_GET_LED_CONFIG; 6105 6106 mcp->out_mb = MBX_0; 6107 mcp->in_mb = MBX_2|MBX_1|MBX_0; 6108 if (IS_QLA8031(ha)) 6109 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3; 6110 mcp->tov = MBX_TOV_SECONDS; 6111 mcp->flags = 0; 6112 6113 rval = qla2x00_mailbox_command(vha, mcp); 6114 if (rval != QLA_SUCCESS) { 6115 ql_dbg(ql_dbg_mbx, vha, 0x1137, 6116 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 6117 } else { 6118 led_cfg[0] = mcp->mb[1]; 6119 led_cfg[1] = mcp->mb[2]; 6120 if (IS_QLA8031(ha)) { 6121 led_cfg[2] = mcp->mb[3]; 6122 led_cfg[3] = mcp->mb[4]; 6123 led_cfg[4] = mcp->mb[5]; 6124 led_cfg[5] = mcp->mb[6]; 6125 } 6126 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138, 6127 "Done %s.\n", __func__); 6128 } 6129 6130 return rval; 6131} 6132 6133int 6134qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable) 6135{ 6136 int rval; 6137 struct qla_hw_data *ha = vha->hw; 6138 mbx_cmd_t mc; 6139 mbx_cmd_t *mcp = &mc; 6140 6141 if (!IS_P3P_TYPE(ha)) 6142 return QLA_FUNCTION_FAILED; 6143 6144 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127, 6145 "Entered %s.\n", __func__); 6146 6147 memset(mcp, 0, sizeof(mbx_cmd_t)); 6148 mcp->mb[0] = MBC_SET_LED_CONFIG; 6149 if (enable) 6150 mcp->mb[7] = 0xE; 6151 else 6152 mcp->mb[7] = 0xD; 6153 6154 mcp->out_mb = MBX_7|MBX_0; 6155 mcp->in_mb = MBX_0; 6156 mcp->tov = MBX_TOV_SECONDS; 6157 mcp->flags = 0; 6158 6159 rval = qla2x00_mailbox_command(vha, mcp); 6160 if (rval != QLA_SUCCESS) { 6161 ql_dbg(ql_dbg_mbx, vha, 0x1128, 6162 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 6163 } else { 6164 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129, 6165 "Done %s.\n", __func__); 6166 } 6167 6168 return rval; 6169} 6170 6171int 6172qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data) 6173{ 6174 int rval; 6175 struct qla_hw_data *ha = vha->hw; 6176 mbx_cmd_t mc; 6177 mbx_cmd_t *mcp = &mc; 6178 6179 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 6180 return QLA_FUNCTION_FAILED; 6181 6182 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130, 6183 "Entered %s.\n", __func__); 6184 6185 mcp->mb[0] = MBC_WRITE_REMOTE_REG; 6186 mcp->mb[1] = LSW(reg); 6187 mcp->mb[2] = MSW(reg); 6188 mcp->mb[3] = LSW(data); 6189 mcp->mb[4] = MSW(data); 6190 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 6191 6192 mcp->in_mb = MBX_1|MBX_0; 6193 mcp->tov = MBX_TOV_SECONDS; 6194 mcp->flags = 0; 6195 rval = qla2x00_mailbox_command(vha, mcp); 6196 6197 if (rval != QLA_SUCCESS) { 6198 ql_dbg(ql_dbg_mbx, vha, 0x1131, 6199 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 6200 } else { 6201 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132, 6202 "Done %s.\n", __func__); 6203 } 6204 6205 return rval; 6206} 6207 6208int 6209qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport) 6210{ 6211 int rval; 6212 struct qla_hw_data *ha = vha->hw; 6213 mbx_cmd_t mc; 6214 mbx_cmd_t *mcp = &mc; 6215 6216 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 6217 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b, 6218 "Implicit LOGO Unsupported.\n"); 6219 return QLA_FUNCTION_FAILED; 6220 } 6221 6222 6223 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c, 6224 "Entering %s.\n", __func__); 6225 6226 /* Perform Implicit LOGO. */ 6227 mcp->mb[0] = MBC_PORT_LOGOUT; 6228 mcp->mb[1] = fcport->loop_id; 6229 mcp->mb[10] = BIT_15; 6230 mcp->out_mb = MBX_10|MBX_1|MBX_0; 6231 mcp->in_mb = MBX_0; 6232 mcp->tov = MBX_TOV_SECONDS; 6233 mcp->flags = 0; 6234 rval = qla2x00_mailbox_command(vha, mcp); 6235 if (rval != QLA_SUCCESS) 6236 ql_dbg(ql_dbg_mbx, vha, 0x113d, 6237 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 6238 else 6239 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e, 6240 "Done %s.\n", __func__); 6241 6242 return rval; 6243} 6244 6245int 6246qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data) 6247{ 6248 int rval; 6249 mbx_cmd_t mc; 6250 mbx_cmd_t *mcp = &mc; 6251 struct qla_hw_data *ha = vha->hw; 6252 unsigned long retry_max_time = jiffies + (2 * HZ); 6253 6254 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 6255 return QLA_FUNCTION_FAILED; 6256 6257 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__); 6258 6259retry_rd_reg: 6260 mcp->mb[0] = MBC_READ_REMOTE_REG; 6261 mcp->mb[1] = LSW(reg); 6262 mcp->mb[2] = MSW(reg); 6263 mcp->out_mb = MBX_2|MBX_1|MBX_0; 6264 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0; 6265 mcp->tov = MBX_TOV_SECONDS; 6266 mcp->flags = 0; 6267 rval = qla2x00_mailbox_command(vha, mcp); 6268 6269 if (rval != QLA_SUCCESS) { 6270 ql_dbg(ql_dbg_mbx, vha, 0x114c, 6271 "Failed=%x mb[0]=%x mb[1]=%x.\n", 6272 rval, mcp->mb[0], mcp->mb[1]); 6273 } else { 6274 *data = (mcp->mb[3] | (mcp->mb[4] << 16)); 6275 if (*data == QLA8XXX_BAD_VALUE) { 6276 /* 6277 * During soft-reset CAMRAM register reads might 6278 * return 0xbad0bad0. So retry for MAX of 2 sec 6279 * while reading camram registers. 6280 */ 6281 if (time_after(jiffies, retry_max_time)) { 6282 ql_dbg(ql_dbg_mbx, vha, 0x1141, 6283 "Failure to read CAMRAM register. " 6284 "data=0x%x.\n", *data); 6285 return QLA_FUNCTION_FAILED; 6286 } 6287 msleep(100); 6288 goto retry_rd_reg; 6289 } 6290 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__); 6291 } 6292 6293 return rval; 6294} 6295 6296int 6297qla83xx_restart_nic_firmware(scsi_qla_host_t *vha) 6298{ 6299 int rval; 6300 mbx_cmd_t mc; 6301 mbx_cmd_t *mcp = &mc; 6302 struct qla_hw_data *ha = vha->hw; 6303 6304 if (!IS_QLA83XX(ha)) 6305 return QLA_FUNCTION_FAILED; 6306 6307 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__); 6308 6309 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE; 6310 mcp->out_mb = MBX_0; 6311 mcp->in_mb = MBX_1|MBX_0; 6312 mcp->tov = MBX_TOV_SECONDS; 6313 mcp->flags = 0; 6314 rval = qla2x00_mailbox_command(vha, mcp); 6315 6316 if (rval != QLA_SUCCESS) { 6317 ql_dbg(ql_dbg_mbx, vha, 0x1144, 6318 "Failed=%x mb[0]=%x mb[1]=%x.\n", 6319 rval, mcp->mb[0], mcp->mb[1]); 6320 qla2xxx_dump_fw(vha); 6321 } else { 6322 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__); 6323 } 6324 6325 return rval; 6326} 6327 6328int 6329qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options, 6330 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size) 6331{ 6332 int rval; 6333 mbx_cmd_t mc; 6334 mbx_cmd_t *mcp = &mc; 6335 uint8_t subcode = (uint8_t)options; 6336 struct qla_hw_data *ha = vha->hw; 6337 6338 if (!IS_QLA8031(ha)) 6339 return QLA_FUNCTION_FAILED; 6340 6341 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__); 6342 6343 mcp->mb[0] = MBC_SET_ACCESS_CONTROL; 6344 mcp->mb[1] = options; 6345 mcp->out_mb = MBX_1|MBX_0; 6346 if (subcode & BIT_2) { 6347 mcp->mb[2] = LSW(start_addr); 6348 mcp->mb[3] = MSW(start_addr); 6349 mcp->mb[4] = LSW(end_addr); 6350 mcp->mb[5] = MSW(end_addr); 6351 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2; 6352 } 6353 mcp->in_mb = MBX_2|MBX_1|MBX_0; 6354 if (!(subcode & (BIT_2 | BIT_5))) 6355 mcp->in_mb |= MBX_4|MBX_3; 6356 mcp->tov = MBX_TOV_SECONDS; 6357 mcp->flags = 0; 6358 rval = qla2x00_mailbox_command(vha, mcp); 6359 6360 if (rval != QLA_SUCCESS) { 6361 ql_dbg(ql_dbg_mbx, vha, 0x1147, 6362 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n", 6363 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], 6364 mcp->mb[4]); 6365 qla2xxx_dump_fw(vha); 6366 } else { 6367 if (subcode & BIT_5) 6368 *sector_size = mcp->mb[1]; 6369 else if (subcode & (BIT_6 | BIT_7)) { 6370 ql_dbg(ql_dbg_mbx, vha, 0x1148, 6371 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]); 6372 } else if (subcode & (BIT_3 | BIT_4)) { 6373 ql_dbg(ql_dbg_mbx, vha, 0x1149, 6374 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]); 6375 } 6376 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__); 6377 } 6378 6379 return rval; 6380} 6381 6382int 6383qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr, 6384 uint32_t size) 6385{ 6386 int rval; 6387 mbx_cmd_t mc; 6388 mbx_cmd_t *mcp = &mc; 6389 6390 if (!IS_MCTP_CAPABLE(vha->hw)) 6391 return QLA_FUNCTION_FAILED; 6392 6393 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f, 6394 "Entered %s.\n", __func__); 6395 6396 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED; 6397 mcp->mb[1] = LSW(addr); 6398 mcp->mb[2] = MSW(req_dma); 6399 mcp->mb[3] = LSW(req_dma); 6400 mcp->mb[4] = MSW(size); 6401 mcp->mb[5] = LSW(size); 6402 mcp->mb[6] = MSW(MSD(req_dma)); 6403 mcp->mb[7] = LSW(MSD(req_dma)); 6404 mcp->mb[8] = MSW(addr); 6405 /* Setting RAM ID to valid */ 6406 /* For MCTP RAM ID is 0x40 */ 6407 mcp->mb[10] = BIT_7 | 0x40; 6408 6409 mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| 6410 MBX_0; 6411 6412 mcp->in_mb = MBX_0; 6413 mcp->tov = MBX_TOV_SECONDS; 6414 mcp->flags = 0; 6415 rval = qla2x00_mailbox_command(vha, mcp); 6416 6417 if (rval != QLA_SUCCESS) { 6418 ql_dbg(ql_dbg_mbx, vha, 0x114e, 6419 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 6420 } else { 6421 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d, 6422 "Done %s.\n", __func__); 6423 } 6424 6425 return rval; 6426} 6427 6428int 6429qla26xx_dport_diagnostics(scsi_qla_host_t *vha, 6430 void *dd_buf, uint size, uint options) 6431{ 6432 int rval; 6433 mbx_cmd_t mc; 6434 mbx_cmd_t *mcp = &mc; 6435 dma_addr_t dd_dma; 6436 6437 if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && 6438 !IS_QLA28XX(vha->hw)) 6439 return QLA_FUNCTION_FAILED; 6440 6441 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f, 6442 "Entered %s.\n", __func__); 6443 6444 dd_dma = dma_map_single(&vha->hw->pdev->dev, 6445 dd_buf, size, DMA_FROM_DEVICE); 6446 if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) { 6447 ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n"); 6448 return QLA_MEMORY_ALLOC_FAILED; 6449 } 6450 6451 memset(dd_buf, 0, size); 6452 6453 mcp->mb[0] = MBC_DPORT_DIAGNOSTICS; 6454 mcp->mb[1] = options; 6455 mcp->mb[2] = MSW(LSD(dd_dma)); 6456 mcp->mb[3] = LSW(LSD(dd_dma)); 6457 mcp->mb[6] = MSW(MSD(dd_dma)); 6458 mcp->mb[7] = LSW(MSD(dd_dma)); 6459 mcp->mb[8] = size; 6460 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 6461 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 6462 mcp->buf_size = size; 6463 mcp->flags = MBX_DMA_IN; 6464 mcp->tov = MBX_TOV_SECONDS * 4; 6465 rval = qla2x00_mailbox_command(vha, mcp); 6466 6467 if (rval != QLA_SUCCESS) { 6468 ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval); 6469 } else { 6470 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196, 6471 "Done %s.\n", __func__); 6472 } 6473 6474 dma_unmap_single(&vha->hw->pdev->dev, dd_dma, 6475 size, DMA_FROM_DEVICE); 6476 6477 return rval; 6478} 6479 6480int 6481qla26xx_dport_diagnostics_v2(scsi_qla_host_t *vha, 6482 struct qla_dport_diag_v2 *dd, mbx_cmd_t *mcp) 6483{ 6484 int rval; 6485 dma_addr_t dd_dma; 6486 uint size = sizeof(dd->buf); 6487 uint16_t options = dd->options; 6488 6489 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f, 6490 "Entered %s.\n", __func__); 6491 6492 dd_dma = dma_map_single(&vha->hw->pdev->dev, 6493 dd->buf, size, DMA_FROM_DEVICE); 6494 if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) { 6495 ql_log(ql_log_warn, vha, 0x1194, 6496 "Failed to map dma buffer.\n"); 6497 return QLA_MEMORY_ALLOC_FAILED; 6498 } 6499 6500 memset(dd->buf, 0, size); 6501 6502 mcp->mb[0] = MBC_DPORT_DIAGNOSTICS; 6503 mcp->mb[1] = options; 6504 mcp->mb[2] = MSW(LSD(dd_dma)); 6505 mcp->mb[3] = LSW(LSD(dd_dma)); 6506 mcp->mb[6] = MSW(MSD(dd_dma)); 6507 mcp->mb[7] = LSW(MSD(dd_dma)); 6508 mcp->mb[8] = size; 6509 mcp->out_mb = MBX_8 | MBX_7 | MBX_6 | MBX_3 | MBX_2 | MBX_1 | MBX_0; 6510 mcp->in_mb = MBX_3 | MBX_2 | MBX_1 | MBX_0; 6511 mcp->buf_size = size; 6512 mcp->flags = MBX_DMA_IN; 6513 mcp->tov = MBX_TOV_SECONDS * 4; 6514 rval = qla2x00_mailbox_command(vha, mcp); 6515 6516 if (rval != QLA_SUCCESS) { 6517 ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval); 6518 } else { 6519 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196, 6520 "Done %s.\n", __func__); 6521 } 6522 6523 dma_unmap_single(&vha->hw->pdev->dev, dd_dma, size, DMA_FROM_DEVICE); 6524 6525 return rval; 6526} 6527 6528static void qla2x00_async_mb_sp_done(srb_t *sp, int res) 6529{ 6530 sp->u.iocb_cmd.u.mbx.rc = res; 6531 6532 complete(&sp->u.iocb_cmd.u.mbx.comp); 6533 /* don't free sp here. Let the caller do the free */ 6534} 6535 6536/* 6537 * This mailbox uses the iocb interface to send MB command. 6538 * This allows non-critial (non chip setup) command to go 6539 * out in parrallel. 6540 */ 6541int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp) 6542{ 6543 int rval = QLA_FUNCTION_FAILED; 6544 srb_t *sp; 6545 struct srb_iocb *c; 6546 6547 if (!vha->hw->flags.fw_started) 6548 goto done; 6549 6550 /* ref: INIT */ 6551 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 6552 if (!sp) 6553 goto done; 6554 6555 c = &sp->u.iocb_cmd; 6556 init_completion(&c->u.mbx.comp); 6557 6558 sp->type = SRB_MB_IOCB; 6559 sp->name = mb_to_str(mcp->mb[0]); 6560 qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, 6561 qla2x00_async_mb_sp_done); 6562 6563 memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG); 6564 6565 rval = qla2x00_start_sp(sp); 6566 if (rval != QLA_SUCCESS) { 6567 ql_dbg(ql_dbg_mbx, vha, 0x1018, 6568 "%s: %s Failed submission. %x.\n", 6569 __func__, sp->name, rval); 6570 goto done_free_sp; 6571 } 6572 6573 ql_dbg(ql_dbg_mbx, vha, 0x113f, "MB:%s hndl %x submitted\n", 6574 sp->name, sp->handle); 6575 6576 wait_for_completion(&c->u.mbx.comp); 6577 memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG); 6578 6579 rval = c->u.mbx.rc; 6580 switch (rval) { 6581 case QLA_FUNCTION_TIMEOUT: 6582 ql_dbg(ql_dbg_mbx, vha, 0x1140, "%s: %s Timeout. %x.\n", 6583 __func__, sp->name, rval); 6584 break; 6585 case QLA_SUCCESS: 6586 ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n", 6587 __func__, sp->name); 6588 break; 6589 default: 6590 ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n", 6591 __func__, sp->name, rval); 6592 break; 6593 } 6594 6595done_free_sp: 6596 /* ref: INIT */ 6597 kref_put(&sp->cmd_kref, qla2x00_sp_release); 6598done: 6599 return rval; 6600} 6601 6602int qla24xx_print_fc_port_id(struct scsi_qla_host *vha, struct seq_file *s, u16 loop_id) 6603{ 6604 int rval = QLA_FUNCTION_FAILED; 6605 dma_addr_t pd_dma; 6606 struct port_database_24xx *pd; 6607 struct qla_hw_data *ha = vha->hw; 6608 mbx_cmd_t mc; 6609 6610 if (!vha->hw->flags.fw_started) 6611 goto done; 6612 6613 pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); 6614 if (pd == NULL) { 6615 ql_log(ql_log_warn, vha, 0xd047, 6616 "Failed to allocate port database structure.\n"); 6617 goto done; 6618 } 6619 6620 memset(&mc, 0, sizeof(mc)); 6621 mc.mb[0] = MBC_GET_PORT_DATABASE; 6622 mc.mb[1] = loop_id; 6623 mc.mb[2] = MSW(pd_dma); 6624 mc.mb[3] = LSW(pd_dma); 6625 mc.mb[6] = MSW(MSD(pd_dma)); 6626 mc.mb[7] = LSW(MSD(pd_dma)); 6627 mc.mb[9] = vha->vp_idx; 6628 6629 rval = qla24xx_send_mb_cmd(vha, &mc); 6630 if (rval != QLA_SUCCESS) { 6631 ql_dbg(ql_dbg_mbx, vha, 0x1193, "%s: fail\n", __func__); 6632 goto done_free_sp; 6633 } 6634 6635 ql_dbg(ql_dbg_mbx, vha, 0x1197, "%s: %8phC done\n", 6636 __func__, pd->port_name); 6637 6638 seq_printf(s, "%8phC %02x%02x%02x %d\n", 6639 pd->port_name, pd->port_id[0], 6640 pd->port_id[1], pd->port_id[2], 6641 loop_id); 6642 6643done_free_sp: 6644 if (pd) 6645 dma_pool_free(ha->s_dma_pool, pd, pd_dma); 6646done: 6647 return rval; 6648} 6649 6650/* 6651 * qla24xx_gpdb_wait 6652 * NOTE: Do not call this routine from DPC thread 6653 */ 6654int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) 6655{ 6656 int rval = QLA_FUNCTION_FAILED; 6657 dma_addr_t pd_dma; 6658 struct port_database_24xx *pd; 6659 struct qla_hw_data *ha = vha->hw; 6660 mbx_cmd_t mc; 6661 6662 if (!vha->hw->flags.fw_started) 6663 goto done; 6664 6665 pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); 6666 if (pd == NULL) { 6667 ql_log(ql_log_warn, vha, 0xd047, 6668 "Failed to allocate port database structure.\n"); 6669 goto done_free_sp; 6670 } 6671 6672 memset(&mc, 0, sizeof(mc)); 6673 mc.mb[0] = MBC_GET_PORT_DATABASE; 6674 mc.mb[1] = fcport->loop_id; 6675 mc.mb[2] = MSW(pd_dma); 6676 mc.mb[3] = LSW(pd_dma); 6677 mc.mb[6] = MSW(MSD(pd_dma)); 6678 mc.mb[7] = LSW(MSD(pd_dma)); 6679 mc.mb[9] = vha->vp_idx; 6680 mc.mb[10] = opt; 6681 6682 rval = qla24xx_send_mb_cmd(vha, &mc); 6683 if (rval != QLA_SUCCESS) { 6684 ql_dbg(ql_dbg_mbx, vha, 0x1193, 6685 "%s: %8phC fail\n", __func__, fcport->port_name); 6686 goto done_free_sp; 6687 } 6688 6689 rval = __qla24xx_parse_gpdb(vha, fcport, pd); 6690 6691 ql_dbg(ql_dbg_mbx, vha, 0x1197, "%s: %8phC done\n", 6692 __func__, fcport->port_name); 6693 6694done_free_sp: 6695 if (pd) 6696 dma_pool_free(ha->s_dma_pool, pd, pd_dma); 6697done: 6698 return rval; 6699} 6700 6701int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, 6702 struct port_database_24xx *pd) 6703{ 6704 int rval = QLA_SUCCESS; 6705 uint64_t zero = 0; 6706 u8 current_login_state, last_login_state; 6707 6708 if (NVME_TARGET(vha->hw, fcport)) { 6709 current_login_state = pd->current_login_state >> 4; 6710 last_login_state = pd->last_login_state >> 4; 6711 } else { 6712 current_login_state = pd->current_login_state & 0xf; 6713 last_login_state = pd->last_login_state & 0xf; 6714 } 6715 6716 /* Check for logged in state. */ 6717 if (current_login_state != PDS_PRLI_COMPLETE) { 6718 ql_dbg(ql_dbg_mbx, vha, 0x119a, 6719 "Unable to verify login-state (%x/%x) for loop_id %x.\n", 6720 current_login_state, last_login_state, fcport->loop_id); 6721 rval = QLA_FUNCTION_FAILED; 6722 goto gpd_error_out; 6723 } 6724 6725 if (fcport->loop_id == FC_NO_LOOP_ID || 6726 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && 6727 memcmp(fcport->port_name, pd->port_name, 8))) { 6728 /* We lost the device mid way. */ 6729 rval = QLA_NOT_LOGGED_IN; 6730 goto gpd_error_out; 6731 } 6732 6733 /* Names are little-endian. */ 6734 memcpy(fcport->node_name, pd->node_name, WWN_SIZE); 6735 memcpy(fcport->port_name, pd->port_name, WWN_SIZE); 6736 6737 /* Get port_id of device. */ 6738 fcport->d_id.b.domain = pd->port_id[0]; 6739 fcport->d_id.b.area = pd->port_id[1]; 6740 fcport->d_id.b.al_pa = pd->port_id[2]; 6741 fcport->d_id.b.rsvd_1 = 0; 6742 6743 ql_dbg(ql_dbg_disc, vha, 0x2062, 6744 "%8phC SVC Param w3 %02x%02x", 6745 fcport->port_name, 6746 pd->prli_svc_param_word_3[1], 6747 pd->prli_svc_param_word_3[0]); 6748 6749 if (NVME_TARGET(vha->hw, fcport)) { 6750 fcport->port_type = FCT_NVME; 6751 if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0) 6752 fcport->port_type |= FCT_NVME_INITIATOR; 6753 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 6754 fcport->port_type |= FCT_NVME_TARGET; 6755 if ((pd->prli_svc_param_word_3[0] & BIT_3) == 0) 6756 fcport->port_type |= FCT_NVME_DISCOVERY; 6757 } else { 6758 /* If not target must be initiator or unknown type. */ 6759 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 6760 fcport->port_type = FCT_INITIATOR; 6761 else 6762 fcport->port_type = FCT_TARGET; 6763 } 6764 /* Passback COS information. */ 6765 fcport->supported_classes = (pd->flags & PDF_CLASS_2) ? 6766 FC_COS_CLASS2 : FC_COS_CLASS3; 6767 6768 if (pd->prli_svc_param_word_3[0] & BIT_7) { 6769 fcport->flags |= FCF_CONF_COMP_SUPPORTED; 6770 fcport->conf_compl_supported = 1; 6771 } 6772 6773gpd_error_out: 6774 return rval; 6775} 6776 6777/* 6778 * qla24xx_gidlist__wait 6779 * NOTE: don't call this routine from DPC thread. 6780 */ 6781int qla24xx_gidlist_wait(struct scsi_qla_host *vha, 6782 void *id_list, dma_addr_t id_list_dma, uint16_t *entries) 6783{ 6784 int rval = QLA_FUNCTION_FAILED; 6785 mbx_cmd_t mc; 6786 6787 if (!vha->hw->flags.fw_started) 6788 goto done; 6789 6790 memset(&mc, 0, sizeof(mc)); 6791 mc.mb[0] = MBC_GET_ID_LIST; 6792 mc.mb[2] = MSW(id_list_dma); 6793 mc.mb[3] = LSW(id_list_dma); 6794 mc.mb[6] = MSW(MSD(id_list_dma)); 6795 mc.mb[7] = LSW(MSD(id_list_dma)); 6796 mc.mb[8] = 0; 6797 mc.mb[9] = vha->vp_idx; 6798 6799 rval = qla24xx_send_mb_cmd(vha, &mc); 6800 if (rval != QLA_SUCCESS) { 6801 ql_dbg(ql_dbg_mbx, vha, 0x119b, 6802 "%s: fail\n", __func__); 6803 } else { 6804 *entries = mc.mb[1]; 6805 ql_dbg(ql_dbg_mbx, vha, 0x119c, 6806 "%s: done\n", __func__); 6807 } 6808done: 6809 return rval; 6810} 6811 6812int qla27xx_set_zio_threshold(scsi_qla_host_t *vha, uint16_t value) 6813{ 6814 int rval; 6815 mbx_cmd_t mc; 6816 mbx_cmd_t *mcp = &mc; 6817 6818 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1200, 6819 "Entered %s\n", __func__); 6820 6821 memset(mcp->mb, 0 , sizeof(mcp->mb)); 6822 mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD; 6823 mcp->mb[1] = 1; 6824 mcp->mb[2] = value; 6825 mcp->out_mb = MBX_2 | MBX_1 | MBX_0; 6826 mcp->in_mb = MBX_2 | MBX_0; 6827 mcp->tov = MBX_TOV_SECONDS; 6828 mcp->flags = 0; 6829 6830 rval = qla2x00_mailbox_command(vha, mcp); 6831 6832 ql_dbg(ql_dbg_mbx, vha, 0x1201, "%s %x\n", 6833 (rval != QLA_SUCCESS) ? "Failed" : "Done", rval); 6834 6835 return rval; 6836} 6837 6838int qla27xx_get_zio_threshold(scsi_qla_host_t *vha, uint16_t *value) 6839{ 6840 int rval; 6841 mbx_cmd_t mc; 6842 mbx_cmd_t *mcp = &mc; 6843 6844 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1203, 6845 "Entered %s\n", __func__); 6846 6847 memset(mcp->mb, 0, sizeof(mcp->mb)); 6848 mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD; 6849 mcp->mb[1] = 0; 6850 mcp->out_mb = MBX_1 | MBX_0; 6851 mcp->in_mb = MBX_2 | MBX_0; 6852 mcp->tov = MBX_TOV_SECONDS; 6853 mcp->flags = 0; 6854 6855 rval = qla2x00_mailbox_command(vha, mcp); 6856 if (rval == QLA_SUCCESS) 6857 *value = mc.mb[2]; 6858 6859 ql_dbg(ql_dbg_mbx, vha, 0x1205, "%s %x\n", 6860 (rval != QLA_SUCCESS) ? "Failed" : "Done", rval); 6861 6862 return rval; 6863} 6864 6865int 6866qla2x00_read_sfp_dev(struct scsi_qla_host *vha, char *buf, int count) 6867{ 6868 struct qla_hw_data *ha = vha->hw; 6869 uint16_t iter, addr, offset; 6870 dma_addr_t phys_addr; 6871 int rval, c; 6872 u8 *sfp_data; 6873 6874 memset(ha->sfp_data, 0, SFP_DEV_SIZE); 6875 addr = 0xa0; 6876 phys_addr = ha->sfp_data_dma; 6877 sfp_data = ha->sfp_data; 6878 offset = c = 0; 6879 6880 for (iter = 0; iter < SFP_DEV_SIZE / SFP_BLOCK_SIZE; iter++) { 6881 if (iter == 4) { 6882 /* Skip to next device address. */ 6883 addr = 0xa2; 6884 offset = 0; 6885 } 6886 6887 rval = qla2x00_read_sfp(vha, phys_addr, sfp_data, 6888 addr, offset, SFP_BLOCK_SIZE, BIT_1); 6889 if (rval != QLA_SUCCESS) { 6890 ql_log(ql_log_warn, vha, 0x706d, 6891 "Unable to read SFP data (%x/%x/%x).\n", rval, 6892 addr, offset); 6893 6894 return rval; 6895 } 6896 6897 if (buf && (c < count)) { 6898 u16 sz; 6899 6900 if ((count - c) >= SFP_BLOCK_SIZE) 6901 sz = SFP_BLOCK_SIZE; 6902 else 6903 sz = count - c; 6904 6905 memcpy(buf, sfp_data, sz); 6906 buf += SFP_BLOCK_SIZE; 6907 c += sz; 6908 } 6909 phys_addr += SFP_BLOCK_SIZE; 6910 sfp_data += SFP_BLOCK_SIZE; 6911 offset += SFP_BLOCK_SIZE; 6912 } 6913 6914 return rval; 6915} 6916 6917int qla24xx_res_count_wait(struct scsi_qla_host *vha, 6918 uint16_t *out_mb, int out_mb_sz) 6919{ 6920 int rval = QLA_FUNCTION_FAILED; 6921 mbx_cmd_t mc; 6922 6923 if (!vha->hw->flags.fw_started) 6924 goto done; 6925 6926 memset(&mc, 0, sizeof(mc)); 6927 mc.mb[0] = MBC_GET_RESOURCE_COUNTS; 6928 6929 rval = qla24xx_send_mb_cmd(vha, &mc); 6930 if (rval != QLA_SUCCESS) { 6931 ql_dbg(ql_dbg_mbx, vha, 0xffff, 6932 "%s: fail\n", __func__); 6933 } else { 6934 if (out_mb_sz <= SIZEOF_IOCB_MB_REG) 6935 memcpy(out_mb, mc.mb, out_mb_sz); 6936 else 6937 memcpy(out_mb, mc.mb, SIZEOF_IOCB_MB_REG); 6938 6939 ql_dbg(ql_dbg_mbx, vha, 0xffff, 6940 "%s: done\n", __func__); 6941 } 6942done: 6943 return rval; 6944} 6945 6946int qla28xx_secure_flash_update(scsi_qla_host_t *vha, uint16_t opts, 6947 uint16_t region, uint32_t len, dma_addr_t sfub_dma_addr, 6948 uint32_t sfub_len) 6949{ 6950 int rval; 6951 mbx_cmd_t mc; 6952 mbx_cmd_t *mcp = &mc; 6953 6954 mcp->mb[0] = MBC_SECURE_FLASH_UPDATE; 6955 mcp->mb[1] = opts; 6956 mcp->mb[2] = region; 6957 mcp->mb[3] = MSW(len); 6958 mcp->mb[4] = LSW(len); 6959 mcp->mb[5] = MSW(sfub_dma_addr); 6960 mcp->mb[6] = LSW(sfub_dma_addr); 6961 mcp->mb[7] = MSW(MSD(sfub_dma_addr)); 6962 mcp->mb[8] = LSW(MSD(sfub_dma_addr)); 6963 mcp->mb[9] = sfub_len; 6964 mcp->out_mb = 6965 MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 6966 mcp->in_mb = MBX_2|MBX_1|MBX_0; 6967 mcp->tov = MBX_TOV_SECONDS; 6968 mcp->flags = 0; 6969 rval = qla2x00_mailbox_command(vha, mcp); 6970 6971 if (rval != QLA_SUCCESS) { 6972 ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s(%ld): failed rval 0x%x, %x %x %x", 6973 __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1], 6974 mcp->mb[2]); 6975 } 6976 6977 return rval; 6978} 6979 6980int qla2xxx_write_remote_register(scsi_qla_host_t *vha, uint32_t addr, 6981 uint32_t data) 6982{ 6983 int rval; 6984 mbx_cmd_t mc; 6985 mbx_cmd_t *mcp = &mc; 6986 6987 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, 6988 "Entered %s.\n", __func__); 6989 6990 mcp->mb[0] = MBC_WRITE_REMOTE_REG; 6991 mcp->mb[1] = LSW(addr); 6992 mcp->mb[2] = MSW(addr); 6993 mcp->mb[3] = LSW(data); 6994 mcp->mb[4] = MSW(data); 6995 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 6996 mcp->in_mb = MBX_1|MBX_0; 6997 mcp->tov = MBX_TOV_SECONDS; 6998 mcp->flags = 0; 6999 rval = qla2x00_mailbox_command(vha, mcp); 7000 7001 if (rval != QLA_SUCCESS) { 7002 ql_dbg(ql_dbg_mbx, vha, 0x10e9, 7003 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 7004 } else { 7005 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, 7006 "Done %s.\n", __func__); 7007 } 7008 7009 return rval; 7010} 7011 7012int qla2xxx_read_remote_register(scsi_qla_host_t *vha, uint32_t addr, 7013 uint32_t *data) 7014{ 7015 int rval; 7016 mbx_cmd_t mc; 7017 mbx_cmd_t *mcp = &mc; 7018 7019 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, 7020 "Entered %s.\n", __func__); 7021 7022 mcp->mb[0] = MBC_READ_REMOTE_REG; 7023 mcp->mb[1] = LSW(addr); 7024 mcp->mb[2] = MSW(addr); 7025 mcp->out_mb = MBX_2|MBX_1|MBX_0; 7026 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 7027 mcp->tov = MBX_TOV_SECONDS; 7028 mcp->flags = 0; 7029 rval = qla2x00_mailbox_command(vha, mcp); 7030 7031 *data = (uint32_t)((((uint32_t)mcp->mb[4]) << 16) | mcp->mb[3]); 7032 7033 if (rval != QLA_SUCCESS) { 7034 ql_dbg(ql_dbg_mbx, vha, 0x10e9, 7035 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 7036 } else { 7037 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, 7038 "Done %s.\n", __func__); 7039 } 7040 7041 return rval; 7042} 7043 7044int 7045ql26xx_led_config(scsi_qla_host_t *vha, uint16_t options, uint16_t *led) 7046{ 7047 struct qla_hw_data *ha = vha->hw; 7048 mbx_cmd_t mc; 7049 mbx_cmd_t *mcp = &mc; 7050 int rval; 7051 7052 if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 7053 return QLA_FUNCTION_FAILED; 7054 7055 ql_dbg(ql_dbg_mbx, vha, 0x7070, "Entered %s (options=%x).\n", 7056 __func__, options); 7057 7058 mcp->mb[0] = MBC_SET_GET_FC_LED_CONFIG; 7059 mcp->mb[1] = options; 7060 mcp->out_mb = MBX_1|MBX_0; 7061 mcp->in_mb = MBX_1|MBX_0; 7062 if (options & BIT_0) { 7063 if (options & BIT_1) { 7064 mcp->mb[2] = led[2]; 7065 mcp->out_mb |= MBX_2; 7066 } 7067 if (options & BIT_2) { 7068 mcp->mb[3] = led[0]; 7069 mcp->out_mb |= MBX_3; 7070 } 7071 if (options & BIT_3) { 7072 mcp->mb[4] = led[1]; 7073 mcp->out_mb |= MBX_4; 7074 } 7075 } else { 7076 mcp->in_mb |= MBX_4|MBX_3|MBX_2; 7077 } 7078 mcp->tov = MBX_TOV_SECONDS; 7079 mcp->flags = 0; 7080 rval = qla2x00_mailbox_command(vha, mcp); 7081 if (rval) { 7082 ql_dbg(ql_dbg_mbx, vha, 0x7071, "Failed %s %x (mb=%x,%x)\n", 7083 __func__, rval, mcp->mb[0], mcp->mb[1]); 7084 return rval; 7085 } 7086 7087 if (options & BIT_0) { 7088 ha->beacon_blink_led = 0; 7089 ql_dbg(ql_dbg_mbx, vha, 0x7072, "Done %s\n", __func__); 7090 } else { 7091 led[2] = mcp->mb[2]; 7092 led[0] = mcp->mb[3]; 7093 led[1] = mcp->mb[4]; 7094 ql_dbg(ql_dbg_mbx, vha, 0x7073, "Done %s (led=%x,%x,%x)\n", 7095 __func__, led[0], led[1], led[2]); 7096 } 7097 7098 return rval; 7099} 7100 7101/** 7102 * qla_no_op_mb(): This MB is used to check if FW is still alive and 7103 * able to generate an interrupt. Otherwise, a timeout will trigger 7104 * FW dump + reset 7105 * @vha: host adapter pointer 7106 * Return: None 7107 */ 7108void qla_no_op_mb(struct scsi_qla_host *vha) 7109{ 7110 mbx_cmd_t mc; 7111 mbx_cmd_t *mcp = &mc; 7112 int rval; 7113 7114 memset(&mc, 0, sizeof(mc)); 7115 mcp->mb[0] = 0; // noop cmd= 0 7116 mcp->out_mb = MBX_0; 7117 mcp->in_mb = MBX_0; 7118 mcp->tov = 5; 7119 mcp->flags = 0; 7120 rval = qla2x00_mailbox_command(vha, mcp); 7121 7122 if (rval) { 7123 ql_dbg(ql_dbg_async, vha, 0x7071, 7124 "Failed %s %x\n", __func__, rval); 7125 } 7126} 7127 7128int qla_mailbox_passthru(scsi_qla_host_t *vha, 7129 uint16_t *mbx_in, uint16_t *mbx_out) 7130{ 7131 mbx_cmd_t mc; 7132 mbx_cmd_t *mcp = &mc; 7133 int rval = -EINVAL; 7134 7135 memset(&mc, 0, sizeof(mc)); 7136 /* Receiving all 32 register's contents */ 7137 memcpy(&mcp->mb, (char *)mbx_in, (32 * sizeof(uint16_t))); 7138 7139 mcp->out_mb = 0xFFFFFFFF; 7140 mcp->in_mb = 0xFFFFFFFF; 7141 7142 mcp->tov = MBX_TOV_SECONDS; 7143 mcp->flags = 0; 7144 mcp->bufp = NULL; 7145 7146 rval = qla2x00_mailbox_command(vha, mcp); 7147 7148 if (rval != QLA_SUCCESS) { 7149 ql_dbg(ql_dbg_mbx, vha, 0xf0a2, 7150 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 7151 } else { 7152 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xf0a3, "Done %s.\n", 7153 __func__); 7154 /* passing all 32 register's contents */ 7155 memcpy(mbx_out, &mcp->mb, 32 * sizeof(uint16_t)); 7156 } 7157 7158 return rval; 7159}
~/
Read-only file preview.