提交 6694095b 编写于 作者: J Jitendra Bhivare 提交者: Martin K. Petersen

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: NJitendra Bhivare <jitendra.bhivare@broadcom.com>
Reviewed-by: NHannes Reinecke <hare@suse.com>
Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
上级 10bcd47d
...@@ -277,11 +277,10 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba, ...@@ -277,11 +277,10 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl, static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl,
struct be_mcc_compl *compl) struct be_mcc_compl *compl)
{ {
u16 compl_status, extd_status;
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
struct be_cmd_req_hdr *hdr = embedded_payload(wrb); struct be_cmd_req_hdr *hdr = embedded_payload(wrb);
struct be_cmd_resp_hdr *resp_hdr; u16 compl_status, extd_status;
/** /**
* To check if valid bit is set, check the entire word as we don't know * 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,14 +314,7 @@ static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl,
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : error in cmd completion: Subsystem : %d Opcode : %d status(compl/extd)=%d/%d\n", "BC_%d : error in cmd completion: Subsystem : %d Opcode : %d status(compl/extd)=%d/%d\n",
hdr->subsystem, hdr->opcode, compl_status, extd_status); hdr->subsystem, hdr->opcode, compl_status, extd_status);
return compl_status;
if (compl_status == MCC_STATUS_INSUFFICIENT_BUFFER) {
/* if status is insufficient buffer, check the length */
resp_hdr = (struct be_cmd_resp_hdr *) hdr;
if (resp_hdr->response_length)
return 0;
}
return -EINVAL;
} }
static void beiscsi_process_async_link(struct beiscsi_hba *phba, static void beiscsi_process_async_link(struct beiscsi_hba *phba,
...@@ -507,10 +499,8 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl, ...@@ -507,10 +499,8 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
if (ctrl->ptag_state[tag].cbfn) if (ctrl->ptag_state[tag].cbfn)
ctrl->ptag_state[tag].cbfn(phba, tag); ctrl->ptag_state[tag].cbfn(phba, tag);
else else
beiscsi_log(phba, KERN_ERR, __beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT | "BC_%d : MBX ASYNC command with no callback\n");
BEISCSI_LOG_CONFIG,
"BC_%d : MBX ASYNC command with no callback\n");
free_mcc_wrb(ctrl, tag); free_mcc_wrb(ctrl, tag);
return 0; return 0;
} }
...@@ -1371,3 +1361,43 @@ int be_cmd_set_vlan(struct beiscsi_hba *phba, ...@@ -1371,3 +1361,43 @@ int be_cmd_set_vlan(struct beiscsi_hba *phba,
return tag; return tag;
} }
int beiscsi_set_uer_feature(struct beiscsi_hba *phba)
{
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_cmd_set_features *ioctl;
struct be_mcc_wrb *wrb;
int ret = 0;
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_SET_FEATURES,
EMBED_MBX_MAX_PAYLOAD_SIZE);
ioctl->feature = BE_CMD_SET_FEATURE_UER;
ioctl->param_len = sizeof(ioctl->param.req);
ioctl->param.req.uer = BE_CMD_UER_SUPP_BIT;
ret = be_mbox_notify(ctrl);
if (!ret) {
phba->ue2rp = ioctl->param.resp.ue2rp;
set_bit(BEISCSI_HBA_UER_SUPP, &phba->state);
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
"BG_%d : HBA error recovery supported\n");
} else {
/**
* Check "MCC_STATUS_INVALID_LENGTH" for SKH.
* Older FW versions return this error.
*/
if (ret == MCC_STATUS_ILLEGAL_REQUEST ||
ret == MCC_STATUS_INVALID_LENGTH)
__beiscsi_log(phba, KERN_INFO,
"BG_%d : HBA error recovery not supported\n");
}
mutex_unlock(&ctrl->mbox_lock);
return ret;
}
...@@ -57,6 +57,7 @@ struct be_mcc_wrb { ...@@ -57,6 +57,7 @@ struct be_mcc_wrb {
#define MCC_STATUS_ILLEGAL_REQUEST 0x2 #define MCC_STATUS_ILLEGAL_REQUEST 0x2
#define MCC_STATUS_ILLEGAL_FIELD 0x3 #define MCC_STATUS_ILLEGAL_FIELD 0x3
#define MCC_STATUS_INSUFFICIENT_BUFFER 0x4 #define MCC_STATUS_INSUFFICIENT_BUFFER 0x4
#define MCC_STATUS_INVALID_LENGTH 0x74
#define CQE_STATUS_COMPL_MASK 0xFFFF #define CQE_STATUS_COMPL_MASK 0xFFFF
#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ #define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */
...@@ -217,6 +218,7 @@ struct be_mcc_mailbox { ...@@ -217,6 +218,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58 #define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58
#define OPCODE_COMMON_FUNCTION_RESET 61 #define OPCODE_COMMON_FUNCTION_RESET 61
#define OPCODE_COMMON_GET_PORT_NAME 77 #define OPCODE_COMMON_GET_PORT_NAME 77
#define OPCODE_COMMON_SET_FEATURES 191
/** /**
* LIST of opcodes that are common between Initiator and Target * LIST of opcodes that are common between Initiator and Target
...@@ -712,6 +714,8 @@ struct be_cmd_get_nic_conf_resp { ...@@ -712,6 +714,8 @@ struct be_cmd_get_nic_conf_resp {
u8 mac_address[ETH_ALEN]; u8 mac_address[ETH_ALEN];
} __packed; } __packed;
/******************** Get HBA NAME *******************/
#define BEISCSI_ALIAS_LEN 32 #define BEISCSI_ALIAS_LEN 32
struct be_cmd_hba_name { struct be_cmd_hba_name {
...@@ -722,6 +726,34 @@ struct be_cmd_hba_name { ...@@ -722,6 +726,34 @@ struct be_cmd_hba_name {
u8 initiator_alias[BEISCSI_ALIAS_LEN]; u8 initiator_alias[BEISCSI_ALIAS_LEN];
} __packed; } __packed;
/******************** COMMON SET Features *******************/
#define BE_CMD_SET_FEATURE_UER 0x10
#define BE_CMD_UER_SUPP_BIT 0x1
struct be_uer_req {
u32 uer;
u32 rsvd;
};
struct be_uer_resp {
u32 uer;
u16 ue2rp;
u16 ue2sr;
};
struct be_cmd_set_features {
union {
struct be_cmd_req_hdr req_hdr;
struct be_cmd_resp_hdr resp_hdr;
} h;
u32 feature;
u32 param_len;
union {
struct be_uer_req req;
struct be_uer_resp resp;
u32 rsvd[2];
} param;
} __packed;
int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl, int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
struct be_queue_info *eq, int eq_delay); struct be_queue_info *eq, int eq_delay);
...@@ -795,6 +827,8 @@ int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem, ...@@ -795,6 +827,8 @@ int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
/* Configuration Functions */ /* Configuration Functions */
int be_cmd_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag); int be_cmd_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag);
int beiscsi_set_uer_feature(struct beiscsi_hba *phba);
struct be_default_pdu_context { struct be_default_pdu_context {
u32 dw[4]; u32 dw[4];
} __packed; } __packed;
......
...@@ -5660,6 +5660,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, ...@@ -5660,6 +5660,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
} }
mgmt_get_port_name(&phba->ctrl, phba); mgmt_get_port_name(&phba->ctrl, phba);
beiscsi_get_params(phba); beiscsi_get_params(phba);
beiscsi_set_uer_feature(phba);
if (enable_msix) if (enable_msix)
find_num_cpus(phba); find_num_cpus(phba);
......
...@@ -405,13 +405,17 @@ struct beiscsi_hba { ...@@ -405,13 +405,17 @@ struct beiscsi_hba {
#define BEISCSI_HBA_LINK_UP 1 #define BEISCSI_HBA_LINK_UP 1
#define BEISCSI_HBA_BOOT_FOUND 2 #define BEISCSI_HBA_BOOT_FOUND 2
#define BEISCSI_HBA_BOOT_WORK 3 #define BEISCSI_HBA_BOOT_WORK 3
#define BEISCSI_HBA_PCI_ERR 4 #define BEISCSI_HBA_UER_SUPP 4
#define BEISCSI_HBA_FW_TIMEOUT 5 #define BEISCSI_HBA_PCI_ERR 5
#define BEISCSI_HBA_IN_UE 6 #define BEISCSI_HBA_FW_TIMEOUT 6
#define BEISCSI_HBA_IN_UE 7
#define BEISCSI_HBA_IN_TPE 8
/* error bits */ /* error bits */
#define BEISCSI_HBA_IN_ERR ((1 << BEISCSI_HBA_PCI_ERR) | \ #define BEISCSI_HBA_IN_ERR ((1 << BEISCSI_HBA_PCI_ERR) | \
(1 << BEISCSI_HBA_FW_TIMEOUT) | \ (1 << BEISCSI_HBA_FW_TIMEOUT) | \
(1 << BEISCSI_HBA_IN_UE)) (1 << BEISCSI_HBA_IN_UE) | \
(1 << BEISCSI_HBA_IN_TPE))
u8 optic_state; u8 optic_state;
struct delayed_work eqd_update; struct delayed_work eqd_update;
...@@ -420,6 +424,7 @@ struct beiscsi_hba { ...@@ -420,6 +424,7 @@ struct beiscsi_hba {
struct timer_list hw_check; struct timer_list hw_check;
/* check for UE every 1000ms */ /* check for UE every 1000ms */
#define BEISCSI_UE_DETECT_INTERVAL 1000 #define BEISCSI_UE_DETECT_INTERVAL 1000
u32 ue2rp;
bool mac_addr_set; bool mac_addr_set;
u8 mac_address[ETH_ALEN]; u8 mac_address[ETH_ALEN];
......
...@@ -128,7 +128,7 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba) ...@@ -128,7 +128,7 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba)
set_bit(BEISCSI_HBA_IN_UE, &phba->state); set_bit(BEISCSI_HBA_IN_UE, &phba->state);
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : Error detected on the adapter\n"); "BG_%d : HBA error detected\n");
} }
if (ue_lo) { if (ue_lo) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册