Merge remote-tracking branch 'scsi/for-next'
[deliverable/linux.git] / drivers / scsi / be2iscsi / be_mgmt.c
index 83926e221f1ecd3b55f05a0770d107d8c170c40b..aebc4ddb3060ee177c06ec9f11b62a021c346f10 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2015 Emulex
+ * Copyright (C) 2005 - 2016 Broadcom
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,10 +7,10 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@broadcom.com)
  *
  * Contact Information:
- * linux-drivers@avagotech.com
+ * linux-drivers@broadcom.com
  *
  * Emulex
  * 3333 Susan Street
 #include "be_iscsi.h"
 #include "be_main.h"
 
-/* UE Status Low CSR */
-static const char * const desc_ue_status_low[] = {
-       "CEV",
-       "CTX",
-       "DBUF",
-       "ERX",
-       "Host",
-       "MPU",
-       "NDMA",
-       "PTC ",
-       "RDMA ",
-       "RXF ",
-       "RXIPS ",
-       "RXULP0 ",
-       "RXULP1 ",
-       "RXULP2 ",
-       "TIM ",
-       "TPOST ",
-       "TPRE ",
-       "TXIPS ",
-       "TXULP0 ",
-       "TXULP1 ",
-       "UC ",
-       "WDMA ",
-       "TXULP2 ",
-       "HOST1 ",
-       "P0_OB_LINK ",
-       "P1_OB_LINK ",
-       "HOST_GPIO ",
-       "MBOX ",
-       "AXGMAC0",
-       "AXGMAC1",
-       "JTAG",
-       "MPU_INTPEND"
-};
-
-/* UE Status High CSR */
-static const char * const desc_ue_status_hi[] = {
-       "LPCMEMHOST",
-       "MGMT_MAC",
-       "PCS0ONLINE",
-       "MPU_IRAM",
-       "PCS1ONLINE",
-       "PCTL0",
-       "PCTL1",
-       "PMEM",
-       "RR",
-       "TXPB",
-       "RXPP",
-       "XAUI",
-       "TXP",
-       "ARM",
-       "IPC",
-       "HOST2",
-       "HOST3",
-       "HOST4",
-       "HOST5",
-       "HOST6",
-       "HOST7",
-       "HOST8",
-       "HOST9",
-       "NETC",
-       "Unknown",
-       "Unknown",
-       "Unknown",
-       "Unknown",
-       "Unknown",
-       "Unknown",
-       "Unknown",
-       "Unknown"
-};
-
-/*
- * beiscsi_ue_detec()- Detect Unrecoverable Error on adapter
- * @phba: Driver priv structure
- *
- * Read registers linked to UE and check for the UE status
- **/
-void beiscsi_ue_detect(struct beiscsi_hba *phba)
-{
-       uint32_t ue_hi = 0, ue_lo = 0;
-       uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
-       uint8_t i = 0;
-
-       if (phba->ue_detected)
-               return;
-
-       pci_read_config_dword(phba->pcidev,
-                             PCICFG_UE_STATUS_LOW, &ue_lo);
-       pci_read_config_dword(phba->pcidev,
-                             PCICFG_UE_STATUS_MASK_LOW,
-                             &ue_mask_lo);
-       pci_read_config_dword(phba->pcidev,
-                             PCICFG_UE_STATUS_HIGH,
-                             &ue_hi);
-       pci_read_config_dword(phba->pcidev,
-                             PCICFG_UE_STATUS_MASK_HI,
-                             &ue_mask_hi);
-
-       ue_lo = (ue_lo & ~ue_mask_lo);
-       ue_hi = (ue_hi & ~ue_mask_hi);
-
-
-       if (ue_lo || ue_hi) {
-               phba->ue_detected = true;
-               beiscsi_log(phba, KERN_ERR,
-                           BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-                           "BG_%d : Error detected on the adapter\n");
-       }
-
-       if (ue_lo) {
-               for (i = 0; ue_lo; ue_lo >>= 1, i++) {
-                       if (ue_lo & 1)
-                               beiscsi_log(phba, KERN_ERR,
-                                           BEISCSI_LOG_CONFIG,
-                                           "BG_%d : UE_LOW %s bit set\n",
-                                           desc_ue_status_low[i]);
-               }
-       }
-
-       if (ue_hi) {
-               for (i = 0; ue_hi; ue_hi >>= 1, i++) {
-                       if (ue_hi & 1)
-                               beiscsi_log(phba, KERN_ERR,
-                                           BEISCSI_LOG_CONFIG,
-                                           "BG_%d : UE_HIGH %s bit set\n",
-                                           desc_ue_status_hi[i]);
-               }
-       }
-}
-
-int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
-                struct be_set_eqd *set_eqd, int num)
+int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
+                           struct be_set_eqd *set_eqd,
+                           int num)
 {
        struct be_ctrl_info *ctrl = &phba->ctrl;
        struct be_mcc_wrb *wrb;
@@ -174,7 +44,7 @@ int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
        req = embedded_payload(wrb);
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-               OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
+                          OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
 
        req->num_eq = cpu_to_le32(num);
        for (i = 0; i < num; i++) {
@@ -184,386 +54,13 @@ int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
                                cpu_to_le32(set_eqd[i].delay_multiplier);
        }
 
+       /* ignore the completion of this mbox command */
+       set_bit(MCC_TAG_STATE_IGNORE, &ctrl->ptag_state[tag].tag_state);
        be_mcc_notify(phba, tag);
        mutex_unlock(&ctrl->mbox_lock);
        return tag;
 }
 
