aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJitendra Bhivare <jitendra.bhivare@broadcom.com>2016-08-19 05:50:14 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-08-23 22:42:43 -0400
commit6694095b5a28c54d9fd114997e483cdc47a2e792 (patch)
tree07a93f2f35cddeaf7485b0c82aa2da2cfae414e8
parent10bcd47dff496206de68223aeb1a581bccad03d3 (diff)
scsi: be2iscsi: Add IOCTL to check UER supported
BE3 and SH cards can recover from transient parity errors treated earlier as unrecoverable errors. Add IOCTL to query FW support for this feature. Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c58
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h34
-rw-r--r--drivers/scsi/be2iscsi/be_main.c1
-rw-r--r--drivers/scsi/be2iscsi/be_main.h13
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c2
5 files changed, 89 insertions, 19 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 7cb009e0030e..a246abebb1de 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -277,11 +277,10 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
277static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl, 277static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl,
278 struct be_mcc_compl *compl) 278 struct be_mcc_compl *compl)
279{ 279{
280 u16 compl_status, extd_status;
281 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); 280 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
282 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); 281 struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
283 struct be_cmd_req_hdr *hdr = embedded_payload(wrb); 282 struct be_cmd_req_hdr *hdr = embedded_payload(wrb);
284 struct be_cmd_resp_hdr *resp_hdr; 283 u16 compl_status, extd_status;
285 284
286 /** 285 /**
287 * To check if valid bit is set, check the entire word as we don't know 286 * To check if valid bit is set, check the entire word as we don't know
@@ -315,14 +314,7 @@ static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl,
315 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 314 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
316 "BC_%d : error in cmd completion: Subsystem : %d Opcode : %d status(compl/extd)=%d/%d\n", 315 "BC_%d : error in cmd completion: Subsystem : %d Opcode : %d status(compl/extd)=%d/%d\n",
317 hdr->subsystem, hdr->opcode, compl_status, extd_status); 316 hdr->subsystem, hdr->opcode, compl_status, extd_status);
318 317 return compl_status;
319 if (compl_status == MCC_STATUS_INSUFFICIENT_BUFFER) {
320 /* if status is insufficient buffer, check the length */
321 resp_hdr = (struct be_cmd_resp_hdr *) hdr;
322 if (resp_hdr->response_length)
323 return 0;
324 }
325 return -EINVAL;
326} 318}
327 319
328static void beiscsi_process_async_link(struct beiscsi_hba *phba, 320static void beiscsi_process_async_link(struct beiscsi_hba *phba,
@@ -507,10 +499,8 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
507 if (ctrl->ptag_state[tag].cbfn) 499 if (ctrl->ptag_state[tag].cbfn)
508 ctrl->ptag_state[tag].cbfn(phba, tag); 500 ctrl->ptag_state[tag].cbfn(phba, tag);
509 else 501 else
510 beiscsi_log(phba, KERN_ERR, 502 __beiscsi_log(phba, KERN_ERR,
511 BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT | 503 "BC_%d : MBX ASYNC command with no callback\n");
512 BEISCSI_LOG_CONFIG,
513 "BC_%d : MBX ASYNC command with no callback\n");
514 free_mcc_wrb(ctrl, tag); 504 free_mcc_wrb(ctrl, tag);
515 return 0; 505 return 0;
516 } 506 }
@@ -1371,3 +1361,43 @@ int be_cmd_set_vlan(struct beiscsi_hba *phba,
1371 1361
1372 return tag; 1362 return tag;
1373} 1363}
1364
1365int beiscsi_set_uer_feature(struct beiscsi_hba *phba)
1366{
1367 struct be_ctrl_info *ctrl = &phba->ctrl;
1368 struct be_cmd_set_features *ioctl;
1369 struct be_mcc_wrb *wrb;
1370 int ret = 0;
1371
1372 mutex_lock(&ctrl->mbox_lock);
1373 wrb = wrb_from_mbox(&ctrl->mbox_mem);
1374 memset(wrb, 0, sizeof(*wrb));
1375 ioctl = embedded_payload(wrb);
1376
1377 be_wrb_hdr_prepare(wrb, sizeof(*ioctl), true, 0);
1378 be_cmd_hdr_prepare(&ioctl->h.req_hdr, CMD_SUBSYSTEM_COMMON,
1379 OPCODE_COMMON_SET_FEATURES,
1380 EMBED_MBX_MAX_PAYLOAD_SIZE);
1381 ioctl->feature = BE_CMD_SET_FEATURE_UER;
1382 ioctl->param_len = sizeof(ioctl->param.req);
1383 ioctl->param.req.uer = BE_CMD_UER_SUPP_BIT;
1384 ret = be_mbox_notify(ctrl);
1385 if (!ret) {
1386 phba->ue2rp = ioctl->param.resp.ue2rp;
1387 set_bit(BEISCSI_HBA_UER_SUPP, &phba->state);
1388 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
1389 "BG_%d : HBA error recovery supported\n");
1390 } else {
1391 /**
1392 * Check "MCC_STATUS_INVALID_LENGTH" for SKH.
1393 * Older FW versions return this error.
1394 */
1395 if (ret == MCC_STATUS_ILLEGAL_REQUEST ||
1396 ret == MCC_STATUS_INVALID_LENGTH)
1397 __beiscsi_log(phba, KERN_INFO,
1398 "BG_%d : HBA error recovery not supported\n");
1399 }
1400
1401 mutex_unlock(&ctrl->mbox_lock);
1402 return ret;
1403}
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 6fb9673248b3..f1356c941e44 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -57,6 +57,7 @@ struct be_mcc_wrb {
57#define MCC_STATUS_ILLEGAL_REQUEST 0x2 57#define MCC_STATUS_ILLEGAL_REQUEST 0x2
58#define MCC_STATUS_ILLEGAL_FIELD 0x3 58#define MCC_STATUS_ILLEGAL_FIELD 0x3
59#define MCC_STATUS_INSUFFICIENT_BUFFER 0x4 59#define MCC_STATUS_INSUFFICIENT_BUFFER 0x4
60#define MCC_STATUS_INVALID_LENGTH 0x74
60 61
61#define CQE_STATUS_COMPL_MASK 0xFFFF 62#define CQE_STATUS_COMPL_MASK 0xFFFF
62#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ 63#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */
@@ -217,6 +218,7 @@ struct be_mcc_mailbox {
217#define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58 218#define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58
218#define OPCODE_COMMON_FUNCTION_RESET 61 219#define OPCODE_COMMON_FUNCTION_RESET 61
219#define OPCODE_COMMON_GET_PORT_NAME 77 220#define OPCODE_COMMON_GET_PORT_NAME 77
221#define OPCODE_COMMON_SET_FEATURES 191
220 222
221/** 223/**
222 * LIST of opcodes that are common between Initiator and Target 224 * LIST of opcodes that are common between Initiator and Target
@@ -712,6 +714,8 @@ struct be_cmd_get_nic_conf_resp {
712 u8 mac_address[ETH_ALEN]; 714 u8 mac_address[ETH_ALEN];
713} __packed; 715} __packed;
714 716
717/******************** Get HBA NAME *******************/
718
715#define BEISCSI_ALIAS_LEN 32 719#define BEISCSI_ALIAS_LEN 32
716 720
717struct be_cmd_hba_name { 721struct be_cmd_hba_name {
@@ -722,6 +726,34 @@ struct be_cmd_hba_name {
722 u8 initiator_alias[BEISCSI_ALIAS_LEN]; 726 u8 initiator_alias[BEISCSI_ALIAS_LEN];
723} __packed; 727} __packed;
724 728
729/******************** COMMON SET Features *******************/
730#define BE_CMD_SET_FEATURE_UER 0x10
731#define BE_CMD_UER_SUPP_BIT 0x1
732struct be_uer_req {
733 u32 uer;
734 u32 rsvd;
735};
736
737struct be_uer_resp {
738 u32 uer;
739 u16 ue2rp;
740 u16 ue2sr;
741};
742
743struct be_cmd_set_features {
744 union {
745 struct be_cmd_req_hdr req_hdr;
746 struct be_cmd_resp_hdr resp_hdr;
747 } h;
748 u32 feature;
749 u32 param_len;
750 union {
751 struct be_uer_req req;
752 struct be_uer_resp resp;
753 u32 rsvd[2];
754 } param;
755} __packed;
756
725int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl, 757int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
726 struct be_queue_info *eq, int eq_delay); 758 struct be_queue_info *eq, int eq_delay);
727 759
@@ -795,6 +827,8 @@ int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
795/* Configuration Functions */ 827/* Configuration Functions */
796int be_cmd_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag); 828int be_cmd_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag);
797 829
830int beiscsi_set_uer_feature(struct beiscsi_hba *phba);
831
798struct be_default_pdu_context { 832struct be_default_pdu_context {
799 u32 dw[4]; 833 u32 dw[4];
800} __packed; 834} __packed;
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 3dd4f9d126ae..55dc6439ae64 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5660,6 +5660,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5660 } 5660 }
5661 mgmt_get_port_name(&phba->ctrl, phba); 5661 mgmt_get_port_name(&phba->ctrl, phba);
5662 beiscsi_get_params(phba); 5662 beiscsi_get_params(phba);
5663 beiscsi_set_uer_feature(phba);
5663 5664
5664 if (enable_msix) 5665 if (enable_msix)
5665 find_num_cpus(phba); 5666 find_num_cpus(phba);
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 0d34ac611d2f..0a5de01c3883 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -405,13 +405,17 @@ struct beiscsi_hba {
405#define BEISCSI_HBA_LINK_UP 1 405#define BEISCSI_HBA_LINK_UP 1
406#define BEISCSI_HBA_BOOT_FOUND 2 406#define BEISCSI_HBA_BOOT_FOUND 2
407#define BEISCSI_HBA_BOOT_WORK 3 407#define BEISCSI_HBA_BOOT_WORK 3
408#define BEISCSI_HBA_PCI_ERR 4 408#define BEISCSI_HBA_UER_SUPP 4
409#define BEISCSI_HBA_FW_TIMEOUT 5 409#define BEISCSI_HBA_PCI_ERR 5
410#define BEISCSI_HBA_IN_UE 6 410#define BEISCSI_HBA_FW_TIMEOUT 6
411#define BEISCSI_HBA_IN_UE 7
412#define BEISCSI_HBA_IN_TPE 8
413
411/* error bits */ 414/* error bits */
412#define BEISCSI_HBA_IN_ERR ((1 << BEISCSI_HBA_PCI_ERR) | \ 415#define BEISCSI_HBA_IN_ERR ((1 << BEISCSI_HBA_PCI_ERR) | \
413 (1 << BEISCSI_HBA_FW_TIMEOUT) | \ 416 (1 << BEISCSI_HBA_FW_TIMEOUT) | \
414 (1 << BEISCSI_HBA_IN_UE)) 417 (1 << BEISCSI_HBA_IN_UE) | \
418 (1 << BEISCSI_HBA_IN_TPE))
415 419
416 u8 optic_state; 420 u8 optic_state;
417 struct delayed_work eqd_update; 421 struct delayed_work eqd_update;
@@ -420,6 +424,7 @@ struct beiscsi_hba {
420 struct timer_list hw_check; 424 struct timer_list hw_check;
421 /* check for UE every 1000ms */ 425 /* check for UE every 1000ms */
422#define BEISCSI_UE_DETECT_INTERVAL 1000 426#define BEISCSI_UE_DETECT_INTERVAL 1000
427 u32 ue2rp;
423 428
424 bool mac_addr_set; 429 bool mac_addr_set;
425 u8 mac_address[ETH_ALEN]; 430 u8 mac_address[ETH_ALEN];
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 60a116388467..08d94b014459 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -128,7 +128,7 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba)
128 set_bit(BEISCSI_HBA_IN_UE, &phba->state); 128 set_bit(BEISCSI_HBA_IN_UE, &phba->state);
129 beiscsi_log(phba, KERN_ERR, 129 beiscsi_log(phba, KERN_ERR,
130 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 130 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
131 "BG_%d : Error detected on the adapter\n"); 131 "BG_%d : HBA error detected\n");
132 } 132 }
133 133
134 if (ue_lo) { 134 if (ue_lo) {