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