]> Pileus Git - ~andy/linux/commitdiff
[SCSI] be2iscsi: Config parameters update for Dual Chute Support
authorJayamohan Kallickal <jayamohank@gmail.com>
Sat, 28 Sep 2013 22:35:44 +0000 (15:35 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 25 Oct 2013 08:58:06 +0000 (09:58 +0100)
On the adapter iSCSI protocol can be loaded on either one or both
the CHUTE.Check on which CHUTE iSCSI Protocol is loaded and get
configuration parameters based on which driver initization is done.

For BE-X family iSCSI protocol is loaded only on single chute.

Signed-off-by: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/be2iscsi/be_cmds.h
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h
drivers/scsi/be2iscsi/be_mgmt.c

index 89c407377b772c52ae3ec0c07cce2f381944e210..b812e380ef4677975157d22c747bdecadce487f4 100644 (file)
@@ -40,6 +40,7 @@ struct be_mcc_wrb {
        u32 tag1;               /* dword 3 */
        u32 rsvd;               /* dword 4 */
        union {
+#define EMBED_MBX_MAX_PAYLOAD_SIZE  220
                u8 embedded_payload[236];       /* used by embedded cmds */
                struct be_sge sgl[19];  /* used by non-embedded cmds */
        } payload;
@@ -1030,6 +1031,7 @@ union tcp_upload_params {
 } __packed;
 
 struct be_ulp_fw_cfg {
+#define BEISCSI_ULP_ISCSI_INI_MODE     0x10
        u32 ulp_mode;
        u32 etx_base;
        u32 etx_count;
@@ -1045,14 +1047,26 @@ struct be_ulp_fw_cfg {
        u32 icd_count;
 };
 
+struct be_ulp_chain_icd {
+       u32 chain_base;
+       u32 chain_count;
+};
+
 struct be_fw_cfg {
        struct be_cmd_req_hdr hdr;
        u32 be_config_number;
        u32 asic_revision;
        u32 phys_port;
+#define BEISCSI_FUNC_ISCSI_INI_MODE    0x10
+#define BEISCSI_FUNC_DUA_MODE  0x800
        u32 function_mode;
        struct be_ulp_fw_cfg ulp[2];
        u32 function_caps;
+       u32 cqid_base;
+       u32 cqid_count;
+       u32 eqid_base;
+       u32 eqid_count;
+       struct be_ulp_chain_icd chain_icd[2];
 } __packed;
 
 struct be_cmd_get_all_if_id_req {
index 6ad36af4654a73c665678db53dc93bfcfdcd0631..2bea0762c14f93917b805157f62f8a05f78b2ed1 100644 (file)
@@ -699,30 +699,38 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev)
        return status;
 }
 
+/**
+ * beiscsi_get_params()- Set the config paramters
+ * @phba: ptr  device priv structure
+ **/
 static void beiscsi_get_params(struct beiscsi_hba *phba)
 {
-       phba->params.ios_per_ctrl = (phba->fw_config.iscsi_icd_count
-                                   - (phba->fw_config.iscsi_cid_count
-                                   + BE2_TMFS
-                                   + BE2_NOPOUT_REQ));
-       phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count;
-       phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;
-       phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;
+       uint32_t total_cid_count = 0;
+       uint32_t total_icd_count = 0;
+       uint8_t ulp_num = 0;
+
+       total_cid_count = BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP0) +
+                         BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP1);
+
+       for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
+               if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
+                       total_icd_count = phba->fw_config.
+                                         iscsi_icd_count[ulp_num];
+                       break;
+               }
+
+       phba->params.ios_per_ctrl = (total_icd_count -
+                                   (total_cid_count +
+                                    BE2_TMFS + BE2_NOPOUT_REQ));
+       phba->params.cxns_per_ctrl = total_cid_count;
+       phba->params.asyncpdus_per_ctrl = total_cid_count;
+       phba->params.icds_per_ctrl = total_icd_count;
        phba->params.num_sge_per_io = BE2_SGE;
        phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
        phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ;
        phba->params.eq_timer = 64;
