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