-/**
- * mgmt_reopen_session()- Reopen a session based on reopen_type
- * @phba: Device priv structure instance
- * @reopen_type: Type of reopen_session FW should do.
- * @sess_handle: Session Handle of the session to be re-opened
- *
- * return
- *     the TAG used for MBOX Command
- *
- **/
-unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
-                                 unsigned int reopen_type,
-                                 unsigned int sess_handle)
-{
-       struct be_ctrl_info *ctrl = &phba->ctrl;
-       struct be_mcc_wrb *wrb;
-       struct be_cmd_reopen_session_req *req;
-       unsigned int tag;
-
-       beiscsi_log(phba, KERN_INFO,
-                   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-                   "BG_%d : In bescsi_get_boot_target\n");
-
-       mutex_lock(&ctrl->mbox_lock);
-       wrb = alloc_mcc_wrb(phba, &tag);
-       if (!wrb) {
-               mutex_unlock(&ctrl->mbox_lock);
-               return 0;
-       }
-
-       req = embedded_payload(wrb);
-       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
-                          OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
-                          sizeof(struct be_cmd_reopen_session_resp));
-
-       /* set the reopen_type,sess_handle */
-       req->reopen_type = reopen_type;
-       req->session_handle = sess_handle;
-
-       be_mcc_notify(phba, tag);
-       mutex_unlock(&ctrl->mbox_lock);
-       return tag;
-}
-
-unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
-{
-       struct be_ctrl_info *ctrl = &phba->ctrl;
-       struct be_mcc_wrb *wrb;
-       struct be_cmd_get_boot_target_req *req;
-       unsigned int tag;
-
-       beiscsi_log(phba, KERN_INFO,
-                   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-                   "BG_%d : In bescsi_get_boot_target\n");
-
-       mutex_lock(&ctrl->mbox_lock);
-       wrb = alloc_mcc_wrb(phba, &tag);
-       if (!wrb) {
-               mutex_unlock(&ctrl->mbox_lock);
-               return 0;
-       }
-
-       req = embedded_payload(wrb);
-       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
-                          OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
-                          sizeof(struct be_cmd_get_boot_target_resp));
-
-       be_mcc_notify(phba, tag);
-       mutex_unlock(&ctrl->mbox_lock);
-       return tag;
-}
-
-unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
-                                  u32 boot_session_handle,
-                                  struct be_dma_mem *nonemb_cmd)
-{
-       struct be_ctrl_info *ctrl = &phba->ctrl;
-       struct be_mcc_wrb *wrb;
-       unsigned int tag;
-       struct  be_cmd_get_session_req *req;
-       struct be_cmd_get_session_resp *resp;
-       struct be_sge *sge;
-
-       beiscsi_log(phba, KERN_INFO,
-                   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-                   "BG_%d : In beiscsi_get_session_info\n");
-
-       mutex_lock(&ctrl->mbox_lock);
-       wrb = alloc_mcc_wrb(phba, &tag);
-       if (!wrb) {
-               mutex_unlock(&ctrl->mbox_lock);
-               return 0;
-       }
-
-       nonemb_cmd->size = sizeof(*resp);
-       req = nonemb_cmd->va;
-       memset(req, 0, sizeof(*req));
-       sge = nonembedded_sgl(wrb);
-       be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
-       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
-                          OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
-                          sizeof(*resp));
-       req->session_handle = boot_session_handle;
-       sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
-       sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
-       sge->len = cpu_to_le32(nonemb_cmd->size);
-
-       be_mcc_notify(phba, tag);
-       mutex_unlock(&ctrl->mbox_lock);
-       return tag;
-}
-
-/**
- * mgmt_get_port_name()- Get port name for the function
- * @ctrl: ptr to Ctrl Info
- * @phba: ptr to the dev priv structure
- *
- * Get the alphanumeric character for port
- *
- **/
-int mgmt_get_port_name(struct be_ctrl_info *ctrl,
-                      struct beiscsi_hba *phba)
-{
-       int ret = 0;
-       struct be_mcc_wrb *wrb;
-       struct be_cmd_get_port_name *ioctl;
-
-       mutex_lock(&ctrl->mbox_lock);
-       wrb = wrb_from_mbox(&ctrl->mbox_mem);
-       memset(wrb, 0, sizeof(*wrb));
-       ioctl = embedded_payload(wrb);
-
-       be_wrb_hdr_prepare(wrb, sizeof(*ioctl), true, 0);
-       be_cmd_hdr_prepare(&ioctl->h.req_hdr, CMD_SUBSYSTEM_COMMON,
-                          OPCODE_COMMON_GET_PORT_NAME,
-                          EMBED_MBX_MAX_PAYLOAD_SIZE);
-       ret = be_mbox_notify(ctrl);
-       phba->port_name = 0;
-       if (!ret) {
-               phba->port_name = ioctl->p.resp.port_names >>
-                                 (phba->fw_config.phys_port * 8) & 0xff;
-       } else {
-               beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
-                           "BG_%d : GET_PORT_NAME ret 0x%x status 0x%x\n",
-                           ret, ioctl->h.resp_hdr.status);
-       }
-
-       if (phba->port_name == 0)
-               phba->port_name = '?';
-
-       mutex_unlock(&ctrl->mbox_lock);
-       return ret;
-}
-
-/**
- * mgmt_get_fw_config()- Get the FW config for the function
- * @ctrl: ptr to Ctrl Info
- * @phba: ptr to the dev priv structure
- *
- * Get the FW config and resources available for the function.
- * The resources are created based on the count received here.
- *
- * return
- *     Success: 0
- *     Failure: Non-Zero Value
- **/
-int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
-                               struct beiscsi_hba *phba)
-{
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-       struct be_fw_cfg *pfw_cfg = embedded_payload(wrb);
-       uint32_t cid_count, icd_count;
-       int status = -EINVAL;
-       uint8_t ulp_num = 0;
-
-       mutex_lock(&ctrl->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
-       be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
-
-       be_cmd_hdr_prepare(&pfw_cfg->hdr, CMD_SUBSYSTEM_COMMON,
-                          OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
-                          EMBED_MBX_MAX_PAYLOAD_SIZE);
-
-       if (be_mbox_notify(ctrl)) {
-               beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-                           "BG_%d : Failed in mgmt_get_fw_config\n");
-               goto fail_init;
-       }
-
-       /* FW response formats depend on port id */
-       phba->fw_config.phys_port = pfw_cfg->phys_port;
-       if (phba->fw_config.phys_port >= BEISCSI_PHYS_PORT_MAX) {
-               beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-                           "BG_%d : invalid physical port id %d\n",
-                           phba->fw_config.phys_port);
-               goto fail_init;
-       }
-
-       /* populate and check FW config against min and max values */
-       if (!is_chip_be2_be3r(phba)) {
-               phba->fw_config.eqid_count = pfw_cfg->eqid_count;
-               phba->fw_config.cqid_count = pfw_cfg->cqid_count;
-               if (phba->fw_config.eqid_count == 0 ||
-                   phba->fw_config.eqid_count > 2048) {
-                       beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-                                   "BG_%d : invalid EQ count %d\n",
-                                   phba->fw_config.eqid_count);
-                       goto fail_init;
-               }
-               if (phba->fw_config.cqid_count == 0 ||
-                   phba->fw_config.cqid_count > 4096) {
-                       beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-                                   "BG_%d : invalid CQ count %d\n",
-                                   phba->fw_config.cqid_count);
-                       goto fail_init;
-               }
-               beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
-                           "BG_%d : EQ_Count : %d CQ_Count : %d\n",
-                           phba->fw_config.eqid_count,
-                           phba->fw_config.cqid_count);
-       }
-
-       /**
-        * Check on which all ULP iSCSI Protocol is loaded.
-        * Set the Bit for those ULP. This set flag is used
-        * at all places in the code to check on which ULP
-        * iSCSi Protocol is loaded
-        **/
-       for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
-               if (pfw_cfg->ulp[ulp_num].ulp_mode &
-                   BEISCSI_ULP_ISCSI_INI_MODE) {
-                       set_bit(ulp_num, &phba->fw_config.ulp_supported);
-
-                       /* Get the CID, ICD and Chain count for each ULP */
-                       phba->fw_config.iscsi_cid_start[ulp_num] =
-                               pfw_cfg->ulp[ulp_num].sq_base;
-                       phba->fw_config.iscsi_cid_count[ulp_num] =
-                               pfw_cfg->ulp[ulp_num].sq_count;
-
-                       phba->fw_config.iscsi_icd_start[ulp_num] =
-                               pfw_cfg->ulp[ulp_num].icd_base;
-                       phba->fw_config.iscsi_icd_count[ulp_num] =
-                               pfw_cfg->ulp[ulp_num].icd_count;
-
-                       phba->fw_config.iscsi_chain_start[ulp_num] =
-                               pfw_cfg->chain_icd[ulp_num].chain_base;
-                       phba->fw_config.iscsi_chain_count[ulp_num] =
-                               pfw_cfg->chain_icd[ulp_num].chain_count;
-
-                       beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
-                                   "BG_%d : Function loaded on ULP : %d\n"
-                                   "\tiscsi_cid_count : %d\n"
-                                   "\tiscsi_cid_start : %d\n"
-                                   "\t iscsi_icd_count : %d\n"
-                                   "\t iscsi_icd_start : %d\n",
-                                   ulp_num,
-                                   phba->fw_config.
-                                   iscsi_cid_count[ulp_num],
-                                   phba->fw_config.
-                                   iscsi_cid_start[ulp_num],
-                                   phba->fw_config.
-                                   iscsi_icd_count[ulp_num],
-                                   phba->fw_config.
-                                   iscsi_icd_start[ulp_num]);
-               }
-       }
-
-       if (phba->fw_config.ulp_supported == 0) {
-               beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-                           "BG_%d : iSCSI initiator mode not set: ULP0 %x ULP1 %x\n",
-                           pfw_cfg->ulp[BEISCSI_ULP0].ulp_mode,
-                           pfw_cfg->ulp[BEISCSI_ULP1].ulp_mode);
-               goto fail_init;
-       }
-
-       /**
-        * ICD is shared among ULPs. Use icd_count of any one loaded ULP
-        **/
-       for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
-               if (test_bit(ulp_num, &phba->fw_config.ulp_supported))
-                       break;
-       icd_count = phba->fw_config.iscsi_icd_count[ulp_num];
-       if (icd_count == 0 || icd_count > 65536) {
-               beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-                           "BG_%d: invalid ICD count %d\n", icd_count);
-               goto fail_init;
-       }
-
-       cid_count = BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP0) +
-                   BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP1);
-       if (cid_count == 0 || cid_count > 4096) {
-               beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-                           "BG_%d: invalid CID count %d\n", cid_count);
-               goto fail_init;
-       }
-
-       /**
-        * Check FW is dual ULP aware i.e. can handle either
-        * of the protocols.
-        */
-       phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
-                                         BEISCSI_FUNC_DUA_MODE);
-
-       beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
-                   "BG_%d : DUA Mode : 0x%x\n",
-                   phba->fw_config.dual_ulp_aware);
-
-       /* all set, continue using this FW config */
-       status = 0;
-fail_init:
-       mutex_unlock(&ctrl->mbox_lock);
-       return status;
-}
-
-int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
-                                     struct beiscsi_hba *phba)
-{
-       struct be_dma_mem nonemb_cmd;
-       struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-       struct be_mgmt_controller_attributes *req;
-       struct be_sge *sge = nonembedded_sgl(wrb);
-       int status = 0;
-
-       nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
-                               sizeof(struct be_mgmt_controller_attributes),
-                               &nonemb_cmd.dma);
-       if (nonemb_cmd.va == NULL) {
-               beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-                           "BG_%d : Failed to allocate memory for "
-                           "mgmt_check_supported_fw\n");
-               return -ENOMEM;
-       }
-       nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
-       req = nonemb_cmd.va;
-       memset(req, 0, sizeof(*req));
-       mutex_lock(&ctrl->mbox_lock);
-       memset(wrb, 0, sizeof(*wrb));
-       be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
-       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-                          OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
-       sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
-       sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
-       sge->len = cpu_to_le32(nonemb_cmd.size);
-       status = be_mbox_notify(ctrl);
-       if (!status) {
-               struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
-               beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
-                           "BG_%d : Firmware Version of CMD : %s\n"
-                           "Firmware Version is : %s\n"
-                           "Developer Build, not performing version check...\n",
-                           resp->params.hba_attribs
-                           .flashrom_version_string,
-                           resp->params.hba_attribs.
-                           firmware_version_string);
-
-               phba->fw_config.iscsi_features =
-                               resp->params.hba_attribs.iscsi_features;
-               beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
-                           "BM_%d : phba->fw_config.iscsi_features = %d\n",
-                           phba->fw_config.iscsi_features);
-               memcpy(phba->fw_ver_str, resp->params.hba_attribs.
-                      firmware_version_string, BEISCSI_VER_STRLEN);
-       } else
-               beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-                           "BG_%d :  Failed in mgmt_check_supported_fw\n");
-       mutex_unlock(&ctrl->mbox_lock);
-       if (nonemb_cmd.va)
-               pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
-                                   nonemb_cmd.va, nonemb_cmd.dma);
-
-       return status;
-}
-
 unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
                                         struct beiscsi_hba *phba,
                                         struct bsg_job *job,
