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