linux/drivers/scsi/qla4xxx/ql4_mbx.c
<<
>>
Prefs
   1/*
   2 * QLogic iSCSI HBA Driver
   3 * Copyright (c)  2003-2012 QLogic Corporation
   4 *
   5 * See LICENSE.qla4xxx for copyright and licensing details.
   6 */
   7
   8#include "ql4_def.h"
   9#include "ql4_glbl.h"
  10#include "ql4_dbg.h"
  11#include "ql4_inline.h"
  12#include "ql4_version.h"
  13
  14void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
  15                            int in_count)
  16{
  17        int i;
  18
  19        /* Load all mailbox registers, except mailbox 0. */
  20        for (i = 1; i < in_count; i++)
  21                writel(mbx_cmd[i], &ha->reg->mailbox[i]);
  22
  23        /* Wakeup firmware  */
  24        writel(mbx_cmd[0], &ha->reg->mailbox[0]);
  25        readl(&ha->reg->mailbox[0]);
  26        writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
  27        readl(&ha->reg->ctrl_status);
  28}
  29
  30void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
  31{
  32        int intr_status;
  33
  34        intr_status = readl(&ha->reg->ctrl_status);
  35        if (intr_status & INTR_PENDING) {
  36                /*
  37                 * Service the interrupt.
  38                 * The ISR will save the mailbox status registers
  39                 * to a temporary storage location in the adapter structure.
  40                 */
  41                ha->mbox_status_count = out_count;
  42                ha->isp_ops->interrupt_service_routine(ha, intr_status);
  43        }
  44}
  45
  46/**
  47 * qla4xxx_is_intr_poll_mode – Are we allowed to poll for interrupts?
  48 * @ha: Pointer to host adapter structure.
  49 * @ret: 1=polling mode, 0=non-polling mode
  50 **/
  51static int qla4xxx_is_intr_poll_mode(struct scsi_qla_host *ha)
  52{
  53        int rval = 1;
  54
  55        if (is_qla8032(ha)) {
  56                if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
  57                    test_bit(AF_83XX_MBOX_INTR_ON, &ha->flags))
  58                        rval = 0;
  59        } else {
  60                if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
  61                    test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
  62                    test_bit(AF_ONLINE, &ha->flags) &&
  63                    !test_bit(AF_HA_REMOVAL, &ha->flags))
  64                        rval = 0;
  65        }
  66
  67        return rval;
  68}
  69
  70/**
  71 * qla4xxx_mailbox_command - issues mailbox commands
  72 * @ha: Pointer to host adapter structure.
  73 * @inCount: number of mailbox registers to load.
  74 * @outCount: number of mailbox registers to return.
  75 * @mbx_cmd: data pointer for mailbox in registers.
  76 * @mbx_sts: data pointer for mailbox out registers.
  77 *
  78 * This routine issue mailbox commands and waits for completion.
  79 * If outCount is 0, this routine completes successfully WITHOUT waiting
  80 * for the mailbox command to complete.
  81 **/
  82int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
  83                            uint8_t outCount, uint32_t *mbx_cmd,
  84                            uint32_t *mbx_sts)
  85{
  86        int status = QLA_ERROR;
  87        uint8_t i;
  88        u_long wait_count;
  89        unsigned long flags = 0;
  90        uint32_t dev_state;
  91
  92        /* Make sure that pointers are valid */
  93        if (!mbx_cmd || !mbx_sts) {
  94                DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
  95                              "pointer\n", ha->host_no, __func__));
  96                return status;
  97        }
  98
  99        if (is_qla40XX(ha)) {
 100                if (test_bit(AF_HA_REMOVAL, &ha->flags)) {
 101                        DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: "
 102                                          "prematurely completing mbx cmd as "
 103                                          "adapter removal detected\n",
 104                                          ha->host_no, __func__));
 105                        return status;
 106                }
 107        }
 108
 109        if ((is_aer_supported(ha)) &&
 110            (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) {
 111                DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, "
 112                    "timeout MBX Exiting.\n", ha->host_no, __func__));
 113                return status;
 114        }
 115
 116        /* Mailbox code active */
 117        wait_count = MBOX_TOV * 100;
 118
 119        while (wait_count--) {
 120                mutex_lock(&ha->mbox_sem);
 121                if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {
 122                        set_bit(AF_MBOX_COMMAND, &ha->flags);
 123                        mutex_unlock(&ha->mbox_sem);
 124                        break;
 125                }
 126                mutex_unlock(&ha->mbox_sem);
 127                if (!wait_count) {
 128                        DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n",
 129                                ha->host_no, __func__));
 130                        return status;
 131                }
 132                msleep(10);
 133        }
 134
 135        if (is_qla80XX(ha)) {
 136                if (test_bit(AF_FW_RECOVERY, &ha->flags)) {
 137                        DEBUG2(ql4_printk(KERN_WARNING, ha,
 138                                          "scsi%ld: %s: prematurely completing mbx cmd as firmware recovery detected\n",
 139                                          ha->host_no, __func__));
 140                        goto mbox_exit;
 141                }
 142                /* Do not send any mbx cmd if h/w is in failed state*/
 143                ha->isp_ops->idc_lock(ha);
 144                dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
 145                ha->isp_ops->idc_unlock(ha);
 146                if (dev_state == QLA8XXX_DEV_FAILED) {
 147                        ql4_printk(KERN_WARNING, ha,
 148                                   "scsi%ld: %s: H/W is in failed state, do not send any mailbox commands\n",
 149                                   ha->host_no, __func__);
 150                        goto mbox_exit;
 151                }
 152        }
 153
 154        spin_lock_irqsave(&ha->hardware_lock, flags);
 155
 156        ha->mbox_status_count = outCount;
 157        for (i = 0; i < outCount; i++)
 158                ha->mbox_status[i] = 0;
 159
 160        /* Queue the mailbox command to the firmware */
 161        ha->isp_ops->queue_mailbox_command(ha, mbx_cmd, inCount);
 162
 163        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 164
 165        /* Wait for completion */
 166
 167        /*
 168         * If we don't want status, don't wait for the mailbox command to
 169         * complete.  For example, MBOX_CMD_RESET_FW doesn't return status,
 170         * you must poll the inbound Interrupt Mask for completion.
 171         */
 172        if (outCount == 0) {
 173                status = QLA_SUCCESS;
 174                goto mbox_exit;
 175        }
 176
 177        /*
 178         * Wait for completion: Poll or completion queue
 179         */
 180        if (qla4xxx_is_intr_poll_mode(ha)) {
 181                /* Poll for command to complete */
 182                wait_count = jiffies + MBOX_TOV * HZ;
 183                while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
 184                        if (time_after_eq(jiffies, wait_count))
 185                                break;
 186                        /*
 187                         * Service the interrupt.
 188                         * The ISR will save the mailbox status registers
 189                         * to a temporary storage location in the adapter
 190                         * structure.
 191                         */
 192                        spin_lock_irqsave(&ha->hardware_lock, flags);
 193                        ha->isp_ops->process_mailbox_interrupt(ha, outCount);
 194                        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 195                        msleep(10);
 196                }
 197        } else {
 198                /* Do not poll for completion. Use completion queue */
 199                set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
 200                wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);
 201                clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
 202        }
 203
 204        /* Check for mailbox timeout. */
 205        if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
 206                if (is_qla80XX(ha) &&
 207                    test_bit(AF_FW_RECOVERY, &ha->flags)) {
 208                        DEBUG2(ql4_printk(KERN_INFO, ha,
 209                            "scsi%ld: %s: prematurely completing mbx cmd as "
 210                            "firmware recovery detected\n",
 211                            ha->host_no, __func__));
 212                        goto mbox_exit;
 213                }
 214                DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...,"
 215                              " Scheduling Adapter Reset\n", ha->host_no,
 216                              mbx_cmd[0]));
 217                ha->mailbox_timeout_count++;
 218                mbx_sts[0] = (-1);
 219                set_bit(DPC_RESET_HA, &ha->dpc_flags);
 220                if (is_qla8022(ha)) {
 221                        ql4_printk(KERN_INFO, ha,
 222                                   "disabling pause transmit on port 0 & 1.\n");
 223                        qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
 224                                        CRB_NIU_XG_PAUSE_CTL_P0 |
 225                                        CRB_NIU_XG_PAUSE_CTL_P1);
 226                } else if (is_qla8032(ha)) {
 227                        ql4_printk(KERN_INFO, ha, " %s: disabling pause transmit on port 0 & 1.\n",
 228                                   __func__);
 229                        qla4_83xx_disable_pause(ha);
 230                }
 231                goto mbox_exit;
 232        }
 233
 234        /*
 235         * Copy the mailbox out registers to the caller's mailbox in/out
 236         * structure.
 237         */
 238        spin_lock_irqsave(&ha->hardware_lock, flags);
 239        for (i = 0; i < outCount; i++)
 240                mbx_sts[i] = ha->mbox_status[i];
 241
 242        /* Set return status and error flags (if applicable). */
 243        switch (ha->mbox_status[0]) {
 244        case MBOX_STS_COMMAND_COMPLETE:
 245                status = QLA_SUCCESS;
 246                break;
 247
 248        case MBOX_STS_INTERMEDIATE_COMPLETION:
 249                status = QLA_SUCCESS;
 250                break;
 251
 252        case MBOX_STS_BUSY:
 253                DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n",
 254                               ha->host_no, __func__, mbx_cmd[0]));
 255                ha->mailbox_timeout_count++;
 256                break;
 257
 258        default:
 259                DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, "
 260                              "sts = %08X ****\n", ha->host_no, __func__,
 261                              mbx_cmd[0], mbx_sts[0]));
 262                break;
 263        }
 264        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 265
 266mbox_exit:
 267        mutex_lock(&ha->mbox_sem);
 268        clear_bit(AF_MBOX_COMMAND, &ha->flags);
 269        mutex_unlock(&ha->mbox_sem);
 270        clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
 271
 272        return status;
 273}
 274
 275/**
 276 * qla4xxx_get_minidump_template - Get the firmware template
 277 * @ha: Pointer to host adapter structure.
 278 * @phys_addr: dma address for template
 279 *
 280 * Obtain the minidump template from firmware during initialization
 281 * as it may not be available when minidump is desired.
 282 **/
 283int qla4xxx_get_minidump_template(struct scsi_qla_host *ha,
 284                                  dma_addr_t phys_addr)
 285{
 286        uint32_t mbox_cmd[MBOX_REG_COUNT];
 287        uint32_t mbox_sts[MBOX_REG_COUNT];
 288        int status;
 289
 290        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 291        memset(&mbox_sts, 0, sizeof(mbox_sts));
 292
 293        mbox_cmd[0] = MBOX_CMD_MINIDUMP;
 294        mbox_cmd[1] = MINIDUMP_GET_TMPLT_SUBCOMMAND;
 295        mbox_cmd[2] = LSDW(phys_addr);
 296        mbox_cmd[3] = MSDW(phys_addr);
 297        mbox_cmd[4] = ha->fw_dump_tmplt_size;
 298        mbox_cmd[5] = 0;
 299
 300        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],
 301                                         &mbox_sts[0]);
 302        if (status != QLA_SUCCESS) {
 303                DEBUG2(ql4_printk(KERN_INFO, ha,
 304                                  "scsi%ld: %s: Cmd = %08X, mbx[0] = 0x%04x, mbx[1] = 0x%04x\n",
 305                                  ha->host_no, __func__, mbox_cmd[0],
 306                                  mbox_sts[0], mbox_sts[1]));
 307        }
 308        return status;
 309}
 310
 311/**
 312 * qla4xxx_req_template_size - Get minidump template size from firmware.
 313 * @ha: Pointer to host adapter structure.
 314 **/
 315int qla4xxx_req_template_size(struct scsi_qla_host *ha)
 316{
 317        uint32_t mbox_cmd[MBOX_REG_COUNT];
 318        uint32_t mbox_sts[MBOX_REG_COUNT];
 319        int status;
 320
 321        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 322        memset(&mbox_sts, 0, sizeof(mbox_sts));
 323
 324        mbox_cmd[0] = MBOX_CMD_MINIDUMP;
 325        mbox_cmd[1] = MINIDUMP_GET_SIZE_SUBCOMMAND;
 326
 327        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
 328                                         &mbox_sts[0]);
 329        if (status == QLA_SUCCESS) {
 330                ha->fw_dump_tmplt_size = mbox_sts[1];
 331                DEBUG2(ql4_printk(KERN_INFO, ha,
 332                                  "%s: sts[0]=0x%04x, template  size=0x%04x, size_cm_02=0x%04x, size_cm_04=0x%04x, size_cm_08=0x%04x, size_cm_10=0x%04x, size_cm_FF=0x%04x, version=0x%04x\n",
 333                                  __func__, mbox_sts[0], mbox_sts[1],
 334                                  mbox_sts[2], mbox_sts[3], mbox_sts[4],
 335                                  mbox_sts[5], mbox_sts[6], mbox_sts[7]));
 336                if (ha->fw_dump_tmplt_size == 0)
 337                        status = QLA_ERROR;
 338        } else {
 339                ql4_printk(KERN_WARNING, ha,
 340                           "%s: Error sts[0]=0x%04x, mbx[1]=0x%04x\n",
 341                           __func__, mbox_sts[0], mbox_sts[1]);
 342                status = QLA_ERROR;
 343        }
 344
 345        return status;
 346}
 347
 348void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha)
 349{
 350        set_bit(AF_FW_RECOVERY, &ha->flags);
 351        ql4_printk(KERN_INFO, ha, "scsi%ld: %s: set FW RECOVERY!\n",
 352            ha->host_no, __func__);
 353
 354        if (test_bit(AF_MBOX_COMMAND, &ha->flags)) {
 355                if (test_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags)) {
 356                        complete(&ha->mbx_intr_comp);
 357                        ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw "
 358                            "recovery, doing premature completion of "
 359                            "mbx cmd\n", ha->host_no, __func__);
 360
 361                } else {
 362                        set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
 363                        ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw "
 364                            "recovery, doing premature completion of "
 365                            "polling mbx cmd\n", ha->host_no, __func__);
 366                }
 367        }
 368}
 369
 370static uint8_t
 371qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
 372                 uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
 373{
 374        memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
 375        memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
 376
 377        if (is_qla8022(ha))
 378                qla4_82xx_wr_32(ha, ha->nx_db_wr_ptr, 0);
 379
 380        mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
 381        mbox_cmd[1] = 0;
 382        mbox_cmd[2] = LSDW(init_fw_cb_dma);
 383        mbox_cmd[3] = MSDW(init_fw_cb_dma);
 384        mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
 385        mbox_cmd[5] = (IFCB_VER_MAX << 8) | IFCB_VER_MIN;
 386
 387        if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) !=
 388            QLA_SUCCESS) {
 389                DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "
 390                              "MBOX_CMD_INITIALIZE_FIRMWARE"
 391                              " failed w/ status %04X\n",
 392                              ha->host_no, __func__, mbox_sts[0]));
 393                return QLA_ERROR;
 394        }
 395        return QLA_SUCCESS;
 396}
 397
 398uint8_t
 399qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
 400                 uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
 401{
 402        memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
 403        memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
 404        mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
 405        mbox_cmd[2] = LSDW(init_fw_cb_dma);
 406        mbox_cmd[3] = MSDW(init_fw_cb_dma);
 407        mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
 408
 409        if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts) !=
 410            QLA_SUCCESS) {
 411                DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "
 412                              "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK"
 413                              " failed w/ status %04X\n",
 414                              ha->host_no, __func__, mbox_sts[0]));
 415                return QLA_ERROR;
 416        }
 417        return QLA_SUCCESS;
 418}
 419
 420static void
 421qla4xxx_update_local_ip(struct scsi_qla_host *ha,
 422                        struct addr_ctrl_blk *init_fw_cb)
 423{
 424        ha->ip_config.tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts);
 425        ha->ip_config.ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts);
 426        ha->ip_config.ipv4_addr_state =
 427                                le16_to_cpu(init_fw_cb->ipv4_addr_state);
 428        ha->ip_config.eth_mtu_size =
 429                                le16_to_cpu(init_fw_cb->eth_mtu_size);
 430        ha->ip_config.ipv4_port = le16_to_cpu(init_fw_cb->ipv4_port);
 431
 432        if (ha->acb_version == ACB_SUPPORTED) {
 433                ha->ip_config.ipv6_options = le16_to_cpu(init_fw_cb->ipv6_opts);
 434                ha->ip_config.ipv6_addl_options =
 435                                le16_to_cpu(init_fw_cb->ipv6_addtl_opts);
 436        }
 437
 438        /* Save IPv4 Address Info */
 439        memcpy(ha->ip_config.ip_address, init_fw_cb->ipv4_addr,
 440               min(sizeof(ha->ip_config.ip_address),
 441                   sizeof(init_fw_cb->ipv4_addr)));
 442        memcpy(ha->ip_config.subnet_mask, init_fw_cb->ipv4_subnet,
 443               min(sizeof(ha->ip_config.subnet_mask),
 444                   sizeof(init_fw_cb->ipv4_subnet)));
 445        memcpy(ha->ip_config.gateway, init_fw_cb->ipv4_gw_addr,
 446               min(sizeof(ha->ip_config.gateway),
 447                   sizeof(init_fw_cb->ipv4_gw_addr)));
 448
 449        ha->ip_config.ipv4_vlan_tag = be16_to_cpu(init_fw_cb->ipv4_vlan_tag);
 450
 451        if (is_ipv6_enabled(ha)) {
 452                /* Save IPv6 Address */
 453                ha->ip_config.ipv6_link_local_state =
 454                        le16_to_cpu(init_fw_cb->ipv6_lnk_lcl_addr_state);
 455                ha->ip_config.ipv6_addr0_state =
 456                                le16_to_cpu(init_fw_cb->ipv6_addr0_state);
 457                ha->ip_config.ipv6_addr1_state =
 458                                le16_to_cpu(init_fw_cb->ipv6_addr1_state);
 459                ha->ip_config.ipv6_default_router_state =
 460                                le16_to_cpu(init_fw_cb->ipv6_dflt_rtr_state);
 461                ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE;
 462                ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80;
 463
 464                memcpy(&ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[8],
 465                       init_fw_cb->ipv6_if_id,
 466                       min(sizeof(ha->ip_config.ipv6_link_local_addr)/2,
 467                           sizeof(init_fw_cb->ipv6_if_id)));
 468                memcpy(&ha->ip_config.ipv6_addr0, init_fw_cb->ipv6_addr0,
 469                       min(sizeof(ha->ip_config.ipv6_addr0),
 470                           sizeof(init_fw_cb->ipv6_addr0)));
 471                memcpy(&ha->ip_config.ipv6_addr1, init_fw_cb->ipv6_addr1,
 472                       min(sizeof(ha->ip_config.ipv6_addr1),
 473                           sizeof(init_fw_cb->ipv6_addr1)));
 474                memcpy(&ha->ip_config.ipv6_default_router_addr,
 475                       init_fw_cb->ipv6_dflt_rtr_addr,
 476                       min(sizeof(ha->ip_config.ipv6_default_router_addr),
 477                           sizeof(init_fw_cb->ipv6_dflt_rtr_addr)));
 478                ha->ip_config.ipv6_vlan_tag =
 479                                be16_to_cpu(init_fw_cb->ipv6_vlan_tag);
 480                ha->ip_config.ipv6_port = le16_to_cpu(init_fw_cb->ipv6_port);
 481        }
 482}
 483
 484uint8_t
 485qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
 486                          uint32_t *mbox_cmd,
 487                          uint32_t *mbox_sts,
 488                          struct addr_ctrl_blk  *init_fw_cb,
 489                          dma_addr_t init_fw_cb_dma)
 490{
 491        if (qla4xxx_get_ifcb(ha, mbox_cmd, mbox_sts, init_fw_cb_dma)
 492            != QLA_SUCCESS) {
 493                DEBUG2(printk(KERN_WARNING
 494                              "scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
 495                              ha->host_no, __func__));
 496                return QLA_ERROR;
 497        }
 498
 499        DEBUG2(qla4xxx_dump_buffer(init_fw_cb, sizeof(struct addr_ctrl_blk)));
 500
 501        /* Save some info in adapter structure. */
 502        ha->acb_version = init_fw_cb->acb_version;
 503        ha->firmware_options = le16_to_cpu(init_fw_cb->fw_options);
 504        ha->heartbeat_interval = init_fw_cb->hb_interval;
 505        memcpy(ha->name_string, init_fw_cb->iscsi_name,
 506                min(sizeof(ha->name_string),
 507                sizeof(init_fw_cb->iscsi_name)));
 508        ha->def_timeout = le16_to_cpu(init_fw_cb->def_timeout);
 509        /*memcpy(ha->alias, init_fw_cb->Alias,
 510               min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/
 511
 512        qla4xxx_update_local_ip(ha, init_fw_cb);
 513
 514        return QLA_SUCCESS;
 515}
 516
 517/**
 518 * qla4xxx_initialize_fw_cb - initializes firmware control block.
 519 * @ha: Pointer to host adapter structure.
 520 **/
 521int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
 522{
 523        struct addr_ctrl_blk *init_fw_cb;
 524        dma_addr_t init_fw_cb_dma;
 525        uint32_t mbox_cmd[MBOX_REG_COUNT];
 526        uint32_t mbox_sts[MBOX_REG_COUNT];
 527        int status = QLA_ERROR;
 528
 529        init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
 530                                        sizeof(struct addr_ctrl_blk),
 531                                        &init_fw_cb_dma, GFP_KERNEL);
 532        if (init_fw_cb == NULL) {
 533                DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n",
 534                              ha->host_no, __func__));
 535                goto exit_init_fw_cb_no_free;
 536        }
 537        memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
 538
 539        /* Get Initialize Firmware Control Block. */
 540        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 541        memset(&mbox_sts, 0, sizeof(mbox_sts));
 542
 543        if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=
 544            QLA_SUCCESS) {
 545                dma_free_coherent(&ha->pdev->dev,
 546                                  sizeof(struct addr_ctrl_blk),
 547                                  init_fw_cb, init_fw_cb_dma);
 548                goto exit_init_fw_cb;
 549        }
 550
 551        /* Initialize request and response queues. */
 552        qla4xxx_init_rings(ha);
 553
 554        /* Fill in the request and response queue information. */
 555        init_fw_cb->rqq_consumer_idx = cpu_to_le16(ha->request_out);
 556        init_fw_cb->compq_producer_idx = cpu_to_le16(ha->response_in);
 557        init_fw_cb->rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
 558        init_fw_cb->compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
 559        init_fw_cb->rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma));
 560        init_fw_cb->rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma));
 561        init_fw_cb->compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma));
 562        init_fw_cb->compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma));
 563        init_fw_cb->shdwreg_addr_lo = cpu_to_le32(LSDW(ha->shadow_regs_dma));
 564        init_fw_cb->shdwreg_addr_hi = cpu_to_le32(MSDW(ha->shadow_regs_dma));
 565
 566        /* Set up required options. */
 567        init_fw_cb->fw_options |=
 568                __constant_cpu_to_le16(FWOPT_SESSION_MODE |
 569                                       FWOPT_INITIATOR_MODE);
 570
 571        if (is_qla80XX(ha))
 572                init_fw_cb->fw_options |=
 573                    __constant_cpu_to_le16(FWOPT_ENABLE_CRBDB);
 574
 575        init_fw_cb->fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
 576
 577        init_fw_cb->add_fw_options = 0;
 578        init_fw_cb->add_fw_options |=
 579                        __constant_cpu_to_le16(ADFWOPT_SERIALIZE_TASK_MGMT);
 580        init_fw_cb->add_fw_options |=
 581                        __constant_cpu_to_le16(ADFWOPT_AUTOCONN_DISABLE);
 582
 583        if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma)
 584                != QLA_SUCCESS) {
 585                DEBUG2(printk(KERN_WARNING
 586                              "scsi%ld: %s: Failed to set init_fw_ctrl_blk\n",
 587                              ha->host_no, __func__));
 588                goto exit_init_fw_cb;
 589        }
 590
 591        if (qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0],
 592                init_fw_cb, init_fw_cb_dma) != QLA_SUCCESS) {
 593                DEBUG2(printk("scsi%ld: %s: Failed to update local ifcb\n",
 594                                ha->host_no, __func__));
 595                goto exit_init_fw_cb;
 596        }
 597        status = QLA_SUCCESS;
 598
 599exit_init_fw_cb:
 600        dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
 601                                init_fw_cb, init_fw_cb_dma);
 602exit_init_fw_cb_no_free:
 603        return status;
 604}
 605
 606/**
 607 * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP
 608 * @ha: Pointer to host adapter structure.
 609 **/
 610int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
 611{
 612        struct addr_ctrl_blk *init_fw_cb;
 613        dma_addr_t init_fw_cb_dma;
 614        uint32_t mbox_cmd[MBOX_REG_COUNT];
 615        uint32_t mbox_sts[MBOX_REG_COUNT];
 616
 617        init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
 618                                        sizeof(struct addr_ctrl_blk),
 619                                        &init_fw_cb_dma, GFP_KERNEL);
 620        if (init_fw_cb == NULL) {
 621                printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no,
 622                       __func__);
 623                return QLA_ERROR;
 624        }
 625
 626        /* Get Initialize Firmware Control Block. */
 627        memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
 628        if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=
 629            QLA_SUCCESS) {
 630                DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
 631                              ha->host_no, __func__));
 632                dma_free_coherent(&ha->pdev->dev,
 633                                  sizeof(struct addr_ctrl_blk),
 634                                  init_fw_cb, init_fw_cb_dma);
 635                return QLA_ERROR;
 636        }
 637
 638        /* Save IP Address. */
 639        qla4xxx_update_local_ip(ha, init_fw_cb);
 640        dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
 641                                init_fw_cb, init_fw_cb_dma);
 642
 643        return QLA_SUCCESS;
 644}
 645
 646/**
 647 * qla4xxx_get_firmware_state - gets firmware state of HBA
 648 * @ha: Pointer to host adapter structure.
 649 **/
 650int qla4xxx_get_firmware_state(struct scsi_qla_host * ha)
 651{
 652        uint32_t mbox_cmd[MBOX_REG_COUNT];
 653        uint32_t mbox_sts[MBOX_REG_COUNT];
 654
 655        /* Get firmware version */
 656        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 657        memset(&mbox_sts, 0, sizeof(mbox_sts));
 658
 659        mbox_cmd[0] = MBOX_CMD_GET_FW_STATE;
 660
 661        if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) !=
 662            QLA_SUCCESS) {
 663                DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ "
 664                              "status %04X\n", ha->host_no, __func__,
 665                              mbox_sts[0]));
 666                return QLA_ERROR;
 667        }
 668        ha->firmware_state = mbox_sts[1];
 669        ha->board_id = mbox_sts[2];
 670        ha->addl_fw_state = mbox_sts[3];
 671        DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n",
 672                      ha->host_no, __func__, ha->firmware_state);)
 673
 674        return QLA_SUCCESS;
 675}
 676
 677/**
 678 * qla4xxx_get_firmware_status - retrieves firmware status
 679 * @ha: Pointer to host adapter structure.
 680 **/
 681int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
 682{
 683        uint32_t mbox_cmd[MBOX_REG_COUNT];
 684        uint32_t mbox_sts[MBOX_REG_COUNT];
 685
 686        /* Get firmware version */
 687        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 688        memset(&mbox_sts, 0, sizeof(mbox_sts));
 689
 690        mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS;
 691
 692        if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
 693            QLA_SUCCESS) {
 694                DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ "
 695                              "status %04X\n", ha->host_no, __func__,
 696                              mbox_sts[0]));
 697                return QLA_ERROR;
 698        }
 699
 700        /* High-water mark of IOCBs */
 701        ha->iocb_hiwat = mbox_sts[2];
 702        DEBUG2(ql4_printk(KERN_INFO, ha,
 703                          "%s: firmware IOCBs available = %d\n", __func__,
 704                          ha->iocb_hiwat));
 705
 706        if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION)
 707                ha->iocb_hiwat -= IOCB_HIWAT_CUSHION;
 708
 709        /* Ideally, we should not enter this code, as the # of firmware
 710         * IOCBs is hard-coded in the firmware. We set a default
 711         * iocb_hiwat here just in case */
 712        if (ha->iocb_hiwat == 0) {
 713                ha->iocb_hiwat = REQUEST_QUEUE_DEPTH / 4;
 714                DEBUG2(ql4_printk(KERN_WARNING, ha,
 715                                  "%s: Setting IOCB's to = %d\n", __func__,
 716                                  ha->iocb_hiwat));
 717        }
 718
 719        return QLA_SUCCESS;
 720}
 721
 722/**
 723 * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry
 724 * @ha: Pointer to host adapter structure.
 725 * @fw_ddb_index: Firmware's device database index
 726 * @fw_ddb_entry: Pointer to firmware's device database entry structure
 727 * @num_valid_ddb_entries: Pointer to number of valid ddb entries
 728 * @next_ddb_index: Pointer to next valid device database index
 729 * @fw_ddb_device_state: Pointer to device state
 730 **/
 731int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
 732                            uint16_t fw_ddb_index,
 733                            struct dev_db_entry *fw_ddb_entry,
 734                            dma_addr_t fw_ddb_entry_dma,
 735                            uint32_t *num_valid_ddb_entries,
 736                            uint32_t *next_ddb_index,
 737                            uint32_t *fw_ddb_device_state,
 738                            uint32_t *conn_err_detail,
 739                            uint16_t *tcp_source_port_num,
 740                            uint16_t *connection_id)
 741{
 742        int status = QLA_ERROR;
 743        uint16_t options;
 744        uint32_t mbox_cmd[MBOX_REG_COUNT];
 745        uint32_t mbox_sts[MBOX_REG_COUNT];
 746
 747        /* Make sure the device index is valid */
 748        if (fw_ddb_index >= MAX_DDB_ENTRIES) {
 749                DEBUG2(printk("scsi%ld: %s: ddb [%d] out of range.\n",
 750                              ha->host_no, __func__, fw_ddb_index));
 751                goto exit_get_fwddb;
 752        }
 753        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 754        memset(&mbox_sts, 0, sizeof(mbox_sts));
 755        if (fw_ddb_entry)
 756                memset(fw_ddb_entry, 0, sizeof(struct dev_db_entry));
 757
 758        mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
 759        mbox_cmd[1] = (uint32_t) fw_ddb_index;
 760        mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
 761        mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
 762        mbox_cmd[4] = sizeof(struct dev_db_entry);
 763
 764        if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) ==
 765            QLA_ERROR) {
 766                DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"
 767                              " with status 0x%04X\n", ha->host_no, __func__,
 768                              mbox_sts[0]));
 769                goto exit_get_fwddb;
 770        }
 771        if (fw_ddb_index != mbox_sts[1]) {
 772                DEBUG2(printk("scsi%ld: %s: ddb mismatch [%d] != [%d].\n",
 773                              ha->host_no, __func__, fw_ddb_index,
 774                              mbox_sts[1]));
 775                goto exit_get_fwddb;
 776        }
 777        if (fw_ddb_entry) {
 778                options = le16_to_cpu(fw_ddb_entry->options);
 779                if (options & DDB_OPT_IPV6_DEVICE) {
 780                        ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d "
 781                                "Next %d State %04x ConnErr %08x %pI6 "
 782                                ":%04d \"%s\"\n", __func__, fw_ddb_index,
 783                                mbox_sts[0], mbox_sts[2], mbox_sts[3],
 784                                mbox_sts[4], mbox_sts[5],
 785                                fw_ddb_entry->ip_addr,
 786                                le16_to_cpu(fw_ddb_entry->port),
 787                                fw_ddb_entry->iscsi_name);
 788                } else {
 789                        ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d "
 790                                "Next %d State %04x ConnErr %08x %pI4 "
 791                                ":%04d \"%s\"\n", __func__, fw_ddb_index,
 792                                mbox_sts[0], mbox_sts[2], mbox_sts[3],
 793                                mbox_sts[4], mbox_sts[5],
 794                                fw_ddb_entry->ip_addr,
 795                                le16_to_cpu(fw_ddb_entry->port),
 796                                fw_ddb_entry->iscsi_name);
 797                }
 798        }
 799        if (num_valid_ddb_entries)
 800                *num_valid_ddb_entries = mbox_sts[2];
 801        if (next_ddb_index)
 802                *next_ddb_index = mbox_sts[3];
 803        if (fw_ddb_device_state)
 804                *fw_ddb_device_state = mbox_sts[4];
 805
 806        /*
 807         * RA: This mailbox has been changed to pass connection error and
 808         * details.  Its true for ISP4010 as per Version E - Not sure when it
 809         * was changed.  Get the time2wait from the fw_dd_entry field :
 810         * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY
 811         * struct.
 812         */
 813        if (conn_err_detail)
 814                *conn_err_detail = mbox_sts[5];
 815        if (tcp_source_port_num)
 816                *tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16);
 817        if (connection_id)
 818                *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
 819        status = QLA_SUCCESS;
 820
 821exit_get_fwddb:
 822        return status;
 823}
 824
 825int qla4xxx_conn_open(struct scsi_qla_host *ha, uint16_t fw_ddb_index)
 826{
 827        uint32_t mbox_cmd[MBOX_REG_COUNT];
 828        uint32_t mbox_sts[MBOX_REG_COUNT];
 829        int status;
 830
 831        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 832        memset(&mbox_sts, 0, sizeof(mbox_sts));
 833
 834        mbox_cmd[0] = MBOX_CMD_CONN_OPEN;
 835        mbox_cmd[1] = fw_ddb_index;
 836
 837        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],
 838                                         &mbox_sts[0]);
 839        DEBUG2(ql4_printk(KERN_INFO, ha,
 840                          "%s: status = %d mbx0 = 0x%x mbx1 = 0x%x\n",
 841                          __func__, status, mbox_sts[0], mbox_sts[1]));
 842        return status;
 843}
 844
 845/**
 846 * qla4xxx_set_fwddb_entry - sets a ddb entry.
 847 * @ha: Pointer to host adapter structure.
 848 * @fw_ddb_index: Firmware's device database index
 849 * @fw_ddb_entry_dma: dma address of ddb entry
 850 * @mbx_sts: mailbox 0 to be returned or NULL
 851 *
 852 * This routine initializes or updates the adapter's device database
 853 * entry for the specified device.
 854 **/
 855int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
 856                          dma_addr_t fw_ddb_entry_dma, uint32_t *mbx_sts)
 857{
 858        uint32_t mbox_cmd[MBOX_REG_COUNT];
 859        uint32_t mbox_sts[MBOX_REG_COUNT];
 860        int status;
 861
 862        /* Do not wait for completion. The firmware will send us an
 863         * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
 864         */
 865        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 866        memset(&mbox_sts, 0, sizeof(mbox_sts));
 867
 868        mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY;
 869        mbox_cmd[1] = (uint32_t) fw_ddb_index;
 870        mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
 871        mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
 872        mbox_cmd[4] = sizeof(struct dev_db_entry);
 873
 874        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0],
 875                                         &mbox_sts[0]);
 876        if (mbx_sts)
 877                *mbx_sts = mbox_sts[0];
 878        DEBUG2(printk("scsi%ld: %s: status=%d mbx0=0x%x mbx4=0x%x\n",
 879            ha->host_no, __func__, status, mbox_sts[0], mbox_sts[4]);)
 880
 881        return status;
 882}
 883
 884int qla4xxx_session_logout_ddb(struct scsi_qla_host *ha,
 885                               struct ddb_entry *ddb_entry, int options)
 886{
 887        int status;
 888        uint32_t mbox_cmd[MBOX_REG_COUNT];
 889        uint32_t mbox_sts[MBOX_REG_COUNT];
 890
 891        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 892        memset(&mbox_sts, 0, sizeof(mbox_sts));
 893
 894        mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;
 895        mbox_cmd[1] = ddb_entry->fw_ddb_index;
 896        mbox_cmd[3] = options;
 897
 898        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],
 899                                         &mbox_sts[0]);
 900        if (status != QLA_SUCCESS) {
 901                DEBUG2(ql4_printk(KERN_INFO, ha,
 902                                  "%s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT "
 903                                  "failed sts %04X %04X", __func__,
 904                                  mbox_sts[0], mbox_sts[1]));
 905        }
 906
 907        return status;
 908}
 909
 910/**
 911 * qla4xxx_get_crash_record - retrieves crash record.
 912 * @ha: Pointer to host adapter structure.
 913 *
 914 * This routine retrieves a crash record from the QLA4010 after an 8002h aen.
 915 **/
 916void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
 917{
 918        uint32_t mbox_cmd[MBOX_REG_COUNT];
 919        uint32_t mbox_sts[MBOX_REG_COUNT];
 920        struct crash_record *crash_record = NULL;
 921        dma_addr_t crash_record_dma = 0;
 922        uint32_t crash_record_size = 0;
 923
 924        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 925        memset(&mbox_sts, 0, sizeof(mbox_cmd));
 926
 927        /* Get size of crash record. */
 928        mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
 929
 930        if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
 931            QLA_SUCCESS) {
 932                DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",
 933                              ha->host_no, __func__));
 934                goto exit_get_crash_record;
 935        }
 936        crash_record_size = mbox_sts[4];
 937        if (crash_record_size == 0) {
 938                DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n",
 939                              ha->host_no, __func__));
 940                goto exit_get_crash_record;
 941        }
 942
 943        /* Alloc Memory for Crash Record. */
 944        crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size,
 945                                          &crash_record_dma, GFP_KERNEL);
 946        if (crash_record == NULL)
 947                goto exit_get_crash_record;
 948
 949        /* Get Crash Record. */
 950        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 951        memset(&mbox_sts, 0, sizeof(mbox_cmd));
 952
 953        mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
 954        mbox_cmd[2] = LSDW(crash_record_dma);
 955        mbox_cmd[3] = MSDW(crash_record_dma);
 956        mbox_cmd[4] = crash_record_size;
 957
 958        if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
 959            QLA_SUCCESS)
 960                goto exit_get_crash_record;
 961
 962        /* Dump Crash Record. */
 963
 964exit_get_crash_record:
 965        if (crash_record)
 966                dma_free_coherent(&ha->pdev->dev, crash_record_size,
 967                                  crash_record, crash_record_dma);
 968}
 969
 970/**
 971 * qla4xxx_get_conn_event_log - retrieves connection event log
 972 * @ha: Pointer to host adapter structure.
 973 **/
 974void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
 975{
 976        uint32_t mbox_cmd[MBOX_REG_COUNT];
 977        uint32_t mbox_sts[MBOX_REG_COUNT];
 978        struct conn_event_log_entry *event_log = NULL;
 979        dma_addr_t event_log_dma = 0;
 980        uint32_t event_log_size = 0;
 981        uint32_t num_valid_entries;
 982        uint32_t      oldest_entry = 0;
 983        uint32_t        max_event_log_entries;
 984        uint8_t         i;
 985
 986        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 987        memset(&mbox_sts, 0, sizeof(mbox_cmd));
 988
 989        /* Get size of crash record. */
 990        mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
 991
 992        if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
 993            QLA_SUCCESS)
 994                goto exit_get_event_log;
 995
 996        event_log_size = mbox_sts[4];
 997        if (event_log_size == 0)
 998                goto exit_get_event_log;
 999