@@ -609,7 +106,7 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
                            bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
 
                mutex_unlock(&ctrl->mbox_lock);
-               return -ENOSYS;
+               return -EPERM;
        }
 
        wrb = alloc_mcc_wrb(phba, &tag);
@@ -631,48 +128,6 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
        return tag;
 }
 
-/**
- * mgmt_epfw_cleanup()- Inform FW to cleanup data structures.
- * @phba: pointer to dev priv structure
- * @ulp_num: ULP number.
- *
- * return
- *     Success: 0
- *     Failure: Non-Zero Value
- **/
-int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
-{
-       struct be_ctrl_info *ctrl = &phba->ctrl;
-       struct be_mcc_wrb *wrb;
-       struct iscsi_cleanup_req *req;
-       unsigned int tag;
-       int status;
-
-       mutex_lock(&ctrl->mbox_lock);
-       wrb = alloc_mcc_wrb(phba, &tag);
-       if (!wrb) {
-               mutex_unlock(&ctrl->mbox_lock);
-               return -EBUSY;
-       }
-
-       req = embedded_payload(wrb);
-       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
-                          OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
-
-       req->chute = (1 << ulp_num);
-       req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num));
-       req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, ulp_num));
-
-       be_mcc_notify(phba, tag);
-       status = be_mcc_compl_poll(phba, tag);
-       if (status)
-               beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
-                           "BG_%d : mgmt_epfw_cleanup , FAILED\n");
-       mutex_unlock(&ctrl->mbox_lock);
-       return status;
-}
-
 unsigned int  mgmt_invalidate_icds(struct beiscsi_hba *phba,
                                struct invalidate_command_table *inv_tbl,
                                unsigned int num_invalidate, unsigned int cid,
@@ -844,7 +299,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
                           nonemb_cmd->size);
        if (dst_addr->sa_family == PF_INET) {
                __be32 s_addr = daddr_in->sin_addr.s_addr;
-               req->ip_address.ip_type = BE2_IPV4;
+               req->ip_address.ip_type = BEISCSI_IP_TYPE_V4;
                req->ip_address.addr[0] = s_addr & 0x000000ff;
                req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
                req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
@@ -852,17 +307,17 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
                req->tcp_port = ntohs(daddr_in->sin_port);
                beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
                beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
-               beiscsi_ep->ip_type = BE2_IPV4;
+               beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4;
        } else {
                /* else its PF_INET6 family */
-               req->ip_address.ip_type = BE2_IPV6;
+               req->ip_address.ip_type = BEISCSI_IP_TYPE_V6;
                memcpy(&req->ip_address.addr,
                       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
                req->tcp_port = ntohs(daddr_in6->sin6_port);
                beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
                memcpy(&beiscsi_ep->dst6_addr,
                       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
-               beiscsi_ep->ip_type = BE2_IPV6;
+               beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6;
        }
        req->cid = cid;
        i = phba->nxt_cqid++;
@@ -883,7 +338,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
 
        if (!is_chip_be2_be3r(phba)) {
                req->hdr.version = MBX_CMD_VER1;
-               req->tcp_window_size = 0;
+               req->tcp_window_size = 0x8000;
                req->tcp_window_scale_count = 2;
        }
 
@@ -892,44 +347,6 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
        return tag;
 }
 
-unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
-{
-       struct be_ctrl_info *ctrl = &phba->ctrl;
-       struct be_mcc_wrb *wrb;
-       struct be_cmd_get_all_if_id_req *req;
-       struct be_cmd_get_all_if_id_req *pbe_allid;
-       unsigned int tag;
-       int status = 0;
-
-       if (mutex_lock_interruptible(&ctrl->mbox_lock))
-               return -EINTR;
-       wrb = alloc_mcc_wrb(phba, &tag);
-       if (!wrb) {
-               mutex_unlock(&ctrl->mbox_lock);
-               return -ENOMEM;
-       }
-
-       req = embedded_payload(wrb);
-       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
-                          OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
-                          sizeof(*req));
-       be_mcc_notify(phba, tag);
-       mutex_unlock(&ctrl->mbox_lock);
-
-       status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
-       if (status) {
-               beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
-                           "BG_%d : Failed in mgmt_get_all_if_id\n");
-               return -EBUSY;
-       }
-
-       pbe_allid = embedded_payload(wrb);
-       phba->interface_handle = pbe_allid->if_hndl_list[0];
-
-       return status;
-}
-
 /*
  * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
  * @phba: Driver priv structure
@@ -1001,72 +418,68 @@ static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
        }
        cmd->size = size;
        be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
+       beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+                   "BG_%d : subsystem iSCSI cmd %d size %d\n",
+                   iscsi_cmd, size);
        return 0;
 }
 
-static int
-mgmt_static_ip_modify(struct beiscsi_hba *phba,
-                     struct be_cmd_get_if_info_resp *if_info,
-                     struct iscsi_iface_param_info *ip_param,
-                     struct iscsi_iface_param_info *subnet_param,
-                     uint32_t ip_action)
+unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba)
 {
-       struct be_cmd_set_ip_addr_req *req;
-       struct be_dma_mem nonemb_cmd;
-       uint32_t ip_type;
-       int rc;
+       struct be_ctrl_info *ctrl = &phba->ctrl;
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_get_all_if_id_req *req;
+       struct be_cmd_get_all_if_id_req *pbe_allid;
+       unsigned int tag;
+       int status = 0;
 
-       rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
-                                OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
-                                sizeof(*req));
-       if (rc)
-               return rc;
+       if (mutex_lock_interruptible(&ctrl->mbox_lock))
+               return -EINTR;
+       wrb = alloc_mcc_wrb(phba, &tag);
+       if (!wrb) {
+               mutex_unlock(&ctrl->mbox_lock);
+               return -ENOMEM;
+       }
 
-       ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
-               BE2_IPV6 : BE2_IPV4 ;
+       req = embedded_payload(wrb);
+       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
+                          OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
+                          sizeof(*req));
+       be_mcc_notify(phba, tag);
+       mutex_unlock(&ctrl->mbox_lock);
 
-       req = nonemb_cmd.va;
-       req->ip_params.record_entry_count = 1;
-       req->ip_params.ip_record.action = ip_action;
-       req->ip_params.ip_record.interface_hndl =
-               phba->interface_handle;
-       req->ip_params.ip_record.ip_addr.size_of_structure =
-               sizeof(struct be_ip_addr_subnet_format);
-       req->ip_params.ip_record.ip_addr.ip_type = ip_type;
+       status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
+       if (status) {
+               beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+                           "BG_%d : %s failed: %d\n", __func__, status);
+               return -EBUSY;
+       }
 
-       if (ip_action == IP_ACTION_ADD) {
-               memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
-                      sizeof(req->ip_params.ip_record.ip_addr.addr));
+       pbe_allid = embedded_payload(wrb);
+       /* we now support only one interface per function */
+       phba->interface_handle = pbe_allid->if_hndl_list[0];
 
