diff options
author | Jitendra Bhivare <jitendra.bhivare@avagotech.com> | 2016-01-20 03:40:53 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-02-23 21:27:02 -0500 |
commit | 53aefe2552e6efadb0e1a12c2c3adb12105a64f9 (patch) | |
tree | c4e5f79e2744a665099b8ceb34ee260230774e9e /drivers/scsi/be2iscsi/be_cmds.c | |
parent | c9beb6fa14576c4e566696d62f26d748459bac2d (diff) |
be2iscsi: Fix to handle misconfigured optics events
Log messages for misconfigured transceivers reported by FW.
Register async events that driver handles using MCC_CREATE_EXT ioctl.
Errors messages for faulted/uncertified/unqualified optics are logged.
Added IOCTL to get port_name to be displayed in error message.
Signed-off-by: Jitendra Bhivare <jitendra.bhivare@avagotech.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/be2iscsi/be_cmds.c')
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 164 |
1 files changed, 103 insertions, 61 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 66a1fc3f3ddc..533060e12c7f 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -267,26 +267,6 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag) | |||
267 | spin_unlock(&ctrl->mcc_lock); | 267 | spin_unlock(&ctrl->mcc_lock); |
268 | } | 268 | } |
269 | 269 | ||
270 | bool is_link_state_evt(u32 trailer) | ||
271 | { | ||
272 | return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & | ||
273 | ASYNC_TRAILER_EVENT_CODE_MASK) == | ||
274 | ASYNC_EVENT_CODE_LINK_STATE); | ||
275 | } | ||
276 | |||
277 | static bool is_iscsi_evt(u32 trailer) | ||
278 | { | ||
279 | return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & | ||
280 | ASYNC_TRAILER_EVENT_CODE_MASK) == | ||
281 | ASYNC_EVENT_CODE_ISCSI; | ||
282 | } | ||
283 | |||
284 | static int iscsi_evt_type(u32 trailer) | ||
285 | { | ||
286 | return (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) & | ||
287 | ASYNC_TRAILER_EVENT_TYPE_MASK; | ||
288 | } | ||
289 | |||
290 | static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl) | 270 | static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl) |
291 | { | 271 | { |
292 | if (compl->flags != 0) { | 272 | if (compl->flags != 0) { |
@@ -425,7 +405,7 @@ void beiscsi_fail_session(struct iscsi_cls_session *cls_session) | |||
425 | iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); | 405 | iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); |
426 | } | 406 | } |
427 | 407 | ||
428 | void beiscsi_async_link_state_process(struct beiscsi_hba *phba, | 408 | static void beiscsi_async_link_state_process(struct beiscsi_hba *phba, |
429 | struct be_async_event_link_state *evt) | 409 | struct be_async_event_link_state *evt) |
430 | { | 410 | { |
431 | if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) || | 411 | if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) || |
@@ -453,6 +433,100 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba, | |||
453 | } | 433 | } |
454 | } | 434 | } |
455 | 435 | ||
436 | static char *beiscsi_port_misconf_event_msg[] = { | ||
437 | "Physical Link is functional.", | ||
438 | "Optics faulted/incorrectly installed/not installed - Reseat optics, if issue not resolved, replace.", | ||
439 | "Optics of two types installed - Remove one optic or install matching pair of optics.", | ||
440 | "Incompatible optics - Replace with compatible optics for card to function.", | ||
441 | "Unqualified optics - Replace with Avago optics for Warranty and Technical Support.", | ||
442 | "Uncertified optics - Replace with Avago Certified optics to enable link operation." | ||
443 | }; | ||
444 | |||
445 | static void beiscsi_process_async_sli(struct beiscsi_hba *phba, | ||
446 | struct be_mcc_compl *compl) | ||
447 | { | ||
448 | struct be_async_event_sli *async_sli; | ||
449 | u8 evt_type, state, old_state, le; | ||
450 | char *sev = KERN_WARNING; | ||
451 | char *msg = NULL; | ||
452 | |||
453 | evt_type = compl->flags >> ASYNC_TRAILER_EVENT_TYPE_SHIFT; | ||
454 | evt_type &= ASYNC_TRAILER_EVENT_TYPE_MASK; | ||
455 | |||
456 | /* processing only MISCONFIGURED physical port event */ | ||
457 | if (evt_type != ASYNC_SLI_EVENT_TYPE_MISCONFIGURED) | ||
458 | return; | ||
459 | |||
460 | async_sli = (struct be_async_event_sli *)compl; | ||
461 | state = async_sli->event_data1 >> | ||
462 | (phba->fw_config.phys_port * 8) & 0xff; | ||
463 | le = async_sli->event_data2 >> | ||
464 | (phba->fw_config.phys_port * 8) & 0xff; | ||
465 | |||
466 | old_state = phba->optic_state; | ||
467 | phba->optic_state = state; | ||
468 | |||
469 | if (state >= ARRAY_SIZE(beiscsi_port_misconf_event_msg)) { | ||
470 | /* fw is reporting a state we don't know, log and return */ | ||
471 | __beiscsi_log(phba, KERN_ERR, | ||
472 | "BC_%d : Port %c: Unrecognized optic state 0x%x\n", | ||
473 | phba->port_name, async_sli->event_data1); | ||
474 | return; | ||
475 | } | ||
476 | |||
477 | if (ASYNC_SLI_LINK_EFFECT_VALID(le)) { | ||
478 | /* log link effect for unqualified-4, uncertified-5 optics */ | ||
479 | if (state > 3) | ||
480 | msg = (ASYNC_SLI_LINK_EFFECT_STATE(le)) ? | ||
481 | " Link is non-operational." : | ||
482 | " Link is operational."; | ||
483 | /* 1 - info */ | ||
484 | if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 1) | ||
485 | sev = KERN_INFO; | ||
486 | /* 2 - error */ | ||
487 | if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 2) | ||
488 | sev = KERN_ERR; | ||
489 | } | ||
490 | |||
491 | if (old_state != phba->optic_state) | ||
492 | __beiscsi_log(phba, sev, "BC_%d : Port %c: %s%s\n", | ||
493 | phba->port_name, | ||
494 | beiscsi_port_misconf_event_msg[state], | ||
495 | !msg ? "" : msg); | ||
496 | } | ||
497 | |||
498 | void beiscsi_process_async_event(struct beiscsi_hba *phba, | ||
499 | struct be_mcc_compl *compl) | ||
500 | { | ||
501 | char *sev = KERN_INFO; | ||
502 | u8 evt_code; | ||
503 | |||
504 | /* interpret flags as an async trailer */ | ||
505 | evt_code = compl->flags >> ASYNC_TRAILER_EVENT_CODE_SHIFT; | ||
506 | evt_code &= ASYNC_TRAILER_EVENT_CODE_MASK; | ||
507 | switch (evt_code) { | ||
508 | case ASYNC_EVENT_CODE_LINK_STATE: | ||
509 | beiscsi_async_link_state_process(phba, | ||
510 | (struct be_async_event_link_state *)compl); | ||
511 | break; | ||
512 | case ASYNC_EVENT_CODE_ISCSI: | ||
513 | phba->state |= BE_ADAPTER_CHECK_BOOT; | ||
514 | phba->get_boot = BE_GET_BOOT_RETRIES; | ||
515 | sev = KERN_ERR; | ||
516 | break; | ||
517 | case ASYNC_EVENT_CODE_SLI: | ||
518 | beiscsi_process_async_sli(phba, compl); | ||
519 | break; | ||
520 | default: | ||
521 | /* event not registered */ | ||
522 | sev = KERN_ERR; | ||
523 | } | ||
524 | |||
525 | beiscsi_log(phba, sev, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, | ||
526 | "BC_%d : ASYNC Event: status 0x%08x flags 0x%08x\n", | ||
527 | compl->status, compl->flags); | ||
528 | } | ||
529 | |||
456 | int beiscsi_process_mcc(struct beiscsi_hba *phba) | 530 | int beiscsi_process_mcc(struct beiscsi_hba *phba) |
457 | { | 531 | { |
458 | struct be_mcc_compl *compl; | 532 | struct be_mcc_compl *compl; |
@@ -462,45 +536,10 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba) | |||
462 | spin_lock_bh(&phba->ctrl.mcc_cq_lock); | 536 | spin_lock_bh(&phba->ctrl.mcc_cq_lock); |
463 | while ((compl = be_mcc_compl_get(phba))) { | 537 | while ((compl = be_mcc_compl_get(phba))) { |
464 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { | 538 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { |
465 | /* Interpret flags as an async trailer */ | 539 | beiscsi_process_async_event(phba, compl); |
466 | if (is_link_state_evt(compl->flags)) | ||
467 | /* Interpret compl as a async link evt */ | ||
468 | beiscsi_async_link_state_process(phba, | ||
469 | (struct be_async_event_link_state *) compl); | ||
470 | else if (is_iscsi_evt(compl->flags)) { | ||
471 | switch (iscsi_evt_type(compl->flags)) { | ||
472 | case ASYNC_EVENT_NEW_ISCSI_TGT_DISC: | ||
473 | case ASYNC_EVENT_NEW_ISCSI_CONN: | ||
474 | case ASYNC_EVENT_NEW_TCP_CONN: | ||
475 | phba->state |= BE_ADAPTER_CHECK_BOOT; | ||
476 | phba->get_boot = BE_GET_BOOT_RETRIES; | ||
477 | beiscsi_log(phba, KERN_ERR, | ||
478 | BEISCSI_LOG_CONFIG | | ||
479 | BEISCSI_LOG_MBOX, | ||
480 | "BC_%d : Async iscsi Event," | ||
481 | " flags handled = 0x%08x\n", | ||
482 | compl->flags); | ||
483 | break; | ||
484 | default: | ||
485 | phba->state |= BE_ADAPTER_CHECK_BOOT; | ||
486 | phba->get_boot = BE_GET_BOOT_RETRIES; | ||
487 | beiscsi_log(phba, KERN_ERR, | ||
488 | BEISCSI_LOG_CONFIG | | ||
489 | BEISCSI_LOG_MBOX, | ||
490 | "BC_%d : Unsupported Async" | ||
491 | " Event, flags = 0x%08x\n", | ||
492 | compl->flags); | ||
493 | } | ||
494 | } else | ||
495 | beiscsi_log(phba, KERN_ERR, | ||
496 | BEISCSI_LOG_CONFIG | | ||
497 | BEISCSI_LOG_MBOX, | ||
498 | "BC_%d : Unsupported Async Event, flags" | ||
499 | " = 0x%08x\n", compl->flags); | ||
500 | |||
501 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { | 540 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { |
502 | status = be_mcc_compl_process(ctrl, compl); | 541 | status = be_mcc_compl_process(ctrl, compl); |
503 | atomic_dec(&phba->ctrl.mcc_obj.q.used); | 542 | atomic_dec(&phba->ctrl.mcc_obj.q.used); |
504 | } | 543 | } |
505 | be_mcc_compl_use(compl); | 544 | be_mcc_compl_use(compl); |
506 | num++; | 545 | num++; |
@@ -1016,7 +1055,7 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, | |||
1016 | struct be_queue_info *cq) | 1055 | struct be_queue_info *cq) |
1017 | { | 1056 | { |
1018 | struct be_mcc_wrb *wrb; | 1057 | struct be_mcc_wrb *wrb; |
1019 | struct be_cmd_req_mcc_create *req; | 1058 | struct be_cmd_req_mcc_create_ext *req; |
1020 | struct be_dma_mem *q_mem = &mccq->dma_mem; | 1059 | struct be_dma_mem *q_mem = &mccq->dma_mem; |
1021 | struct be_ctrl_info *ctrl; | 1060 | struct be_ctrl_info *ctrl; |
1022 | void *ctxt; | 1061 | void *ctxt; |
@@ -1032,9 +1071,12 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, | |||
1032 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 1071 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
1033 | 1072 | ||
1034 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 1073 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
1035 | OPCODE_COMMON_MCC_CREATE, sizeof(*req)); | 1074 | OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req)); |
1036 | 1075 | ||
1037 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); | 1076 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); |
1077 | req->async_evt_bitmap = 1 << ASYNC_EVENT_CODE_LINK_STATE; | ||
1078 | req->async_evt_bitmap |= 1 << ASYNC_EVENT_CODE_ISCSI; | ||
1079 | req->async_evt_bitmap |= 1 << ASYNC_EVENT_CODE_SLI; | ||
1038 | 1080 | ||
1039 | AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, | 1081 | AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, |
1040 | PCI_FUNC(phba->pcidev->devfn)); | 1082 | PCI_FUNC(phba->pcidev->devfn)); |