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