-               if (subnet_param)
-                       memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
-                              subnet_param->value,
-                              sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
-       } else {
-               memcpy(req->ip_params.ip_record.ip_addr.addr,
-                      if_info->ip_addr.addr,
-                      sizeof(req->ip_params.ip_record.ip_addr.addr));
+       return status;
+}
 
-               memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
-                      if_info->ip_addr.subnet_mask,
-                      sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
-       }
+static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type)
+{
+       u32 len;
 
-       rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
-       if (rc < 0)
-               beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
-                           "BG_%d : Failed to Modify existing IP Address\n");
-       return rc;
+       len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
+       while (len && !ip[len - 1])
+               len--;
+       return (len == 0);
 }
 
-static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
-                              uint32_t gtway_action, uint32_t param_len)
+static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
+                            u32 action, u32 ip_type, u8 *gw)
 {
        struct be_cmd_set_def_gateway_req *req;
        struct be_dma_mem nonemb_cmd;
        int rt_val;
 
-
        rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
                                OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
                                sizeof(*req));
@@ -1074,200 +487,300 @@ static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
                return rt_val;
 
        req = nonemb_cmd.va;
-       req->action = gtway_action;
-       req->ip_addr.ip_type = BE2_IPV4;
+       req->action = action;
+       req->ip_addr.ip_type = ip_type;
+       memcpy(req->ip_addr.addr, gw,
+              (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
+       return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
+}
 
-       memcpy(req->ip_addr.addr, gt_addr, sizeof(req->ip_addr.addr));
+int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
+{
+       struct be_cmd_get_def_gateway_resp gw_resp;
+       int rt_val;
 
-       return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
+       memset(&gw_resp, 0, sizeof(gw_resp));
+       rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp);
+       if (rt_val) {
+               beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+                           "BG_%d : Failed to Get Gateway Addr\n");
+               return rt_val;
+       }
+
+       if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) {
+               rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type,
+                                          gw_resp.ip_addr.addr);
+               if (rt_val) {
+                       beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+                                   "BG_%d : Failed to clear Gateway Addr Set\n");
+                       return rt_val;
+               }
+       }
+
+       rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw);
+       if (rt_val)
+               beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+                           "BG_%d : Failed to Set Gateway Addr\n");
+
+       return rt_val;
 }
 
