root/drivers/scsi/qla4xxx/ql4_mbx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qla4xxx_queue_mbox_cmd
  2. qla4xxx_process_mbox_intr
  3. qla4xxx_is_intr_poll_mode
  4. qla4xxx_mailbox_command
  5. qla4xxx_get_minidump_template
  6. qla4xxx_req_template_size
  7. qla4xxx_mailbox_premature_completion
  8. qla4xxx_set_ifcb
  9. qla4xxx_get_ifcb
  10. qla4xxx_set_ipaddr_state
  11. qla4xxx_update_local_ip
  12. qla4xxx_update_local_ifcb
  13. qla4xxx_initialize_fw_cb
  14. qla4xxx_get_dhcp_ip_address
  15. qla4xxx_get_firmware_state
  16. qla4xxx_get_firmware_status
  17. qla4xxx_get_fwddb_entry
  18. qla4xxx_conn_open
  19. qla4xxx_set_ddb_entry
  20. qla4xxx_session_logout_ddb
  21. qla4xxx_get_crash_record
  22. qla4xxx_get_conn_event_log
  23. qla4xxx_abort_task
  24. qla4xxx_reset_lun
  25. qla4xxx_reset_target
  26. qla4xxx_get_flash
  27. qla4xxx_about_firmware
  28. qla4xxx_get_default_ddb
  29. qla4xxx_req_ddb_entry
  30. qla4xxx_clear_ddb_entry
  31. qla4xxx_set_flash
  32. qla4xxx_bootdb_by_index
  33. qla4xxx_flashdb_by_index
  34. qla4xxx_get_chap
  35. qla4xxx_set_chap
  36. qla4xxx_get_uni_chap_at_index
  37. qla4xxx_get_chap_index
  38. qla4xxx_conn_close_sess_logout
  39. qla4_84xx_extend_idc_tmo
  40. qla4xxx_disable_acb
  41. qla4xxx_get_acb
  42. qla4xxx_set_acb
  43. qla4xxx_set_param_ddbentry
  44. qla4xxx_get_mgmt_data
  45. qla4xxx_get_ip_state
  46. qla4xxx_get_nvram
  47. qla4xxx_set_nvram
  48. qla4xxx_restore_factory_defaults
  49. qla4_8xxx_set_param
  50. qla4_83xx_post_idc_ack
  51. qla4_84xx_config_acb
  52. qla4_83xx_get_port_config
  53. qla4_83xx_set_port_config

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

/* [<][>][^][v][top][bottom][index][help] */