-       phba->params.num_eq_entries =
-           (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2
-                                   + BE2_TMFS) / 512) + 1) * 512;
-       phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024)
-                               ? 1024 : phba->params.num_eq_entries;
-       beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
-                   "BM_%d : phba->params.num_eq_entries=%d\n",
-                   phba->params.num_eq_entries);
-       phba->params.num_cq_entries =
-           (((BE2_CMDS_PER_CXN * 2 +  phba->fw_config.iscsi_cid_count * 2
-                                   + BE2_TMFS) / 512) + 1) * 512;
+       phba->params.num_eq_entries = 1024;
+       phba->params.num_cq_entries = 1024;
        phba->params.wrbs_per_cxn = 256;
 }
 
@@ -2482,6 +2490,10 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
        AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1);
 }
 
+/**
+ * beiscsi_find_mem_req()- Find mem needed
+ * @phba: ptr to HBA struct
+ **/
 static void beiscsi_find_mem_req(struct beiscsi_hba *phba)
 {
        unsigned int num_cq_pages, num_async_pdu_buf_pages;
@@ -2705,7 +2717,7 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
        /* Allocate memory for WRBQ */
        phwi_ctxt = phwi_ctrlr->phwi_ctxt;
        phwi_ctxt->be_wrbq = kzalloc(sizeof(struct be_queue_info) *
-                                    phba->fw_config.iscsi_cid_count,
+                                    phba->params.cxns_per_ctrl,
                                     GFP_KERNEL);
        if (!phwi_ctxt->be_wrbq) {
                beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -2804,7 +2816,7 @@ static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
        memset(pasync_ctx, 0, sizeof(*pasync_ctx));
 
        pasync_ctx->async_entry = kzalloc(sizeof(struct hwi_async_entry) *
-                                         phba->fw_config.iscsi_cid_count,
+                                         phba->params.cxns_per_ctrl,
                                          GFP_KERNEL);
        if (!pasync_ctx->async_entry) {
                beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -3303,14 +3315,14 @@ beiscsi_post_pages(struct beiscsi_hba *phba)
        struct mem_array *pm_arr;
        unsigned int page_offset, i;
        struct be_dma_mem sgl;
-       int status;
+       int status, ulp_num = 0;
 
        mem_descr = phba->init_mem;
        mem_descr += HWI_MEM_SGE;
        pm_arr = mem_descr->mem_array;
 
        page_offset = (sizeof(struct iscsi_sge) * phba->params.num_sge_per_io *
-                       phba->fw_config.iscsi_icd_start) / PAGE_SIZE;
+                       phba->fw_config.iscsi_icd_start[ulp_num]) / PAGE_SIZE;
        for (i = 0; i < mem_descr->num_elements; i++) {
                hwi_build_be_sgl_arr(phba, pm_arr, &sgl);
                status = be_cmd_iscsi_post_sgl_pages(&phba->ctrl, &sgl,
@@ -3767,7 +3779,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
        struct be_mem_descriptor *mem_descr_sglh, *mem_descr_sg;
        struct sgl_handle *psgl_handle;
        struct iscsi_sge *pfrag;
-       unsigned int arr_index, i, idx;
+       unsigned int arr_index, i, idx, ulp_num = 0;
 
        phba->io_sgl_hndl_avbl = 0;
        phba->eh_sgl_hndl_avbl = 0;
@@ -3853,7 +3865,8 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
                        AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0);
                        pfrag += phba->params.num_sge_per_io;
                        psgl_handle->sgl_index =
-                               phba->fw_config.iscsi_icd_start + arr_index++;
+                               phba->fw_config.iscsi_icd_start[ulp_num] +
+                               arr_index++;
                }
                idx++;
        }
@@ -5022,7 +5035,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
                            "BM_%d : Error getting fw config\n");
                goto free_port;
        }
-       phba->shost->max_id = phba->fw_config.iscsi_cid_count;
+       phba->shost->max_id = phba->params.cxns_per_ctrl;
        beiscsi_get_params(phba);
        phba->shost->can_queue = phba->params.ios_per_ctrl;
        ret = beiscsi_init_port(phba);