-int mgmt_set_ip(struct beiscsi_hba *phba,
-               struct iscsi_iface_param_info *ip_param,
-               struct iscsi_iface_param_info *subnet_param,
-               uint32_t boot_proto)
+int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
+                     struct be_cmd_get_def_gateway_resp *resp)
 {
-       struct be_cmd_get_def_gateway_resp gtway_addr_set;
-       struct be_cmd_get_if_info_resp *if_info;
-       struct be_cmd_set_dhcp_req *dhcpreq;
-       struct be_cmd_rel_dhcp_req *reldhcp;
+       struct be_cmd_get_def_gateway_req *req;
        struct be_dma_mem nonemb_cmd;
-       uint8_t *gtway_addr;
-       uint32_t ip_type;
        int rc;
 
-       rc = mgmt_get_all_if_id(phba);
+       rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
+                                OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
+                                sizeof(*resp));
        if (rc)
                return rc;
 
-       ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
-               BE2_IPV6 : BE2_IPV4 ;
+       req = nonemb_cmd.va;
+       req->ip_type = ip_type;
+
+       return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, resp,
+                                   sizeof(*resp));
+}
 
-       rc = mgmt_get_if_info(phba, ip_type, &if_info);
+static int
+beiscsi_if_clr_ip(struct beiscsi_hba *phba,
+                 struct be_cmd_get_if_info_resp *if_info)
+{
+       struct be_cmd_set_ip_addr_req *req;
+       struct be_dma_mem nonemb_cmd;
+       int rc;
+
+       rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
+                                OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
+                                sizeof(*req));
        if (rc)
                return rc;
 
-       if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
-               if (if_info->dhcp_state) {
-                       beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
-                                   "BG_%d : DHCP Already Enabled\n");
-                       goto exit;
-               }
-               /* The ip_param->len is 1 in DHCP case. Setting
-                  proper IP len as this it is used while
-                  freeing the Static IP.
-                */
-               ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
-                               IP_V6_LEN : IP_V4_LEN;
-
-       } else {
-               if (if_info->dhcp_state) {
+       req = nonemb_cmd.va;
+       req->ip_params.record_entry_count = 1;
+       req->ip_params.ip_record.action = IP_ACTION_DEL;
+       req->ip_params.ip_record.interface_hndl =
+               phba->interface_handle;
+       req->ip_params.ip_record.ip_addr.size_of_structure =
+               sizeof(struct be_ip_addr_subnet_format);
+       req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type;
+       memcpy(req->ip_params.ip_record.ip_addr.addr,
+              if_info->ip_addr.addr,
+              sizeof(if_info->ip_addr.addr));
+       memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
+              if_info->ip_addr.subnet_mask,
+              sizeof(if_info->ip_addr.subnet_mask));
+       rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
+       if (rc < 0 || req->ip_params.ip_record.status) {
+               beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+                           "BG_%d : failed to clear IP: rc %d status %d\n",
+                           rc, req->ip_params.ip_record.status);
+       }
+       return rc;
+}
 
-                       memset(if_info, 0, sizeof(*if_info));
-                       rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
-                               OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
-                               sizeof(*reldhcp));
+static int
+beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
+                 u8 *subnet, u32 ip_type)
+{
+       struct be_cmd_set_ip_addr_req *req;
+       struct be_dma_mem nonemb_cmd;
+       uint32_t ip_len;
+       int rc;
 
-                       if (rc)
-                               goto exit;
+       rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
+                                OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
+                                sizeof(*req));
+       if (rc)
+               return rc;
 
-                       reldhcp = nonemb_cmd.va;
-                       reldhcp->interface_hndl = phba->interface_handle;
-                       reldhcp->ip_type = ip_type;
+       req = nonemb_cmd.va;
+       req->ip_params.record_entry_count = 1;
+       req->ip_params.ip_record.action = IP_ACTION_ADD;
+       req->ip_params.ip_record.interface_hndl =
+               phba->interface_handle;
+       req->ip_params.ip_record.ip_addr.size_of_structure =
+               sizeof(struct be_ip_addr_subnet_format);
+       req->ip_params.ip_record.ip_addr.ip_type = ip_type;
+       ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
+       memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len);
+       if (subnet)
+               memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
+                      subnet, ip_len);
 
-                       rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
-                       if (rc < 0) {
-                               beiscsi_log(phba, KERN_WARNING,
-                                           BEISCSI_LOG_CONFIG,
-                                           "BG_%d : Failed to Delete existing dhcp\n");
-                               goto exit;
-                       }
-               }
+       rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
+       /**
+        * In some cases, host needs to look into individual record status
+        * even though FW reported success for that IOCTL.
+        */
+       if (rc < 0 || req->ip_params.ip_record.status) {
+               __beiscsi_log(phba, KERN_ERR,
+                           "BG_%d : failed to set IP: rc %d status %d\n",
+                           rc, req->ip_params.ip_record.status);
+               if (req->ip_params.ip_record.status)
+                       rc = -EINVAL;
        }
+       return rc;
+}
 
-       /* Delete the Static IP Set */
-       if (if_info->ip_addr.addr[0]) {
-               rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
-                                          IP_ACTION_DEL);
+int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
+                        u8 *ip, u8 *subnet)
+{
+       struct be_cmd_get_if_info_resp *if_info;
+       struct be_cmd_rel_dhcp_req *reldhcp;
+       struct be_dma_mem nonemb_cmd;
+       int rc;
+
+       rc = beiscsi_if_get_info(phba, ip_type, &if_info);
+       if (rc)
+               return rc;
+
+       if (if_info->dhcp_state) {
+               rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
+                               OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
+                               sizeof(*reldhcp));
                if (rc)
                        goto exit;
-       }
 
-       /* Delete the Gateway settings if mode change is to DHCP */
-       if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
-               memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
-               rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
-               if (rc) {
+               reldhcp = nonemb_cmd.va;
+               reldhcp->interface_hndl = phba->interface_handle;
+               reldhcp->ip_type = ip_type;
+               rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
+               if (rc < 0) {
                        beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
-                                   "BG_%d : Failed to Get Gateway Addr\n");
+                                   "BG_%d : failed to release existing DHCP: %d\n",
+                                   rc);
                        goto exit;
                }
-
-               if (gtway_addr_set.ip_addr.addr[0]) {
-                       gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
-                       rc = mgmt_modify_gateway(phba, gtway_addr,
-                                                IP_ACTION_DEL, IP_V4_LEN);
-
-                       if (rc) {
-                               beiscsi_log(phba, KERN_WARNING,
-                                           BEISCSI_LOG_CONFIG,
-                                           "BG_%d : Failed to clear Gateway Addr Set\n");
-                               goto exit;
-                       }
-               }
        }
 
