aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h14
-rw-r--r--drivers/scsi/be2iscsi/be_main.c63
-rw-r--r--drivers/scsi/be2iscsi/be_main.h27
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c77
4 files changed, 128 insertions, 53 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 89c407377b77..b812e380ef46 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -40,6 +40,7 @@ struct be_mcc_wrb {
40 u32 tag1; /* dword 3 */ 40 u32 tag1; /* dword 3 */
41 u32 rsvd; /* dword 4 */ 41 u32 rsvd; /* dword 4 */
42 union { 42 union {
43#define EMBED_MBX_MAX_PAYLOAD_SIZE 220
43 u8 embedded_payload[236]; /* used by embedded cmds */ 44 u8 embedded_payload[236]; /* used by embedded cmds */
44 struct be_sge sgl[19]; /* used by non-embedded cmds */ 45 struct be_sge sgl[19]; /* used by non-embedded cmds */
45 } payload; 46 } payload;
@@ -1030,6 +1031,7 @@ union tcp_upload_params {
1030} __packed; 1031} __packed;
1031 1032
1032struct be_ulp_fw_cfg { 1033struct be_ulp_fw_cfg {
1034#define BEISCSI_ULP_ISCSI_INI_MODE 0x10
1033 u32 ulp_mode; 1035 u32 ulp_mode;
1034 u32 etx_base; 1036 u32 etx_base;
1035 u32 etx_count; 1037 u32 etx_count;
@@ -1045,14 +1047,26 @@ struct be_ulp_fw_cfg {
1045 u32 icd_count; 1047 u32 icd_count;
1046}; 1048};
1047 1049
1050struct be_ulp_chain_icd {
1051 u32 chain_base;
1052 u32 chain_count;
1053};
1054
1048struct be_fw_cfg { 1055struct be_fw_cfg {
1049 struct be_cmd_req_hdr hdr; 1056 struct be_cmd_req_hdr hdr;
1050 u32 be_config_number; 1057 u32 be_config_number;
1051 u32 asic_revision; 1058 u32 asic_revision;
1052 u32 phys_port; 1059 u32 phys_port;
1060#define BEISCSI_FUNC_ISCSI_INI_MODE 0x10
1061#define BEISCSI_FUNC_DUA_MODE 0x800
1053 u32 function_mode; 1062 u32 function_mode;
1054 struct be_ulp_fw_cfg ulp[2]; 1063 struct be_ulp_fw_cfg ulp[2];
1055 u32 function_caps; 1064 u32 function_caps;
1065 u32 cqid_base;
1066 u32 cqid_count;
1067 u32 eqid_base;
1068 u32 eqid_count;
1069 struct be_ulp_chain_icd chain_icd[2];
1056} __packed; 1070} __packed;
1057 1071
1058struct be_cmd_get_all_if_id_req { 1072struct be_cmd_get_all_if_id_req {
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 6ad36af4654a..2bea0762c14f 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -699,30 +699,38 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev)
699 return status; 699 return status;
700} 700}
701 701
702/**
703 * beiscsi_get_params()- Set the config paramters
704 * @phba: ptr device priv structure
705 **/
702static void beiscsi_get_params(struct beiscsi_hba *phba) 706static void beiscsi_get_params(struct beiscsi_hba *phba)
703{ 707{
704 phba->params.ios_per_ctrl = (phba->fw_config.iscsi_icd_count 708 uint32_t total_cid_count = 0;
705 - (phba->fw_config.iscsi_cid_count 709 uint32_t total_icd_count = 0;
706 + BE2_TMFS 710 uint8_t ulp_num = 0;
707 + BE2_NOPOUT_REQ)); 711
708 phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; 712 total_cid_count = BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP0) +
709 phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count; 713 BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP1);
710 phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count; 714
715 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
716 if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
717 total_icd_count = phba->fw_config.
718 iscsi_icd_count[ulp_num];
719 break;
720 }
721
722 phba->params.ios_per_ctrl = (total_icd_count -
723 (total_cid_count +
724 BE2_TMFS + BE2_NOPOUT_REQ));
725 phba->params.cxns_per_ctrl = total_cid_count;
726 phba->params.asyncpdus_per_ctrl = total_cid_count;
727 phba->params.icds_per_ctrl = total_icd_count;
711 phba->params.num_sge_per_io = BE2_SGE; 728 phba->params.num_sge_per_io = BE2_SGE;
712 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; 729 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
713 phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ; 730 phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ;
714 phba->params.eq_timer = 64; 731 phba->params.eq_timer = 64;
715 phba->params.num_eq_entries = 732 phba->params.num_eq_entries = 1024;
716 (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2 733 phba->params.num_cq_entries = 1024;
717 + BE2_TMFS) / 512) + 1) * 512;
718 phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024)
719 ? 1024 : phba->params.num_eq_entries;
720 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
721 "BM_%d : phba->params.num_eq_entries=%d\n",
722 phba->params.num_eq_entries);
723 phba->params.num_cq_entries =
724 (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2
725 + BE2_TMFS) / 512) + 1) * 512;
726 phba->params.wrbs_per_cxn = 256; 734 phba->params.wrbs_per_cxn = 256;
727} 735}
728 736
@@ -2482,6 +2490,10 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
2482 AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1); 2490 AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1);
2483} 2491}
2484 2492
2493/**
2494 * beiscsi_find_mem_req()- Find mem needed
2495 * @phba: ptr to HBA struct
2496 **/
2485static void beiscsi_find_mem_req(struct beiscsi_hba *phba) 2497static void beiscsi_find_mem_req(struct beiscsi_hba *phba)
2486{ 2498{
2487 unsigned int num_cq_pages, num_async_pdu_buf_pages; 2499 unsigned int num_cq_pages, num_async_pdu_buf_pages;
@@ -2705,7 +2717,7 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
2705 /* Allocate memory for WRBQ */ 2717 /* Allocate memory for WRBQ */
2706 phwi_ctxt = phwi_ctrlr->phwi_ctxt; 2718 phwi_ctxt = phwi_ctrlr->phwi_ctxt;
2707 phwi_ctxt->be_wrbq = kzalloc(sizeof(struct be_queue_info) * 2719 phwi_ctxt->be_wrbq = kzalloc(sizeof(struct be_queue_info) *
2708 phba->fw_config.iscsi_cid_count, 2720 phba->params.cxns_per_ctrl,
2709 GFP_KERNEL); 2721 GFP_KERNEL);
2710 if (!phwi_ctxt->be_wrbq) { 2722 if (!phwi_ctxt->be_wrbq) {
2711 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 2723 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -2804,7 +2816,7 @@ static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
2804 memset(pasync_ctx, 0, sizeof(*pasync_ctx)); 2816 memset(pasync_ctx, 0, sizeof(*pasync_ctx));
2805 2817
2806 pasync_ctx->async_entry = kzalloc(sizeof(struct hwi_async_entry) * 2818 pasync_ctx->async_entry = kzalloc(sizeof(struct hwi_async_entry) *
2807 phba->fw_config.iscsi_cid_count, 2819 phba->params.cxns_per_ctrl,
2808 GFP_KERNEL); 2820 GFP_KERNEL);
2809 if (!pasync_ctx->async_entry) { 2821 if (!pasync_ctx->async_entry) {
2810 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 2822 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -3303,14 +3315,14 @@ beiscsi_post_pages(struct beiscsi_hba *phba)
3303 struct mem_array *pm_arr; 3315 struct mem_array *pm_arr;
3304 unsigned int page_offset, i; 3316 unsigned int page_offset, i;
3305 struct be_dma_mem sgl; 3317 struct be_dma_mem sgl;
3306 int status; 3318 int status, ulp_num = 0;
3307 3319
3308 mem_descr = phba->init_mem; 3320 mem_descr = phba->init_mem;
3309 mem_descr += HWI_MEM_SGE; 3321 mem_descr += HWI_MEM_SGE;
3310 pm_arr = mem_descr->mem_array; 3322 pm_arr = mem_descr->mem_array;
3311 3323
3312 page_offset = (sizeof(struct iscsi_sge) * phba->params.num_sge_per_io * 3324 page_offset = (sizeof(struct iscsi_sge) * phba->params.num_sge_per_io *
3313 phba->fw_config.iscsi_icd_start) / PAGE_SIZE; 3325 phba->fw_config.iscsi_icd_start[ulp_num]) / PAGE_SIZE;
3314 for (i = 0; i < mem_descr->num_elements; i++) { 3326 for (i = 0; i < mem_descr->num_elements; i++) {
3315 hwi_build_be_sgl_arr(phba, pm_arr, &sgl); 3327 hwi_build_be_sgl_arr(phba, pm_arr, &sgl);
3316 status = be_cmd_iscsi_post_sgl_pages(&phba->ctrl, &sgl, 3328 status = be_cmd_iscsi_post_sgl_pages(&phba->ctrl, &sgl,
@@ -3767,7 +3779,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
3767 struct be_mem_descriptor *mem_descr_sglh, *mem_descr_sg; 3779 struct be_mem_descriptor *mem_descr_sglh, *mem_descr_sg;
3768 struct sgl_handle *psgl_handle; 3780 struct sgl_handle *psgl_handle;
3769 struct iscsi_sge *pfrag; 3781 struct iscsi_sge *pfrag;
3770 unsigned int arr_index, i, idx; 3782 unsigned int arr_index, i, idx, ulp_num = 0;
3771 3783
3772 phba->io_sgl_hndl_avbl = 0; 3784 phba->io_sgl_hndl_avbl = 0;
3773 phba->eh_sgl_hndl_avbl = 0; 3785 phba->eh_sgl_hndl_avbl = 0;
@@ -3853,7 +3865,8 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
3853 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0); 3865 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0);
3854 pfrag += phba->params.num_sge_per_io; 3866 pfrag += phba->params.num_sge_per_io;
3855 psgl_handle->sgl_index = 3867 psgl_handle->sgl_index =
3856 phba->fw_config.iscsi_icd_start + arr_index++; 3868 phba->fw_config.iscsi_icd_start[ulp_num] +
3869 arr_index++;
3857 } 3870 }
3858 idx++; 3871 idx++;
3859 } 3872 }
@@ -5022,7 +5035,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5022 "BM_%d : Error getting fw config\n"); 5035 "BM_%d : Error getting fw config\n");
5023 goto free_port; 5036 goto free_port;
5024 } 5037 }
5025 phba->shost->max_id = phba->fw_config.iscsi_cid_count; 5038 phba->shost->max_id = phba->params.cxns_per_ctrl;
5026 beiscsi_get_params(phba); 5039 beiscsi_get_params(phba);
5027 phba->shost->can_queue = phba->params.ios_per_ctrl; 5040 phba->shost->can_queue = phba->params.ios_per_ctrl;
5028 ret = beiscsi_init_port(phba); 5041 ret = beiscsi_init_port(phba);
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 6ac4f2f5bbaa..39bc1857adc5 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -271,6 +271,12 @@ struct invalidate_command_table {
271#define chip_be2(phba) (phba->generation == BE_GEN2) 271#define chip_be2(phba) (phba->generation == BE_GEN2)
272#define chip_be3_r(phba) (phba->generation == BE_GEN3) 272#define chip_be3_r(phba) (phba->generation == BE_GEN3)
273#define is_chip_be2_be3r(phba) (chip_be3_r(phba) || (chip_be2(phba))) 273#define is_chip_be2_be3r(phba) (chip_be3_r(phba) || (chip_be2(phba)))
274
275#define BEISCSI_ULP0 0
276#define BEISCSI_ULP1 1
277#define BEISCSI_ULP_COUNT 2
278#define BEISCSI_ULP0_LOADED 0x01
279#define BEISCSI_ULP1_LOADED 0x02
274struct beiscsi_hba { 280struct beiscsi_hba {
275 struct hba_parameters params; 281 struct hba_parameters params;
276 struct hwi_controller *phwi_ctrlr; 282 struct hwi_controller *phwi_ctrlr;
@@ -328,20 +334,19 @@ struct beiscsi_hba {
328 * group together since they are used most frequently 334 * group together since they are used most frequently
329 * for cid to cri conversion 335 * for cid to cri conversion
330 */ 336 */
331 unsigned int iscsi_cid_start;
332 unsigned int phys_port; 337 unsigned int phys_port;
338 unsigned int iscsi_cid_start[BEISCSI_ULP_COUNT];
339#define BEISCSI_GET_CID_COUNT(phba, ulp_num) \
340 (phba->fw_config.iscsi_cid_count[ulp_num])
341 unsigned int iscsi_cid_count[BEISCSI_ULP_COUNT];
342 unsigned int iscsi_icd_count[BEISCSI_ULP_COUNT];
343 unsigned int iscsi_icd_start[BEISCSI_ULP_COUNT];
344 unsigned int iscsi_chain_start[BEISCSI_ULP_COUNT];
345 unsigned int iscsi_chain_count[BEISCSI_ULP_COUNT];
333 346
334 unsigned int isr_offset;
335 unsigned int iscsi_icd_start;
336 unsigned int iscsi_cid_count;
337 unsigned int iscsi_icd_count;
338 unsigned int pci_function;
339
340 unsigned short cid_alloc;
341 unsigned short cid_free;
342 unsigned short avlbl_cids;
343 unsigned short iscsi_features; 347 unsigned short iscsi_features;
344 spinlock_t cid_lock; 348 uint16_t dual_ulp_aware;
349 unsigned long ulp_supported;
345 } fw_config; 350 } fw_config;
346 351
347 unsigned int state; 352 unsigned int state;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 2efad040b6ae..c46a60b883eb 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -278,6 +278,18 @@ unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
278 return tag; 278 return tag;
279} 279}
280 280
281/**
282 * mgmt_get_fw_config()- Get the FW config for the function
283 * @ctrl: ptr to Ctrl Info
284 * @phba: ptr to the dev priv structure
285 *
286 * Get the FW config and resources available for the function.
287 * The resources are created based on the count received here.
288 *
289 * return
290 * Success: 0
291 * Failure: Non-Zero Value
292 **/
281int mgmt_get_fw_config(struct be_ctrl_info *ctrl, 293int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
282 struct beiscsi_hba *phba) 294 struct beiscsi_hba *phba)
283{ 295{
@@ -291,31 +303,62 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
291 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 303 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
292 304
293 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 305 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
294 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req)); 306 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
307 EMBED_MBX_MAX_PAYLOAD_SIZE);
295 status = be_mbox_notify(ctrl); 308 status = be_mbox_notify(ctrl);
296 if (!status) { 309 if (!status) {
310 uint8_t ulp_num = 0;
297 struct be_fw_cfg *pfw_cfg; 311 struct be_fw_cfg *pfw_cfg;
298 pfw_cfg = req; 312 pfw_cfg = req;
313
314 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
315 if (pfw_cfg->ulp[ulp_num].ulp_mode &
316 BEISCSI_ULP_ISCSI_INI_MODE)
317 set_bit(ulp_num,
318 &phba->fw_config.ulp_supported);
319
299 phba->fw_config.phys_port = pfw_cfg->phys_port; 320 phba->fw_config.phys_port = pfw_cfg->phys_port;
300 phba->fw_config.iscsi_icd_start = 321 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
301 pfw_cfg->ulp[0].icd_base; 322 if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
302 phba->fw_config.iscsi_icd_count = 323
303 pfw_cfg->ulp[0].icd_count; 324 phba->fw_config.iscsi_cid_start[ulp_num] =
304 phba->fw_config.iscsi_cid_start = 325 pfw_cfg->ulp[ulp_num].sq_base;
305 pfw_cfg->ulp[0].sq_base; 326 phba->fw_config.iscsi_cid_count[ulp_num] =
306 phba->fw_config.iscsi_cid_count = 327 pfw_cfg->ulp[ulp_num].sq_count;
307 pfw_cfg->ulp[0].sq_count; 328
308 if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) { 329 phba->fw_config.iscsi_icd_start[ulp_num] =
309 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, 330 pfw_cfg->ulp[ulp_num].icd_base;
310 "BG_%d : FW reported MAX CXNS as %d\t" 331 phba->fw_config.iscsi_icd_count[ulp_num] =
311 "Max Supported = %d.\n", 332 pfw_cfg->ulp[ulp_num].icd_count;
312 phba->fw_config.iscsi_cid_count, 333
313 BE2_MAX_SESSIONS); 334 phba->fw_config.iscsi_chain_start[ulp_num] =
314 phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2; 335 pfw_cfg->chain_icd[ulp_num].chain_base;
336 phba->fw_config.iscsi_chain_count[ulp_num] =
337 pfw_cfg->chain_icd[ulp_num].chain_count;
338
339 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
340 "BG_%d : Function loaded on ULP : %d\n"
341 "\tiscsi_cid_count : %d\n"
342 "\t iscsi_icd_count : %d\n",
343 ulp_num,
344 phba->fw_config.
345 iscsi_cid_count[ulp_num],
346 phba->fw_config.
347 iscsi_icd_count[ulp_num]);
348 }
315 } 349 }
350
351 phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
352 BEISCSI_FUNC_DUA_MODE);
353
354 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
355 "BG_%d : DUA Mode : 0x%x\n",
356 phba->fw_config.dual_ulp_aware);
357
316 } else { 358 } else {
317 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, 359 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
318 "BG_%d : Failed in mgmt_get_fw_config\n"); 360 "BG_%d : Failed in mgmt_get_fw_config\n");
361 status = -EINVAL;
319 } 362 }
320 363
321 spin_unlock(&ctrl->mbox_lock); 364 spin_unlock(&ctrl->mbox_lock);