index 6ac4f2f5bbaa0a81159109377bbc79a8e2090671..39bc1857adc5482ff50c7f4ab12af7cae010d138 100644 (file)
@@ -271,6 +271,12 @@ struct invalidate_command_table {
 #define chip_be2(phba)      (phba->generation == BE_GEN2)
 #define chip_be3_r(phba)    (phba->generation == BE_GEN3)
 #define is_chip_be2_be3r(phba) (chip_be3_r(phba) || (chip_be2(phba)))
+
+#define BEISCSI_ULP0    0
+#define BEISCSI_ULP1    1
+#define BEISCSI_ULP_COUNT   2
+#define BEISCSI_ULP0_LOADED 0x01
+#define BEISCSI_ULP1_LOADED 0x02
 struct beiscsi_hba {
        struct hba_parameters params;
        struct hwi_controller *phwi_ctrlr;
@@ -328,20 +334,19 @@ struct beiscsi_hba {
                 * group together since they are used most frequently
                 * for cid to cri conversion
                 */
-               unsigned int iscsi_cid_start;
                unsigned int phys_port;
+               unsigned int iscsi_cid_start[BEISCSI_ULP_COUNT];
+#define BEISCSI_GET_CID_COUNT(phba, ulp_num) \
+                             (phba->fw_config.iscsi_cid_count[ulp_num])
+               unsigned int iscsi_cid_count[BEISCSI_ULP_COUNT];
+               unsigned int iscsi_icd_count[BEISCSI_ULP_COUNT];
+               unsigned int iscsi_icd_start[BEISCSI_ULP_COUNT];
+               unsigned int iscsi_chain_start[BEISCSI_ULP_COUNT];
+               unsigned int iscsi_chain_count[BEISCSI_ULP_COUNT];
 
-               unsigned int isr_offset;
-               unsigned int iscsi_icd_start;
-               unsigned int iscsi_cid_count;
-               unsigned int iscsi_icd_count;
-               unsigned int pci_function;
-
-               unsigned short cid_alloc;
-               unsigned short cid_free;
-               unsigned short avlbl_cids;
                unsigned short iscsi_features;
-               spinlock_t cid_lock;
+               uint16_t dual_ulp_aware;
+               unsigned long ulp_supported;
        } fw_config;
 
        unsigned int state;
index 2efad040b6aec3ea52f97e23829a8eb8cbd67a40..c46a60b883eb572cad145872a8f99e9d53376088 100644 (file)
@@ -278,6 +278,18 @@ unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
        return tag;
 }
 
+/**
+ * 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)
 {
@@ -291,31 +303,62 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-                          OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
+                          OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
+                          EMBED_MBX_MAX_PAYLOAD_SIZE);
        status = be_mbox_notify(ctrl);
        if (!status) {
+               uint8_t ulp_num = 0;
                struct be_fw_cfg *pfw_cfg;
                pfw_cfg = req;
+
+               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);
+
                phba->fw_config.phys_port = pfw_cfg->phys_port;
-               phba->fw_config.iscsi_icd_start =
-                                       pfw_cfg->ulp[0].icd_base;
-               phba->fw_config.iscsi_icd_count =
-                                       pfw_cfg->ulp[0].icd_count;
-               phba->fw_config.iscsi_cid_start =
-                                       pfw_cfg->ulp[0].sq_base;
-               phba->fw_config.iscsi_cid_count =
-                                       pfw_cfg->ulp[0].sq_count;
-               if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) {
-                       beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
-                                   "BG_%d : FW reported MAX CXNS as %d\t"
-                                   "Max Supported = %d.\n",
-                                   phba->fw_config.iscsi_cid_count,
-                                   BE2_MAX_SESSIONS);
-                       phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2;
+               for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
+                       if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
+
+                               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"
+                                           "\t iscsi_icd_count : %d\n",
+                                           ulp_num,
+                                           phba->fw_config.
+                                           iscsi_cid_count[ulp_num],
+                                           phba->fw_config.
+                                           iscsi_icd_count[ulp_num]);
+                       }
                }
+
+               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);
+
        } else {
-               beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+               beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
                            "BG_%d : Failed in mgmt_get_fw_config\n");
+               status = -EINVAL;
        }
 
        spin_unlock(&ctrl->mbox_lock);