-       /* Set Adapter to DHCP/Static Mode */
-       if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
-               rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
-                       OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
-                       sizeof(*dhcpreq));
+       /* first delete any IP set */
+       if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
+               rc = beiscsi_if_clr_ip(phba, if_info);
                if (rc)
                        goto exit;
-
-               dhcpreq = nonemb_cmd.va;
-               dhcpreq->flags = BLOCKING;
-               dhcpreq->retry_count = 1;
-               dhcpreq->interface_hndl = phba->interface_handle;
-               dhcpreq->ip_type = BE2_DHCP_V4;
-
-               rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
-       } else {
-               rc = mgmt_static_ip_modify(phba, if_info, ip_param,
-                                            subnet_param, IP_ACTION_ADD);
        }
 
+       /* if ip == NULL then this is called just to release DHCP IP */
+       if (ip)
+               rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type);
 exit:
        kfree(if_info);
        return rc;
 }
 
-int mgmt_set_gateway(struct beiscsi_hba *phba,
-                    struct iscsi_iface_param_info *gateway_param)
+int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
 {
-       struct be_cmd_get_def_gateway_resp gtway_addr_set;
-       uint8_t *gtway_addr;
-       int rt_val;
+       struct be_cmd_get_def_gateway_resp gw_resp;
+       struct be_cmd_get_if_info_resp *if_info;
+       struct be_cmd_set_dhcp_req *dhcpreq;
+       struct be_dma_mem nonemb_cmd;
+       u8 *gw;
+       int rc;
 
-       memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
-       rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
-       if (rt_val) {
+       rc = beiscsi_if_get_info(phba, ip_type, &if_info);
+       if (rc)
+               return rc;
+
+       if (if_info->dhcp_state) {
                beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
-                           "BG_%d : Failed to Get Gateway Addr\n");
-               return rt_val;
+                               "BG_%d : DHCP Already Enabled\n");
+               goto exit;
        }
 
-       if (gtway_addr_set.ip_addr.addr[0]) {
-               gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
-               rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
-                                            gateway_param->len);
-               if (rt_val) {
+       /* first delete any IP set */
+       if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
+               rc = beiscsi_if_clr_ip(phba, if_info);
+               if (rc)
+                       goto exit;
+       }
+
+       /* delete gateway settings if mode change is to DHCP */
+       memset(&gw_resp, 0, sizeof(gw_resp));
+       /* use ip_type provided in if_info */
+       rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp);
+       if (rc) {
+               beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+                           "BG_%d : Failed to Get Gateway Addr\n");
+               goto exit;
+       }
+       gw = (u8 *)&gw_resp.ip_addr.addr;
+       if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) {
+               rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL,
+                                      if_info->ip_addr.ip_type, gw);
+               if (rc) {
                        beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
                                    "BG_%d : Failed to clear Gateway Addr Set\n");
-                       return rt_val;
+                       goto exit;
                }
        }
 
-       gtway_addr = (uint8_t *)&gateway_param->value;
-       rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
-                                    gateway_param->len);
+       rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
+                       OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
+                       sizeof(*dhcpreq));
+       if (rc)
+               goto exit;
 
-       if (rt_val)
-               beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
-                           "BG_%d : Failed to Set Gateway Addr\n");
+       dhcpreq = nonemb_cmd.va;
+       dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */
+       dhcpreq->retry_count = 1;
+       dhcpreq->interface_hndl = phba->interface_handle;
+       dhcpreq->ip_type = ip_type;
+       rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
 
-       return rt_val;
+exit:
+       kfree(if_info);
+       return rc;
 }
 
-int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
-                    struct be_cmd_get_def_gateway_resp *gateway)
+/**
+ * beiscsi_if_set_vlan()- Issue and wait for CMD completion
+ * @phba: device private structure instance
+ * @vlan_tag: VLAN tag
+ *
+ * Issue the MBX Cmd and wait for the completion of the
+ * command.
+ *
+ * returns
+ *     Success: 0
+ *     Failure: Non-Xero Value
+ **/
+int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag)
 {
-       struct be_cmd_get_def_gateway_req *req;
-       struct be_dma_mem nonemb_cmd;
        int rc;
+       unsigned int tag;
 
-       rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
-                                OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
-                                sizeof(*gateway));
-       if (rc)
-               return rc;
-
-       req = nonemb_cmd.va;
-       req->ip_type = ip_type;
+       tag = be_cmd_set_vlan(phba, vlan_tag);
+       if (!tag) {
+               beiscsi_log(phba, KERN_ERR,
+                           (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
+                           "BG_%d : VLAN Setting Failed\n");
+               return -EBUSY;
+       }
 
-       return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
-                                   sizeof(*gateway));
+       rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
+       if (rc) {
+               beiscsi_log(phba, KERN_ERR,
+                           (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
+                           "BS_%d : VLAN MBX Cmd Failed\n");
+               return rc;
+       }
+       return rc;
 }
 
-int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
-                    struct be_cmd_get_if_info_resp **if_info)
+
+int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
+                       struct be_cmd_get_if_info_resp **if_info)
 {
        struct be_cmd_get_if_info_req *req;
        struct be_dma_mem nonemb_cmd;
        uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
        int rc;
 
-       rc = mgmt_get_all_if_id(phba);
+       rc = beiscsi_if_get_handle(phba);
        if (rc)
                return rc;
 
@@ -1364,123 +877,317 @@ unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
        return tag;
 }
 