1000        /* Alloc Memory for Crash Record. */
1001        event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size,
1002                                       &event_log_dma, GFP_KERNEL);
1003        if (event_log == NULL)
1004                goto exit_get_event_log;
1005
1006        /* Get Crash Record. */
1007        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1008        memset(&mbox_sts, 0, sizeof(mbox_cmd));
1009
1010        mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
1011        mbox_cmd[2] = LSDW(event_log_dma);
1012        mbox_cmd[3] = MSDW(event_log_dma);
1013
1014        if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
1015            QLA_SUCCESS) {
1016                DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "
1017                              "log!\n", ha->host_no, __func__));
1018                goto exit_get_event_log;
1019        }
1020
1021        /* Dump Event Log. */
1022        num_valid_entries = mbox_sts[1];
1023
1024        max_event_log_entries = event_log_size /
1025                sizeof(struct conn_event_log_entry);
1026
1027        if (num_valid_entries > max_event_log_entries)
1028                oldest_entry = num_valid_entries % max_event_log_entries;
1029
1030        DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
1031                      ha->host_no, num_valid_entries));
1032
1033        if (ql4xextended_error_logging == 3) {
1034                if (oldest_entry == 0) {
1035                        /* Circular Buffer has not wrapped around */
1036                        for (i=0; i < num_valid_entries; i++) {
1037                                qla4xxx_dump_buffer((uint8_t *)event_log+
1038                                                    (i*sizeof(*event_log)),
1039                                                    sizeof(*event_log));
1040                        }
1041                }
1042                else {
1043                        /* Circular Buffer has wrapped around -
1044                         * display accordingly*/
1045                        for (i=oldest_entry; i < max_event_log_entries; i++) {
1046                                qla4xxx_dump_buffer((uint8_t *)event_log+
1047                                                    (i*sizeof(*event_log)),
1048                                                    sizeof(*event_log));
1049                        }
1050                        for (i=0; i < oldest_entry; i++) {
1051                                qla4xxx_dump_buffer((uint8_t *)event_log+
1052                                                    (i*sizeof(*event_log)),
1053                                                    sizeof(*event_log));
1054                        }
1055                }
1056        }
1057
1058exit_get_event_log:
1059        if (event_log)
1060                dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,
1061                                  event_log_dma);
1062}
1063
1064/**
1065 * qla4xxx_abort_task - issues Abort Task
1066 * @ha: Pointer to host adapter structure.
1067 * @srb: Pointer to srb entry
1068 *
1069 * This routine performs a LUN RESET on the specified target/lun.
1070 * The caller must ensure that the ddb_entry and lun_entry pointers
1071 * are valid before calling this routine.
1072 **/
1073int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb)
1074{
1075        uint32_t mbox_cmd[MBOX_REG_COUNT];
1076        uint32_t mbox_sts[MBOX_REG_COUNT];
1077        struct scsi_cmnd *cmd = srb->cmd;
1078        int status = QLA_SUCCESS;
1079        unsigned long flags = 0;
1080        uint32_t index;
1081
1082        /*
1083         * Send abort task command to ISP, so that the ISP will return
1084         * request with ABORT status
1085         */
1086        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1087        memset(&mbox_sts, 0, sizeof(mbox_sts));
1088
1089        spin_lock_irqsave(&ha->hardware_lock, flags);
1090        index = (unsigned long)(unsigned char *)cmd->host_scribble;
1091        spin_unlock_irqrestore(&ha->hardware_lock, flags);
1092
1093        /* Firmware already posted completion on response queue */
1094        if (index == MAX_SRBS)
1095                return status;
1096
1097        mbox_cmd[0] = MBOX_CMD_ABORT_TASK;
1098        mbox_cmd[1] = srb->ddb->fw_ddb_index;
1099        mbox_cmd[2] = index;
1100        /* Immediate Command Enable */
1101        mbox_cmd[5] = 0x01;
1102
1103        qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0],
1104            &mbox_sts[0]);
1105        if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE) {
1106                status = QLA_ERROR;
1107
1108                DEBUG2(printk(KERN_WARNING "scsi%ld:%d:%d: abort task FAILED: "
1109                    "mbx0=%04X, mb1=%04X, mb2=%04X, mb3=%04X, mb4=%04X\n",
1110                    ha->host_no, cmd->device->id, cmd->device->lun, mbox_sts[0],
1111                    mbox_sts[1], mbox_sts[2], mbox_sts[3], mbox_sts[4]));
1112        }
1113
1114        return status;
1115}
1116
1117/**
1118 * qla4xxx_reset_lun - issues LUN Reset
1119 * @ha: Pointer to host adapter structure.
1120 * @ddb_entry: Pointer to device database entry
1121 * @lun: lun number
1122 *
1123 * This routine performs a LUN RESET on the specified target/lun.
1124 * The caller must ensure that the ddb_entry and lun_entry pointers
1125 * are valid before calling this routine.
1126 **/
1127int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
1128                      int lun)
1129{
1130        uint32_t mbox_cmd[MBOX_REG_COUNT];
1131        uint32_t mbox_sts[MBOX_REG_COUNT];
1132        uint32_t scsi_lun[2];
1133        int status = QLA_SUCCESS;
1134
1135        DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no,
1136                      ddb_entry->fw_ddb_index, lun));
1137
1138        /*
1139         * Send lun reset command to ISP, so that the ISP will return all
1140         * outstanding requests with RESET status
1141         */
1142        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1143        memset(&mbox_sts, 0, sizeof(mbox_sts));
1144        int_to_scsilun(lun, (struct scsi_lun *) scsi_lun);
1145
1146        mbox_cmd[0] = MBOX_CMD_LUN_RESET;
1147        mbox_cmd[1] = ddb_entry->fw_ddb_index;
1148        /* FW expects LUN bytes 0-3 in Incoming Mailbox 2
1149         * (LUN byte 0 is LSByte, byte 3 is MSByte) */
1150        mbox_cmd[2] = cpu_to_le32(scsi_lun[0]);
1151        /* FW expects LUN bytes 4-7 in Incoming Mailbox 3
1152         * (LUN byte 4 is LSByte, byte 7 is MSByte) */
1153        mbox_cmd[3] = cpu_to_le32(scsi_lun[1]);
1154        mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
1155
1156        qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
1157        if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
1158            mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
1159                status = QLA_ERROR;
1160
1161        return status;
1162}
1163
1164/**
1165 * qla4xxx_reset_target - issues target Reset
1166 * @ha: Pointer to host adapter structure.
1167 * @db_entry: Pointer to device database entry
1168 * @un_entry: Pointer to lun entry structure
1169 *
1170 * This routine performs a TARGET RESET on the specified target.
1171 * The caller must ensure that the ddb_entry pointers
1172 * are valid before calling this routine.
1173 **/
1174int qla4xxx_reset_target(struct scsi_qla_host *ha,
1175                         struct ddb_entry *ddb_entry)
1176{
1177        uint32_t mbox_cmd[MBOX_REG_COUNT];
1178        uint32_t mbox_sts[MBOX_REG_COUNT];
1179        int status = QLA_SUCCESS;
1180
1181        DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no,
1182                      ddb_entry->fw_ddb_index));
1183
1184        /*
1185         * Send target reset command to ISP, so that the ISP will return all
1186         * outstanding requests with RESET status
1187         */
1188        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1189        memset(&mbox_sts, 0, sizeof(mbox_sts));
1190
1191        mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET;
1192        mbox_cmd[1] = ddb_entry->fw_ddb_index;
1193        mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
1194
1195        qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
1196                                &mbox_sts[0]);
1197        if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
1198            mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
1199                status = QLA_ERROR;
1200
1201        return status;
1202}
1203
1204int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
1205                      uint32_t offset, uint32_t len)
1206{
1207        uint32_t mbox_cmd[MBOX_REG_COUNT];
1208        uint32_t mbox_sts[MBOX_REG_COUNT];
1209
1210        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1211        memset(&mbox_sts, 0, sizeof(mbox_sts));
1212
1213        mbox_cmd[0] = MBOX_CMD_READ_FLASH;
1214        mbox_cmd[1] = LSDW(dma_addr);
1215        mbox_cmd[2] = MSDW(dma_addr);
1216        mbox_cmd[3] = offset;
1217        mbox_cmd[4] = len;
1218
1219        if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) !=
1220            QLA_SUCCESS) {
1221                DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "
1222                    "status %04X %04X, offset %08x, len %08x\n", ha->host_no,
1223                    __func__, mbox_sts[0], mbox_sts[1], offset, len));
1224                return QLA_ERROR;
1225        }
1226        return QLA_SUCCESS;
1227}
1228
1229/**
1230 * qla4xxx_about_firmware - gets FW, iscsi draft and boot loader version
1231 * @ha: Pointer to host adapter structure.
1232 *
1233 * Retrieves the FW version, iSCSI draft version & bootloader version of HBA.
1234 * Mailboxes 2 & 3 may hold an address for data. Make sure that we write 0 to
1235 * those mailboxes, if unused.
1236 **/
1237int qla4xxx_about_firmware(struct scsi_qla_host *ha)
1238{
1239        struct about_fw_info *about_fw = NULL;
1240        dma_addr_t about_fw_dma;
1241        uint32_t mbox_cmd[MBOX_REG_COUNT];
1242        uint32_t mbox_sts[MBOX_REG_COUNT];
1243        int status = QLA_ERROR;
1244
1245        about_fw = dma_alloc_coherent(&ha->pdev->dev,
1246                                      sizeof(struct about_fw_info),
1247                                      &about_fw_dma, GFP_KERNEL);
1248        if (!about_fw) {
1249                DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Unable to alloc memory "
1250                                  "for about_fw\n", __func__));
1251                return status;
1252        }
1253
1254        memset(about_fw, 0, sizeof(struct about_fw_info));
1255        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1256        memset(&mbox_sts, 0, sizeof(mbox_sts));
1257
1258        mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
1259        mbox_cmd[2] = LSDW(about_fw_dma);
1260        mbox_cmd[3] = MSDW(about_fw_dma);
1261        mbox_cmd[4] = sizeof(struct about_fw_info);
1262
1263        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,
1264                                         &mbox_cmd[0], &mbox_sts[0]);
1265        if (status != QLA_SUCCESS) {
1266                DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_ABOUT_FW "
1267                                  "failed w/ status %04X\n", __func__,
1268                                  mbox_sts[0]));
1269                goto exit_about_fw;
1270        }
1271
1272        /* Save version information. */
1273        ha->firmware_version[0] = le16_to_cpu(about_fw->fw_major);
1274        ha->firmware_version[1] = le16_to_cpu(about_fw->fw_minor);
1275        ha->patch_number = le16_to_cpu(about_fw->fw_patch);
1276        ha->build_number = le16_to_cpu(about_fw->fw_build);
1277        ha->iscsi_major = le16_to_cpu(about_fw->iscsi_major);
1278        ha->iscsi_minor = le16_to_cpu(about_fw->iscsi_minor);
1279        ha->bootload_major = le16_to_cpu(about_fw->bootload_major);
1280        ha->bootload_minor = le16_to_cpu(about_fw->bootload_minor);
1281        ha->bootload_patch = le16_to_cpu(about_fw->bootload_patch);
1282        ha->bootload_build = le16_to_cpu(about_fw->bootload_build);
1283        status = QLA_SUCCESS;
1284
1285exit_about_fw:
1286        dma_free_coherent(&ha->pdev->dev, sizeof(struct about_fw_info),
1287                          about_fw, about_fw_dma);
1288        return status;
1289}
1290
1291int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
1292                            dma_addr_t dma_addr)
1293{
1294        uint32_t mbox_cmd[MBOX_REG_COUNT];
1295        uint32_t mbox_sts[MBOX_REG_COUNT];
1296
1297        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1298        memset(&mbox_sts, 0, sizeof(mbox_sts));
1299
1300        mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS;
1301        mbox_cmd[1] = options;
1302        mbox_cmd[2] = LSDW(dma_addr);
1303        mbox_cmd[3] = MSDW(dma_addr);
1304
1305        if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
1306            QLA_SUCCESS) {
1307                DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
1308                     ha->host_no, __func__, mbox_sts[0]));
1309                return QLA_ERROR;
1310        }
1311        return QLA_SUCCESS;
1312}
1313
1314int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index,
1315                          uint32_t *mbx_sts)
1316{
1317        int status;
1318        uint32_t mbox_cmd[MBOX_REG_COUNT];
1319        uint32_t mbox_sts[MBOX_REG_COUNT];
1320
1321        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1322        memset(&mbox_sts, 0, sizeof(mbox_sts));
1323
1324        mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;
1325        mbox_cmd[1] = ddb_index;
1326
1327        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
1328                                         &mbox_sts[0]);
1329        if (status != QLA_SUCCESS) {
1330                DEBUG2(ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",
1331                                   __func__, mbox_sts[0]));
1332        }
1333
1334        *mbx_sts = mbox_sts[0];
1335        return status;
1336}
1337
1338int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index)
1339{
1340        int status;
1341        uint32_t mbox_cmd[MBOX_REG_COUNT];
1342        uint32_t mbox_sts[MBOX_REG_COUNT];
1343
1344        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1345        memset(&mbox_sts, 0, sizeof(mbox_sts));
1346
1347        mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY;
1348        mbox_cmd[1] = ddb_index;
1349
1350        status = qla4xxx_mailbox_command(ha, 2, 1, &mbox_cmd[0],
1351                                         &mbox_sts[0]);
1352        if (status != QLA_SUCCESS) {
1353                DEBUG2(ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",
1354                                   __func__, mbox_sts[0]));
1355        }
1356
1357        return status;
1358}
1359
1360int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr,
1361                      uint32_t offset, uint32_t length, uint32_t options)
1362{
1363        uint32_t mbox_cmd[MBOX_REG_COUNT];
1364        uint32_t mbox_sts[MBOX_REG_COUNT];
1365        int status = QLA_SUCCESS;
1366
1367        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1368        memset(&mbox_sts, 0, sizeof(mbox_sts));
1369
1370        mbox_cmd[0] = MBOX_CMD_WRITE_FLASH;
1371        mbox_cmd[1] = LSDW(dma_addr);
1372        mbox_cmd[2] = MSDW(dma_addr);
1373        mbox_cmd[3] = offset;
1374        mbox_cmd[4] = length;
1375        mbox_cmd[5] = options;
1376
1377        status = qla4xxx_mailbox_command(ha, 6, 2, &mbox_cmd[0], &mbox_sts[0]);
1378        if (status != QLA_SUCCESS) {
1379                DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_WRITE_FLASH "
1380                                  "failed w/ status %04X, mbx1 %04X\n",
1381                                  __func__, mbox_sts[0], mbox_sts[1]));
1382        }
1383        return status;
1384}
1385
1386int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha,
1387                            struct dev_db_entry *fw_ddb_entry,
1388                            dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index)
1389{
1390        uint32_t dev_db_start_offset = FLASH_OFFSET_DB_INFO;
1391        uint32_t dev_db_end_offset;
1392        int status = QLA_ERROR;
1393
1394        memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));
1395
1396        dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));
1397        dev_db_end_offset = FLASH_OFFSET_DB_END;
1398
1399        if (dev_db_start_offset > dev_db_end_offset) {
1400                DEBUG2(ql4_printk(KERN_ERR, ha,
1401                                  "%s:Invalid DDB index %d", __func__,
1402                                  ddb_index));
1403                goto exit_bootdb_failed;
1404        }
1405
1406        if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,
1407                              sizeof(*fw_ddb_entry)) != QLA_SUCCESS) {
1408                ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash"
1409                           "failed\n", ha->host_no, __func__);
1410                goto exit_bootdb_failed;
1411        }
1412
1413        if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)
1414                status = QLA_SUCCESS;
1415
1416exit_bootdb_failed:
1417        return status;
1418}
1419
1420int qla4xxx_flashdb_by_index(struct scsi_qla_host *ha,
1421                             struct dev_db_entry *fw_ddb_entry,
1422                             dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index)
1423{
1424        uint32_t dev_db_start_offset;
1425        uint32_t dev_db_end_offset;
1426        int status = QLA_ERROR;
1427
1428        memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));
1429
1430        if (is_qla40XX(ha)) {
1431                dev_db_start_offset = FLASH_OFFSET_DB_INFO;
1432                dev_db_end_offset = FLASH_OFFSET_DB_END;
1433        } else {
1434                dev_db_start_offset = FLASH_RAW_ACCESS_ADDR +
1435                                      (ha->hw.flt_region_ddb << 2);
1436                /* flt_ddb_size is DDB table size for both ports
1437                 * so divide it by 2 to calculate the offset for second port
1438                 */
1439                if (ha->port_num == 1)
1440                        dev_db_start_offset += (ha->hw.flt_ddb_size / 2);
1441
1442                dev_db_end_offset = dev_db_start_offset +
1443                                    (ha->hw.flt_ddb_size / 2);
1444        }
1445
1446        dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));
1447
1448        if (dev_db_start_offset > dev_db_end_offset) {
1449                DEBUG2(ql4_printk(KERN_ERR, ha,
1450                                  "%s:Invalid DDB index %d", __func__,
1451                                  ddb_index));
1452                goto exit_fdb_failed;
1453        }
1454
1455        if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,
1456                              sizeof(*fw_ddb_entry)) != QLA_SUCCESS) {
1457                ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash failed\n",
1458                           ha->host_no, __func__);
1459                goto exit_fdb_failed;
1460        }
1461
1462        if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)
1463                status = QLA_SUCCESS;
1464
1465exit_fdb_failed:
1466        return status;
1467}
1468
1469int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,
1470                     uint16_t idx)
1471{
1472        int ret = 0;
1473        int rval = QLA_ERROR;
1474        uint32_t offset = 0, chap_size;
1475        struct ql4_chap_table *chap_table;
1476        dma_addr_t chap_dma;
1477
1478        chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
1479        if (chap_table == NULL)
1480                return -ENOMEM;
1481
1482        chap_size = sizeof(struct ql4_chap_table);
1483        memset(chap_table, 0, chap_size);
1484
1485        if (is_qla40XX(ha))
1486                offset = FLASH_CHAP_OFFSET | (idx * chap_size);
1487        else {
1488                offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);
1489                /* flt_chap_size is CHAP table size for both ports
1490                 * so divide it by 2 to calculate the offset for second port
1491                 */
1492                if (ha->port_num == 1)
1493                        offset += (ha->hw.flt_chap_size / 2);
1494                offset += (idx * chap_size);
1495        }
1496
1497        rval = qla4xxx_get_flash(ha, chap_dma, offset, chap_size);
1498        if (rval != QLA_SUCCESS) {
1499                ret = -EINVAL;
1500                goto exit_get_chap;
1501        }
1502
1503        DEBUG2(ql4_printk(KERN_INFO, ha, "Chap Cookie: x%x\n",
1504                __le16_to_cpu(chap_table->cookie)));
1505
1506        if (__le16_to_cpu(chap_table->cookie) != CHAP_VALID_COOKIE) {
1507                ql4_printk(KERN_ERR, ha, "No valid chap entry found\n");
1508                goto exit_get_chap;
1509        }
1510
1511        strncpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN);
1512        strncpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN);
1513        chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE);
1514
1515exit_get_chap:
1516        dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma);
1517        return ret;
1518}
1519
1520static int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username,
1521                            char *password, uint16_t idx, int bidi)
1522{
1523        int ret = 0;
1524        int rval = QLA_ERROR;
1525        uint32_t offset = 0;
1526        struct ql4_chap_table *chap_table;
1527        dma_addr_t chap_dma;
1528
1529        chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
1530        if (chap_table == NULL) {
1531                ret =  -ENOMEM;
1532                goto exit_set_chap;
1533        }
1534
1535        memset(chap_table, 0, sizeof(struct ql4_chap_table));
1536        if (bidi)
1537                chap_table->flags |= BIT_6; /* peer */
1538        else
1539                chap_table->flags |= BIT_7; /* local */
1540        chap_table->secret_len = strlen(password);
1541        strncpy(chap_table->secret, password, MAX_CHAP_SECRET_LEN);
1542        strncpy(chap_table->name, username, MAX_CHAP_NAME_LEN);
1543        chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE);
1544        offset = FLASH_CHAP_OFFSET | (idx * sizeof(struct ql4_chap_table));
1545        rval = qla4xxx_set_flash(ha, chap_dma, offset,
1546                                sizeof(struct ql4_chap_table),
1547                                FLASH_OPT_RMW_COMMIT);
1548
1549        if (rval == QLA_SUCCESS && ha->chap_list) {
1550                /* Update ha chap_list cache */
1551                memcpy((struct ql4_chap_table *)ha->chap_list + idx,
1552                       chap_table, sizeof(struct ql4_chap_table));
1553        }
1554        dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma);
1555        if (rval != QLA_SUCCESS)
1556                ret =  -EINVAL;
1557
1558exit_set_chap:
1559        return ret;
1560}
1561
1562
1563int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,
1564                                  char *password, uint16_t chap_index)
1565{
1566        int rval = QLA_ERROR;
1567        struct ql4_chap_table *chap_table = NULL;
1568        int max_chap_entries;
1569
1570        if (!ha->chap_list) {
1571                ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");
1572                rval = QLA_ERROR;
1573                goto exit_uni_chap;
1574        }
1575
1576        if (!username || !password) {
1577                ql4_printk(KERN_ERR, ha, "No memory for username & secret\n");
1578                rval = QLA_ERROR;
1579                goto exit_uni_chap;
1580        }
1581
1582        if (is_qla80XX(ha))
1583                max_chap_entries = (ha->hw.flt_chap_size / 2) /
1584                                   sizeof(struct ql4_chap_table);
1585        else
1586                max_chap_entries = MAX_CHAP_ENTRIES_40XX;
1587
1588        if (chap_index > max_chap_entries) {
1589                ql4_printk(KERN_ERR, ha, "Invalid Chap index\n");
1590                rval = QLA_ERROR;
1591                goto exit_uni_chap;
1592        }
1593
1594        mutex_lock(&ha->chap_sem);
1595        chap_table = (struct ql4_chap_table *)ha->chap_list + chap_index;
1596        if (chap_table->cookie != __constant_cpu_to_le16(CHAP_VALID_COOKIE)) {
1597                rval = QLA_ERROR;
1598                goto exit_unlock_uni_chap;
1599        }
1600
1601        if (!(chap_table->flags & BIT_6)) {
1602                ql4_printk(KERN_ERR, ha, "Unidirectional entry not set\n");
1603                rval = QLA_ERROR;
1604                goto exit_unlock_uni_chap;
1605        }
1606
1607        strncpy(password, chap_table->secret, MAX_CHAP_SECRET_LEN);
1608        strncpy(username, chap_table->name, MAX_CHAP_NAME_LEN);
1609
1610        rval = QLA_SUCCESS;
1611
1612exit_unlock_uni_chap:
1613        mutex_unlock(&ha->chap_sem);
1614exit_uni_chap:
1615        return rval;
1616}
1617
1618/**
1619 * qla4xxx_get_chap_index - Get chap index given username and secret
1620 * @ha: pointer to adapter structure
1621 * @username: CHAP username to be searched
1622 * @password: CHAP password to be searched
1623 * @bidi: Is this a BIDI CHAP
1624 * @chap_index: CHAP index to be returned
1625 *
1626 * Match the username and password in the chap_list, return the index if a
1627 * match is found. If a match is not found then add the entry in FLASH and
1628 * return the index at which entry is written in the FLASH.
1629 **/
1630int qla4xxx_get_chap_index(struct scsi_qla_host *ha, char *username,
1631                           char *password, int bidi, uint16_t *chap_index)
1632{
1633        int i, rval;
1634        int free_index = -1;
1635        int found_index = 0;
1636        int max_chap_entries = 0;
1637        struct ql4_chap_table *chap_table;
1638
1639        if (is_qla80XX(ha))
1640                max_chap_entries = (ha->hw.flt_chap_size / 2) /
1641                                                sizeof(struct ql4_chap_table);
1642        else
1643                max_chap_entries = MAX_CHAP_ENTRIES_40XX;
1644
1645        if (!ha->chap_list) {
1646                ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");
1647                return QLA_ERROR;
1648        }
1649
1650        if (!username || !password) {
1651                ql4_printk(KERN_ERR, ha, "Do not have username and psw\n");
1652                return QLA_ERROR;
1653        }
1654
1655        mutex_lock(&ha->chap_sem);
1656        for (i = 0; i < max_chap_entries; i++) {
1657                chap_table = (struct ql4_chap_table *)ha->chap_list + i;
1658                if (chap_table->cookie !=
1659                    __constant_cpu_to_le16(CHAP_VALID_COOKIE)) {
1660                        if (i > MAX_RESRV_CHAP_IDX && free_index == -1)
1661                                free_index = i;
1662                        continue;
1663                }
1664                if (bidi) {
1665                        if (chap_table->flags & BIT_7)
1666                                continue;
1667                } else {
1668                        if (chap_table->flags & BIT_6)
1669                                continue;
1670                }
1671                if (!strncmp(chap_table->secret, password,
1672                             MAX_CHAP_SECRET_LEN) &&
1673                    !strncmp(chap_table->name, username,
1674                             MAX_CHAP_NAME_LEN)) {
1675                        *chap_index = i;
1676                        found_index = 1;
1677                        break;
1678                }
1679        }
1680
1681        /* If chap entry is not present and a free index is available then
1682         * write the entry in flash
1683         */
1684        if (!found_index && free_index != -1) {
1685                rval = qla4xxx_set_chap(ha, username, password,
1686                                        free_index, bidi);
1687                if (!rval) {
1688                        *chap_index = free_index;
1689                        found_index = 1;
1690                }
1691        }
1692
1693        mutex_unlock(&ha->chap_sem);
1694
1695        if (found_index)
1696                return QLA_SUCCESS;
1697        return QLA_ERROR;
1698}
1699
1700int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha,
1701                                   uint16_t fw_ddb_index,
1702                                   uint16_t connection_id,
1703                                   uint16_t option)
1704{
1705        uint32_t mbox_cmd[MBOX_REG_COUNT];
1706        uint32_t mbox_sts[MBOX_REG_COUNT];
1707        int status = QLA_SUCCESS;
1708
1709        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1710        memset(&mbox_sts, 0, sizeof(mbox_sts));
1711
1712        mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;
1713        mbox_cmd[1] = fw_ddb_index;
1714        mbox_cmd[2] = connection_id;
1715        mbox_cmd[3] = option;
1716
1717        status = qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]);
1718        if (status != QLA_SUCCESS) {
1719                DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_CONN_CLOSE "
1720                                  "option %04x failed w/ status %04X %04X\n",
1721                                  __func__, option, mbox_sts[0], mbox_sts[1]));
1722        }
1723        return status;
1724}
1725
1726int qla4xxx_disable_acb(struct scsi_qla_host *ha)
1727{
1728        uint32_t mbox_cmd[MBOX_REG_COUNT];
1729        uint32_t mbox_sts[MBOX_REG_COUNT];
1730        int status = QLA_SUCCESS;
1731
1732        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1733        memset(&mbox_sts, 0, sizeof(mbox_sts));
1734
1735        mbox_cmd[0] = MBOX_CMD_DISABLE_ACB;
1736
1737        status = qla4xxx_mailbox_command(ha, 8, 5, &mbox_cmd[0], &mbox_sts[0]);
1738        if (status != QLA_SUCCESS) {
1739                DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_DISABLE_ACB "
1740                                  "failed w/ status %04X %04X %04X", __func__,
1741                                  mbox_sts[0], mbox_sts[1], mbox_sts[2]));
1742        }
1743        return status;
1744}
1745
1746int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,
1747                    uint32_t acb_type, uint32_t len)
1748{
1749        uint32_t mbox_cmd[MBOX_REG_COUNT];
1750        uint32_t mbox_sts[MBOX_REG_COUNT];
1751        int status = QLA_SUCCESS;
1752
1753        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1754        memset(&mbox_sts, 0, sizeof(mbox_sts));
1755
1756        mbox_cmd[0] = MBOX_CMD_GET_ACB;
1757        mbox_cmd[1] = acb_type;
1758        mbox_cmd[2] = LSDW(acb_dma);
1759        mbox_cmd[3] = MSDW(acb_dma);
1760        mbox_cmd[4] = len;
1761
1762        status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]);
1763        if (status != QLA_SUCCESS) {
1764                DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_GET_ACB "
1765                                  "failed w/ status %04X\n", __func__,
1766                                  mbox_sts[0]));
1767        }
1768        return status;
1769}
1770
1771int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
1772                    uint32_t *mbox_sts, dma_addr_t acb_dma)
1773{
1774        int status = QLA_SUCCESS;
1775
1776        memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
1777        memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
1778        mbox_cmd[0] = MBOX_CMD_SET_ACB;
1779        mbox_cmd[1] = 0; /* Primary ACB */
1780        mbox_cmd[2] = LSDW(acb_dma);
1781        mbox_cmd[3] = MSDW(acb_dma);
1782        mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
1783
1784        status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]);
1785        if (status != QLA_SUCCESS) {
1786                DEBUG2(ql4_printk(KERN_WARNING, ha,  "%s: MBOX_CMD_SET_ACB "
1787                                  "failed w/ status %04X\n", __func__,
1788                                  mbox_sts[0]));
1789        }
1790        return status;
1791}
1792
1793int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,
1794                               struct ddb_entry *ddb_entry,
1795                               struct iscsi_cls_conn *cls_conn,
1796                               uint32_t *mbx_sts)
1797{
1798        struct dev_db_entry *fw_ddb_entry;
1799        struct iscsi_conn *conn;
1800        struct iscsi_session *sess;
1801        struct qla_conn *qla_conn;
1802        struct sockaddr *dst_addr;
1803        dma_addr_t fw_ddb_entry_dma;
1804        int status = QLA_SUCCESS;
1805        int rval = 0;
1806        struct sockaddr_in *addr;
1807        struct sockaddr_in6 *addr6;
1808        char *ip;
1809        uint16_t iscsi_opts = 0;
1810        uint32_t options = 0;
1811        uint16_t idx, *ptid;
1812
1813        fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1814                                          &fw_ddb_entry_dma, GFP_KERNEL);
1815        if (!fw_ddb_entry) {
1816                DEBUG2(ql4_printk(KERN_ERR, ha,
1817                                  "%s: Unable to allocate dma buffer.\n",
1818                                  __func__));
1819                rval = -ENOMEM;
1820                goto exit_set_param_no_free;
1821        }
1822
1823        conn = cls_conn->dd_data;
1824        qla_conn = conn->dd_data;
1825        sess = conn->session;
1826        dst_addr = (struct sockaddr *)&qla_conn->qla_ep->dst_addr;
1827
1828        if (dst_addr->sa_family == AF_INET6)
1829                options |= IPV6_DEFAULT_DDB_ENTRY;
1830
1831        status = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma);
1832        if (status == QLA_ERROR) {
1833                rval = -EINVAL;
1834                goto exit_set_param;
1835        }
1836
1837        ptid = (uint16_t *)&fw_ddb_entry->isid[1];
1838        *ptid = cpu_to_le16((uint16_t)ddb_entry->sess->target_id);
1839
1840        DEBUG2(ql4_printk(KERN_INFO, ha, "ISID [%02x%02x%02x%02x%02x%02x]\n",
1841                          fw_ddb_entry->isid[5], fw_ddb_entry->isid[4],
1842                          fw_ddb_entry->isid[3], fw_ddb_entry->isid[2],
1843                          fw_ddb_entry->isid[1], fw_ddb_entry->isid[0]));
1844
1845        iscsi_opts = le16_to_cpu(fw_ddb_entry->iscsi_options);
1846        memset(fw_ddb_entry->iscsi_alias, 0, sizeof(fw_ddb_entry->iscsi_alias));
1847
1848        memset(fw_ddb_entry->iscsi_name, 0, sizeof(fw_ddb_entry->iscsi_name));
1849
1850        if (sess->targetname != NULL) {
1851                memcpy(fw_ddb_entry->iscsi_name, sess->targetname,
1852                       min(strlen(sess->targetname),
1853                       sizeof(fw_ddb_entry->iscsi_name)));
1854        }
1855
1856        memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr));
1857        memset(fw_ddb_entry->tgt_addr, 0, sizeof(fw_ddb_entry->tgt_addr));
1858
1859        fw_ddb_entry->options =  DDB_OPT_TARGET | DDB_OPT_AUTO_SENDTGTS_DISABLE;
1860
1861        if (dst_addr->sa_family == AF_INET) {
1862                addr = (struct sockaddr_in *)dst_addr;
1863                ip = (char *)&addr->sin_addr;
1864                memcpy(fw_ddb_entry->ip_addr, ip, IP_ADDR_LEN);
1865                fw_ddb_entry->port = cpu_to_le16(ntohs(addr->sin_port));
1866                DEBUG2(ql4_printk(KERN_INFO, ha,
1867                                  "%s: Destination Address [%pI4]: index [%d]\n",
1868                                   __func__, fw_ddb_entry->ip_addr,
1869                                  ddb_entry->fw_ddb_index));
1870        } else if (dst_addr->sa_family == AF_INET6) {
1871                addr6 = (struct sockaddr_in6 *)dst_addr;
1872                ip = (char *)&addr6->sin6_addr;
1873                memcpy(fw_ddb_entry->ip_addr, ip, IPv6_ADDR_LEN);
1874                fw_ddb_entry->port = cpu_to_le16(ntohs(addr6->sin6_port));
1875                fw_ddb_entry->options |= DDB_OPT_IPV6_DEVICE;
1876                DEBUG2(ql4_printk(KERN_INFO, ha,
1877                                  "%s: Destination Address [%pI6]: index [%d]\n",
1878                                   __func__, fw_ddb_entry->ip_addr,
1879                                  ddb_entry->fw_ddb_index));
1880        } else {
1881                ql4_printk(KERN_ERR, ha,
1882                           "%s: Failed to get IP Address\n",
1883                           __func__);
1884                rval = -EINVAL;
1885                goto exit_set_param;
1886        }
1887
1888        /* CHAP */
1889        if (sess->username != NULL && sess->password != NULL) {
1890                if (strlen(sess->username) && strlen(sess->password)) {
1891                        iscsi_opts |= BIT_7;
1892
1893                        rval = qla4xxx_get_chap_index(ha, sess->username,
1894                                                sess->password,
1895                                                LOCAL_CHAP, &idx);
1896                        if (rval)
1897                                goto exit_set_param;
1898
1899                        fw_ddb_entry->chap_tbl_idx = cpu_to_le16(idx);
1900                }
1901        }
1902
1903        if (sess->username_in != NULL && sess->password_in != NULL) {
1904                /* Check if BIDI CHAP */
1905                if (strlen(sess->username_in) && strlen(sess->password_in)) {
1906                        iscsi_opts |= BIT_4;
1907
1908                        rval = qla4xxx_get_chap_index(ha, sess->username_in,
1909                                                      sess->password_in,
1910                                                      BIDI_CHAP, &idx);
1911                        if (rval)
1912                                goto exit_set_param;
1913                }
1914        }
1915
1916        if (sess->initial_r2t_en)
1917                iscsi_opts |= BIT_10;
1918
1919        if (sess->imm_data_en)
1920                iscsi_opts |= BIT_11;
1921
1922        fw_ddb_entry->iscsi_options = cpu_to_le16(iscsi_opts);
1923
1924        if (conn->max_recv_dlength)
1925                fw_ddb_entry->iscsi_max_rcv_data_seg_len =
1926                  __constant_cpu_to_le16((conn->max_recv_dlength / BYTE_UNITS));
1927
1928        if (sess->max_r2t)
1929                fw_ddb_entry->iscsi_max_outsnd_r2t = cpu_to_le16(sess->max_r2t);
1930
1931        if (sess->first_burst)
1932                fw_ddb_entry->iscsi_first_burst_len =
1933                       __constant_cpu_to_le16((sess->first_burst / BYTE_UNITS));
1934
1935        if (sess->max_burst)
1936                fw_ddb_entry->iscsi_max_burst_len =
1937                        __constant_cpu_to_le16((sess->max_burst / BYTE_UNITS));
1938
1939        if (sess->time2wait)
1940                fw_ddb_entry->iscsi_def_time2wait =
1941                        cpu_to_le16(sess->time2wait);
1942
1943        if (sess->time2retain)
1944                fw_ddb_entry->iscsi_def_time2retain =
1945                        cpu_to_le16(sess->time2retain);
1946
1947        status = qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index,
1948                                       fw_ddb_entry_dma, mbx_sts);
1949
1950        if (status != QLA_SUCCESS)
1951                rval = -EINVAL;
1952exit_set_param:
1953        dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1954                          fw_ddb_entry, fw_ddb_entry_dma);
1955exit_set_param_no_free:
1956        return rval;
1957}
1958
1959int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index,
1960                          uint16_t stats_size, dma_addr_t stats_dma)
1961{
1962        int status = QLA_SUCCESS;
1963        uint32_t mbox_cmd[MBOX_REG_COUNT];
1964        uint32_t mbox_sts[MBOX_REG_COUNT];
1965
1966        memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
1967        memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
1968        mbox_cmd[0] = MBOX_CMD_GET_MANAGEMENT_DATA;
1969        mbox_cmd[1] = fw_ddb_index;
1970        mbox_cmd[2] = LSDW(stats_dma);
1971        mbox_cmd[3] = MSDW(stats_dma);
1972        mbox_cmd[4] = stats_size;
1973
1974        status = qla4xxx_mailbox_command(ha, 5, 1, &mbox_cmd[0], &mbox_sts[0]);
1975        if (status != QLA_SUCCESS) {
1976                DEBUG2(ql4_printk(KERN_WARNING, ha,
1977                                  "%s: MBOX_CMD_GET_MANAGEMENT_DATA "
1978                                  "failed w/ status %04X\n", __func__,
1979                                  mbox_sts[0]));
1980        }
1981        return status;
1982}
1983
1984int qla4xxx_get_ip_state(struct scsi_qla_host *ha, uint32_t acb_idx,
1985                         uint32_t ip_idx, uint32_t *sts)
1986{
1987        uint32_t mbox_cmd[MBOX_REG_COUNT];
1988        uint32_t mbox_sts[MBOX_REG_COUNT];
1989        int status = QLA_SUCCESS;
1990
1991        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1992        memset(&mbox_sts, 0, sizeof(mbox_sts));
1993        mbox_cmd[0] = MBOX_CMD_GET_IP_ADDR_STATE;
1994        mbox_cmd[1] = acb_idx;
1995        mbox_cmd[2] = ip_idx;
1996
1997        status = qla4xxx_mailbox_command(ha, 3, 8, &mbox_cmd[0], &mbox_sts[0]);
1998        if (status != QLA_SUCCESS) {
1999                DEBUG2(ql4_printk(KERN_WARNING, ha,  "%s: "
2000                                  "MBOX_CMD_GET_IP_ADDR_STATE failed w/ "
2001                                  "status %04X\n", __func__, mbox_sts[0]));
2002        }
2003        memcpy(sts, mbox_sts, sizeof(mbox_sts));
2004        return status;
2005}
2006
2007int qla4xxx_get_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma,
2008                      uint32_t offset, uint32_t size)
2009{
2010        int status = QLA_SUCCESS;
2011        uint32_t mbox_cmd[MBOX_REG_COUNT];
2012        uint32_t mbox_sts[MBOX_REG_COUNT];
2013
2014        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2015        memset(&mbox_sts, 0, sizeof(mbox_sts));
2016
2017        mbox_cmd[0] = MBOX_CMD_GET_NVRAM;
2018        mbox_cmd[1] = LSDW(nvram_dma);
2019        mbox_cmd[2] = MSDW(nvram_dma);
2020        mbox_cmd[3] = offset;
2021        mbox_cmd[4] = size;
2022
2023        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
2024                                         &mbox_sts[0]);
2025        if (status != QLA_SUCCESS) {
2026                DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "
2027                                  "status %04X\n", ha->host_no, __func__,
2028                                  mbox_sts[0]));
2029        }
2030        return status;
2031}
2032
2033int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma,
2034                      uint32_t offset, uint32_t size)
2035{
2036        int status = QLA_SUCCESS;
2037        uint32_t mbox_cmd[MBOX_REG_COUNT];
2038        uint32_t mbox_sts[MBOX_REG_COUNT];
2039
2040        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2041        memset(&mbox_sts, 0, sizeof(mbox_sts));
2042
2043        mbox_cmd[0] = MBOX_CMD_SET_NVRAM;
2044        mbox_cmd[1] = LSDW(nvram_dma);
2045        mbox_cmd[2] = MSDW(nvram_dma);
2046        mbox_cmd[3] = offset;
2047        mbox_cmd[4] = size;
2048
2049        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
2050                                         &mbox_sts[0]);
2051        if (status != QLA_SUCCESS) {
2052                DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "
2053                                  "status %04X\n", ha->host_no, __func__,
2054                                  mbox_sts[0]));
2055        }
2056        return status;
2057}
2058
2059int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha,
2060                                     uint32_t region, uint32_t field0,
2061                                     uint32_t field1)
2062{
2063        int status = QLA_SUCCESS;
2064        uint32_t mbox_cmd[MBOX_REG_COUNT];
2065        uint32_t mbox_sts[MBOX_REG_COUNT];
2066
2067        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2068        memset(&mbox_sts, 0, sizeof(mbox_sts));
2069
2070        mbox_cmd[0] = MBOX_CMD_RESTORE_FACTORY_DEFAULTS;
2071        mbox_cmd[3] = region;
2072        mbox_cmd[4] = field0;
2073        mbox_cmd[5] = field1;
2074
2075        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0],
2076                                         &mbox_sts[0]);
2077        if (status != QLA_SUCCESS) {
2078                DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "
2079                                  "status %04X\n", ha->host_no, __func__,
2080                                  mbox_sts[0]));
2081        }
2082        return status;
2083}
2084
2085/**
2086 * qla4_8xxx_set_param - set driver version in firmware.
2087 * @ha: Pointer to host adapter structure.
2088 * @param: Parameter to set i.e driver version
2089 **/
2090int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param)
2091{
2092        uint32_t mbox_cmd[MBOX_REG_COUNT];
2093        uint32_t mbox_sts[MBOX_REG_COUNT];
2094        uint32_t status;
2095
2096        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2097        memset(&mbox_sts, 0, sizeof(mbox_sts));
2098
2099        mbox_cmd[0] = MBOX_CMD_SET_PARAM;
2100        if (param == SET_DRVR_VERSION) {
2101                mbox_cmd[1] = SET_DRVR_VERSION;
2102                strncpy((char *)&mbox_cmd[2], QLA4XXX_DRIVER_VERSION,
2103                        MAX_DRVR_VER_LEN);
2104        } else {
2105                ql4_printk(KERN_ERR, ha, "%s: invalid parameter 0x%x\n",
2106                           __func__, param);
2107                status = QLA_ERROR;
2108                goto exit_set_param;
2109        }
2110
2111        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, mbox_cmd,
2112                                         mbox_sts);
2113        if (status == QLA_ERROR)
2114                ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",
2115                           __func__, mbox_sts[0]);
2116
2117exit_set_param:
2118        return status;
2119}
2120
2121/**
2122 * qla4_83xx_post_idc_ack - post IDC ACK
2123 * @ha: Pointer to host adapter structure.
2124 *
2125 * Posts IDC ACK for IDC Request Notification AEN.
2126 **/
2127int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha)
2128{
2129        uint32_t mbox_cmd[MBOX_REG_COUNT];
2130        uint32_t mbox_sts[MBOX_REG_COUNT];
2131        int status;
2132
2133        memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2134        memset(&mbox_sts, 0, sizeof(mbox_sts));
2135
2136        mbox_cmd[0] = MBOX_CMD_IDC_ACK;
2137        mbox_cmd[1] = ha->idc_info.request_desc;
2138        mbox_cmd[2] = ha->idc_info.info1;
2139        mbox_cmd[3] = ha->idc_info.info2;
2140        mbox_cmd[4] = ha->idc_info.info3;
2141
2142        status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,
2143                                         mbox_cmd, mbox_sts);
2144        if (status == QLA_ERROR)
2145                ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__,
2146                           mbox_sts[0]);
2147        else
2148               DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IDC ACK posted\n",
2149                                 __func__));
2150
2151        return status;
2152}
2153