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