+static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
+                                      unsigned int tag)
+{
+       struct be_cmd_get_boot_target_resp *boot_resp;
+       struct be_cmd_resp_logout_fw_sess *logo_resp;
+       struct be_cmd_get_session_resp *sess_resp;
+       struct be_mcc_wrb *wrb;
+       struct boot_struct *bs;
+       int boot_work, status;
+
+       if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
+               __beiscsi_log(phba, KERN_ERR,
+                             "BG_%d : %s no boot work %lx\n",
+                             __func__, phba->state);
+               return;
+       }
+
+       if (phba->boot_struct.tag != tag) {
+               __beiscsi_log(phba, KERN_ERR,
+                             "BG_%d : %s tag mismatch %d:%d\n",
+                             __func__, tag, phba->boot_struct.tag);
+               return;
+       }
+       bs = &phba->boot_struct;
+       boot_work = 1;
+       status = 0;
+       switch (bs->action) {
+       case BEISCSI_BOOT_REOPEN_SESS:
+               status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
+               if (!status)
+                       bs->action = BEISCSI_BOOT_GET_SHANDLE;
+               else
+                       bs->retry--;
+               break;
+       case BEISCSI_BOOT_GET_SHANDLE:
+               status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
+               if (!status) {
+                       boot_resp = embedded_payload(wrb);
+                       bs->s_handle = boot_resp->boot_session_handle;
+               }
+               if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
+                       bs->action = BEISCSI_BOOT_REOPEN_SESS;
+                       bs->retry--;
+               } else {
+                       bs->action = BEISCSI_BOOT_GET_SINFO;
+               }
+               break;
+       case BEISCSI_BOOT_GET_SINFO:
+               status = __beiscsi_mcc_compl_status(phba, tag, NULL,
+                                                   &bs->nonemb_cmd);
+               if (!status) {
+                       sess_resp = bs->nonemb_cmd.va;
+                       memcpy(&bs->boot_sess, &sess_resp->session_info,
+                              sizeof(struct mgmt_session_info));
+                       bs->action = BEISCSI_BOOT_LOGOUT_SESS;
+               } else {
+                       __beiscsi_log(phba, KERN_ERR,
+                                     "BG_%d : get boot session info error : 0x%x\n",
+                                     status);
+                       boot_work = 0;
+               }
+               pci_free_consistent(phba->ctrl.pdev, bs->nonemb_cmd.size,
+                                   bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
+               bs->nonemb_cmd.va = NULL;
+               break;
+       case BEISCSI_BOOT_LOGOUT_SESS:
+               status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
+               if (!status) {
+                       logo_resp = embedded_payload(wrb);
+                       if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
+                               __beiscsi_log(phba, KERN_ERR,
+                                             "BG_%d : FW boot session logout error : 0x%x\n",
+                                             logo_resp->session_status);
+                       }
+               }
+               /* continue to create boot_kset even if logout failed? */
+               bs->action = BEISCSI_BOOT_CREATE_KSET;
+               break;
+       default:
+               break;
+       }
+
+       /* clear the tag so no other completion matches this tag */
+       bs->tag = 0;
+       if (!bs->retry) {
+               boot_work = 0;
+               __beiscsi_log(phba, KERN_ERR,
+                             "BG_%d : failed to setup boot target: status %d action %d\n",
+                             status, bs->action);
+       }
+       if (!boot_work) {
+               /* wait for next event to start boot_work */
+               clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
+               return;
+       }
+       schedule_work(&phba->boot_work);
+}
+
 /**
- * be_mgmt_get_boot_shandle()- Get the session handle
- * @phba: device priv structure instance
- * @s_handle: session handle returned for boot session.
+ * beiscsi_boot_logout_sess()- Logout from boot FW session
+ * @phba: Device priv structure instance
+ *
+ * return
+ *     the TAG used for MBOX Command
  *
- * Get the boot target session handle. In case of
- * crashdump mode driver has to issue and MBX Cmd
- * for FW to login to boot target
+ */
+unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
+{
+       struct be_ctrl_info *ctrl = &phba->ctrl;
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_logout_fw_sess *req;
+       unsigned int tag;
+
+       mutex_lock(&ctrl->mbox_lock);
+       wrb = alloc_mcc_wrb(phba, &tag);
+       if (!wrb) {
+               mutex_unlock(&ctrl->mbox_lock);
+               return 0;
+       }
+
+       req = embedded_payload(wrb);
+       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
+                          OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
+                          sizeof(struct be_cmd_req_logout_fw_sess));
+       /* Use the session handle copied into boot_sess */
+       req->session_handle = phba->boot_struct.boot_sess.session_handle;
+
+       phba->boot_struct.tag = tag;
+       set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
+       ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
+
+       be_mcc_notify(phba, tag);
+       mutex_unlock(&ctrl->mbox_lock);
+
+       return tag;
+}
+/**
+ * beiscsi_boot_reopen_sess()- Reopen boot session
+ * @phba: Device priv structure instance
  *
  * return
- *     Success: 0
- *     Failure: Non-Zero value
+ *     the TAG used for MBOX Command
  *
  **/
-int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
-                             unsigned int *s_handle)
+unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
 {
-       struct be_cmd_get_boot_target_resp *boot_resp;
+       struct be_ctrl_info *ctrl = &phba->ctrl;
        struct be_mcc_wrb *wrb;
+       struct be_cmd_reopen_session_req *req;
        unsigned int tag;
-       uint8_t boot_retry = 3;
-       int rc;
 
-       do {
-               /* Get the Boot Target Session Handle and Count*/
-               tag = mgmt_get_boot_target(phba);
-               if (!tag) {
-                       beiscsi_log(phba, KERN_ERR,
-                                   BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
-                                   "BG_%d : Getting Boot Target Info Failed\n");
-                       return -EAGAIN;
-               }
+       mutex_lock(&ctrl->mbox_lock);
+       wrb = alloc_mcc_wrb(phba, &tag);
+       if (!wrb) {
+               mutex_unlock(&ctrl->mbox_lock);
+               return 0;
+       }
 
-               rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
-               if (rc) {
-                       beiscsi_log(phba, KERN_ERR,
-                                   BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
-                                   "BG_%d : MBX CMD get_boot_target Failed\n");
-                       return -EBUSY;
-               }
+       req = embedded_payload(wrb);
+       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
+                          OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
+                          sizeof(struct be_cmd_reopen_session_resp));
+       req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
+       req->session_handle = BE_BOOT_INVALID_SHANDLE;
 
-               boot_resp = embedded_payload(wrb);
+       phba->boot_struct.tag = tag;
+       set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
+       ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
 
-               /* Check if the there are any Boot targets configured */
-               if (!boot_resp->boot_session_count) {
-                       beiscsi_log(phba, KERN_INFO,
-                                   BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
-                                   "BG_%d  ;No boot targets configured\n");
-                       return -ENXIO;
-               }
+       be_mcc_notify(phba, tag);
+       mutex_unlock(&ctrl->mbox_lock);
+       return tag;
+}
 
-               /* FW returns the session handle of the boot session */
-               if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
-                       *s_handle = boot_resp->boot_session_handle;
-                       return 0;
-               }
 
-               /* Issue MBX Cmd to FW to login to the boot target */
-               tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
-                                         INVALID_SESS_HANDLE);
-               if (!tag) {
-                       beiscsi_log(phba, KERN_ERR,
-                                   BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
-                                   "BG_%d : mgmt_reopen_session Failed\n");
-                       return -EAGAIN;
-               }
+/**
+ * beiscsi_boot_get_sinfo()- Get boot session info
+ * @phba: device priv structure instance
+ *
+ * Fetches the boot_struct.s_handle info from FW.
+ * return
+ *     the TAG used for MBOX Command
+ *
+ **/
+unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
+{
+       struct be_ctrl_info *ctrl = &phba->ctrl;
+       struct be_cmd_get_session_resp *resp;
+       struct be_cmd_get_session_req *req;
+       struct be_dma_mem *nonemb_cmd;
+       struct be_mcc_wrb *wrb;
+       struct be_sge *sge;
+       unsigned int tag;
 
-               rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
-               if (rc) {
-                       beiscsi_log(phba, KERN_ERR,
-                                   BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
-                                   "BG_%d : mgmt_reopen_session Failed");
-                       return rc;
-               }
-       } while (--boot_retry);
+       mutex_lock(&ctrl->mbox_lock);
+       wrb = alloc_mcc_wrb(phba, &tag);
+       if (!wrb) {
+               mutex_unlock(&ctrl->mbox_lock);
+               return 0;
+       }
+
+       nonemb_cmd = &phba->boot_struct.nonemb_cmd;
+       nonemb_cmd->size = sizeof(*resp);
+       nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
+                                             sizeof(nonemb_cmd->size),
+                                             &nonemb_cmd->dma);
+       if (!nonemb_cmd->va) {
+               mutex_unlock(&ctrl->mbox_lock);
+               return 0;
+       }
+
+       req = nonemb_cmd->va;
+       memset(req, 0, sizeof(*req));
+       sge = nonembedded_sgl(wrb);
+       be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
+       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
+                          OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
+                          sizeof(*resp));
+       req->session_handle = phba->boot_struct.s_handle;
+       sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+       sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+       sge->len = cpu_to_le32(nonemb_cmd->size);
+
+       phba->boot_struct.tag = tag;
+       set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
+       ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
+
+       be_mcc_notify(phba, tag);
+       mutex_unlock(&ctrl->mbox_lock);
+       return tag;
+}
+
+unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
+{
+       struct be_ctrl_info *ctrl = &phba->ctrl;
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_get_boot_target_req *req;
+       unsigned int tag;
+
+       mutex_lock(&ctrl->mbox_lock);
+       wrb = alloc_mcc_wrb(phba, &tag);
+       if (!wrb) {
+               mutex_unlock(&ctrl->mbox_lock);
+               return 0;
+       }
+
+       req = embedded_payload(wrb);
+       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
+                          OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
+                          sizeof(struct be_cmd_get_boot_target_resp));
 
-       /* Couldn't log into the boot target */
-       beiscsi_log(phba, KERN_ERR,
-                   BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
-                   "BG_%d : Login to Boot Target Failed\n");
-       return -ENXIO;
+       if (async) {
+               phba->boot_struct.tag = tag;
+               set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
+               ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
+       }
+
+       be_mcc_notify(phba, tag);
+       mutex_unlock(&ctrl->mbox_lock);
+       return tag;
 }
 
 /**
- * mgmt_set_vlan()- Issue and wait for CMD completion
- * @phba: device private structure instance
- * @vlan_tag: VLAN tag
+ * beiscsi_boot_get_shandle()- Get boot session handle
+ * @phba: device priv structure instance
+ * @s_handle: session handle returned for boot session.
  *
- * Issue the MBX Cmd and wait for the completion of the
- * command.
+ * return
+ *     Success: 1
+ *     Failure: negative
  *
- * returns
- *     Success: 0
- *     Failure: Non-Xero Value
  **/
-int mgmt_set_vlan(struct beiscsi_hba *phba,
-                  uint16_t vlan_tag)
+int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
 {
-       int rc;
+       struct be_cmd_get_boot_target_resp *boot_resp;
+       struct be_mcc_wrb *wrb;
        unsigned int tag;
+       int rc;
 
-       tag = be_cmd_set_vlan(phba, vlan_tag);
+       *s_handle = BE_BOOT_INVALID_SHANDLE;
+       /* get configured boot session count and handle */
+       tag = __beiscsi_boot_get_shandle(phba, 0);
        if (!tag) {
                beiscsi_log(phba, KERN_ERR,
-                           (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
-                           "BG_%d : VLAN Setting Failed\n");
-               return -EBUSY;
+                           BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
+                           "BG_%d : Getting Boot Target Info Failed\n");
+               return -EAGAIN;
        }
 
-       rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
+       rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
        if (rc) {
                beiscsi_log(phba, KERN_ERR,
-                           (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
-                           "BS_%d : VLAN MBX Cmd Failed\n");
-               return rc;
+                           BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+                           "BG_%d : MBX CMD get_boot_target Failed\n");
+               return -EBUSY;
        }
-       return rc;
+
+       boot_resp = embedded_payload(wrb);
+       /* check if there are any boot targets configured */
+       if (!boot_resp->boot_session_count) {
+               __beiscsi_log(phba, KERN_INFO,
+                             "BG_%d : No boot targets configured\n");
+               return -ENXIO;
+       }
+
+       /* only if FW has logged in to the boot target, s_handle is valid */
+       *s_handle = boot_resp->boot_session_handle;
+       return 1;
 }
 
 /**
@@ -1645,7 +1352,6 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
 {
        struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
 
-       memset(pwrb, 0, sizeof(*pwrb));
        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
                      max_send_data_segment_length, pwrb,
                      params->dw[offsetof(struct amap_beiscsi_offload_params,
@@ -1717,8 +1423,6 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
 {
        struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
 
-       memset(pwrb, 0, sizeof(*pwrb));
-
        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
                      max_burst_length, pwrb, params->dw[offsetof
                      (struct amap_beiscsi_offload_params,
@@ -1790,70 +1494,3 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
                     (params->dw[offsetof(struct amap_beiscsi_offload_params,
                      exp_statsn) / 32] + 1));
 }
-
-/**
- * beiscsi_logout_fw_sess()- Firmware Session Logout
- * @phba: Device priv structure instance
- * @fw_sess_handle: FW session handle
- *
- * Logout from the FW established sessions.
- * returns
- *  Success: 0
- *  Failure: Non-Zero Value
- *
- */
-int beiscsi_logout_fw_sess(struct beiscsi_hba *phba,
-               uint32_t fw_sess_handle)
-{
-       struct be_ctrl_info *ctrl = &phba->ctrl;
-       struct be_mcc_wrb *wrb;
-       struct be_cmd_req_logout_fw_sess *req;
-       struct be_cmd_resp_logout_fw_sess *resp;
-       unsigned int tag;
-       int rc;
-
-       beiscsi_log(phba, KERN_INFO,
-                   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-                   "BG_%d : In bescsi_logout_fwboot_sess\n");
-
-       mutex_lock(&ctrl->mbox_lock);
-       wrb = alloc_mcc_wrb(phba, &tag);
-       if (!wrb) {
-               mutex_unlock(&ctrl->mbox_lock);
-               beiscsi_log(phba, KERN_INFO,
-                           BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-                           "BG_%d : MBX Tag Failure\n");
-               return -EINVAL;
-       }
-
-       req = embedded_payload(wrb);
-       be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-       be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
-                          OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
-                          sizeof(struct be_cmd_req_logout_fw_sess));
-
-       /* Set the session handle */
-       req->session_handle = fw_sess_handle;
-       be_mcc_notify(phba, tag);
-       mutex_unlock(&ctrl->mbox_lock);
-
-       rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
-       if (rc) {
-               beiscsi_log(phba, KERN_ERR,
-                           BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
-                           "BG_%d : MBX CMD FW_SESSION_LOGOUT_TARGET Failed\n");
-               return -EBUSY;
-       }
-
-       resp = embedded_payload(wrb);
-       if (resp->session_status !=
-               BEISCSI_MGMT_SESSION_CLOSE) {
-               beiscsi_log(phba, KERN_ERR,
-                           BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
-                           "BG_%d : FW_SESSION_LOGOUT_TARGET resp : 0x%x\n",
-                           resp->session_status);
-               rc = -EINVAL;
-       }
-
-       return rc;
-}
This page took 0.043028 seconds and 5 git commands to generate.