aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@broadcom.com>2016-07-06 15:35:56 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-07-15 15:25:06 -0400
commit65791f1f90aade6a02877f9bb7c63f67b35f138c (patch)
treeaffa17a63c28bf9836c82d69d07025c38bc1749e
parent6c92d1d0ce4efffc67ba6f4ce0c7f970c15af390 (diff)
lpfc: Add recovery from adapter parity errors on some SLI4 adapters
Add recovery from adapter parity errors on some SLI4 adapters Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/lpfc/lpfc.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h23
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c118
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c45
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h2
5 files changed, 155 insertions, 35 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index c6ade9bb5280..64d6e3399a68 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -647,6 +647,7 @@ struct lpfc_hba {
647#define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */ 647#define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */
648#define HBA_FCP_IOQ_FLUSH 0x8000 /* FCP I/O queues being flushed */ 648#define HBA_FCP_IOQ_FLUSH 0x8000 /* FCP I/O queues being flushed */
649#define HBA_FW_DUMP_OP 0x10000 /* Skips fn reset before FW dump */ 649#define HBA_FW_DUMP_OP 0x10000 /* Skips fn reset before FW dump */
650#define HBA_RECOVERABLE_UE 0x20000 /* Firmware supports recoverable UE */
650 uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ 651 uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
651 struct lpfc_dmabuf slim2p; 652 struct lpfc_dmabuf slim2p;
652 653
@@ -827,6 +828,7 @@ struct lpfc_hba {
827 828
828 struct timer_list fcp_poll_timer; 829 struct timer_list fcp_poll_timer;
829 struct timer_list eratt_poll; 830 struct timer_list eratt_poll;
831 uint32_t eratt_poll_interval;
830 832
831 /* 833 /*
832 * stat counters 834 * stat counters
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 8a5e08dd9f99..8738b3dc87f1 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -544,6 +544,8 @@ struct lpfc_register {
544 uint32_t word0; 544 uint32_t word0;
545}; 545};
546 546
547#define LPFC_PORT_SEM_UE_RECOVERABLE 0xE000
548#define LPFC_PORT_SEM_MASK 0xF000
547/* The following BAR0 Registers apply to SLI4 if_type 0 UCNAs. */ 549/* The following BAR0 Registers apply to SLI4 if_type 0 UCNAs. */
548#define LPFC_UERR_STATUS_HI 0x00A4 550#define LPFC_UERR_STATUS_HI 0x00A4
549#define LPFC_UERR_STATUS_LO 0x00A0 551#define LPFC_UERR_STATUS_LO 0x00A0
@@ -937,6 +939,7 @@ struct mbox_header {
937#define LPFC_MBOX_OPCODE_READ_OBJECT_LIST 0xAD 939#define LPFC_MBOX_OPCODE_READ_OBJECT_LIST 0xAD
938#define LPFC_MBOX_OPCODE_DELETE_OBJECT 0xAE 940#define LPFC_MBOX_OPCODE_DELETE_OBJECT 0xAE
939#define LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS 0xB5 941#define LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS 0xB5
942#define LPFC_MBOX_OPCODE_SET_FEATURES 0xBF
940 943
941/* FCoE Opcodes */ 944/* FCoE Opcodes */
942#define LPFC_MBOX_OPCODE_FCOE_WQ_CREATE 0x01 945#define LPFC_MBOX_OPCODE_FCOE_WQ_CREATE 0x01
@@ -2887,6 +2890,25 @@ struct lpfc_sli4_parameters {
2887#define cfg_ext_embed_cb_WORD word19 2890#define cfg_ext_embed_cb_WORD word19
2888}; 2891};
2889 2892
2893#define LPFC_SET_UE_RECOVERY 0x10
2894struct lpfc_mbx_set_feature {
2895 struct mbox_header header;
2896 uint32_t feature;
2897 uint32_t param_len;
2898 uint32_t word6;
2899#define lpfc_mbx_set_feature_UER_SHIFT 0
2900#define lpfc_mbx_set_feature_UER_MASK 0x00000001
2901#define lpfc_mbx_set_feature_UER_WORD word6
2902 uint32_t word7;
2903#define lpfc_mbx_set_feature_UERP_SHIFT 0
2904#define lpfc_mbx_set_feature_UERP_MASK 0x0000ffff
2905#define lpfc_mbx_set_feature_UERP_WORD word7
2906#define lpfc_mbx_set_feature_UESR_SHIFT 16
2907#define lpfc_mbx_set_feature_UESR_MASK 0x0000ffff
2908#define lpfc_mbx_set_feature_UESR_WORD word7
2909};
2910
2911
2890struct lpfc_mbx_get_sli4_parameters { 2912struct lpfc_mbx_get_sli4_parameters {
2891 struct mbox_header header; 2913 struct mbox_header header;
2892 struct lpfc_sli4_parameters sli4_parameters; 2914 struct lpfc_sli4_parameters sli4_parameters;
@@ -3279,6 +3301,7 @@ struct lpfc_mqe {
3279 struct lpfc_mbx_get_prof_cfg get_prof_cfg; 3301 struct lpfc_mbx_get_prof_cfg get_prof_cfg;
3280 struct lpfc_mbx_wr_object wr_object; 3302 struct lpfc_mbx_wr_object wr_object;
3281 struct lpfc_mbx_get_port_name get_port_name; 3303 struct lpfc_mbx_get_port_name get_port_name;
3304 struct lpfc_mbx_set_feature set_feature;
3282 struct lpfc_mbx_memory_dump_type3 mem_dump_type3; 3305 struct lpfc_mbx_memory_dump_type3 mem_dump_type3;
3283 struct lpfc_mbx_nop nop; 3306 struct lpfc_mbx_nop nop;
3284 } un; 3307 } un;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index bce73b496421..f11e33ee4132 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -568,7 +568,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
568 phba->last_completion_time = jiffies; 568 phba->last_completion_time = jiffies;
569 /* Set up error attention (ERATT) polling timer */ 569 /* Set up error attention (ERATT) polling timer */
570 mod_timer(&phba->eratt_poll, 570 mod_timer(&phba->eratt_poll,
571 jiffies + msecs_to_jiffies(1000 * LPFC_ERATT_POLL_INTERVAL)); 571 jiffies + msecs_to_jiffies(1000 * phba->eratt_poll_interval));
572 572
573 if (phba->hba_flag & LINK_DISABLED) { 573 if (phba->hba_flag & LINK_DISABLED) {
574 lpfc_printf_log(phba, 574 lpfc_printf_log(phba,
@@ -1587,35 +1587,38 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action,
1587 int rc; 1587 int rc;
1588 uint32_t intr_mode; 1588 uint32_t intr_mode;
1589 1589
1590 /* 1590 if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
1591 * On error status condition, driver need to wait for port 1591 LPFC_SLI_INTF_IF_TYPE_2) {
1592 * ready before performing reset. 1592 /*
1593 */ 1593 * On error status condition, driver need to wait for port
1594 rc = lpfc_sli4_pdev_status_reg_wait(phba); 1594 * ready before performing reset.
1595 if (!rc) { 1595 */
1596 /* need reset: attempt for port recovery */ 1596 rc = lpfc_sli4_pdev_status_reg_wait(phba);
1597 if (en_rn_msg) 1597 if (!rc)
1598 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 1598 return rc;
1599 "2887 Reset Needed: Attempting Port " 1599 }
1600 "Recovery...\n"); 1600 /* need reset: attempt for port recovery */
1601 lpfc_offline_prep(phba, mbx_action); 1601 if (en_rn_msg)
1602 lpfc_offline(phba); 1602 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1603 /* release interrupt for possible resource change */ 1603 "2887 Reset Needed: Attempting Port "
1604 lpfc_sli4_disable_intr(phba); 1604 "Recovery...\n");
1605 lpfc_sli_brdrestart(phba); 1605 lpfc_offline_prep(phba, mbx_action);
1606 /* request and enable interrupt */ 1606 lpfc_offline(phba);
1607 intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode); 1607 /* release interrupt for possible resource change */
1608 if (intr_mode == LPFC_INTR_ERROR) { 1608 lpfc_sli4_disable_intr(phba);
1609 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 1609 lpfc_sli_brdrestart(phba);
1610 "3175 Failed to enable interrupt\n"); 1610 /* request and enable interrupt */
1611 return -EIO; 1611 intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode);
1612 } else { 1612 if (intr_mode == LPFC_INTR_ERROR) {
1613 phba->intr_mode = intr_mode; 1613 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1614 } 1614 "3175 Failed to enable interrupt\n");
1615 rc = lpfc_online(phba); 1615 return -EIO;
1616 if (rc == 0)
1617 lpfc_unblock_mgmt_io(phba);
1618 } 1616 }
1617 phba->intr_mode = intr_mode;
1618 rc = lpfc_online(phba);
1619 if (rc == 0)
1620 lpfc_unblock_mgmt_io(phba);
1621
1619 return rc; 1622 return rc;
1620} 1623}
1621 1624
@@ -1636,10 +1639,11 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
1636 struct lpfc_register portstat_reg = {0}; 1639 struct lpfc_register portstat_reg = {0};
1637 uint32_t reg_err1, reg_err2; 1640 uint32_t reg_err1, reg_err2;
1638 uint32_t uerrlo_reg, uemasklo_reg; 1641 uint32_t uerrlo_reg, uemasklo_reg;
1639 uint32_t pci_rd_rc1, pci_rd_rc2; 1642 uint32_t smphr_port_status = 0, pci_rd_rc1, pci_rd_rc2;
1640 bool en_rn_msg = true; 1643 bool en_rn_msg = true;
1641 struct temp_event temp_event_data; 1644 struct temp_event temp_event_data;
1642 int rc; 1645 struct lpfc_register portsmphr_reg;
1646 int rc, i;
1643 1647
1644 /* If the pci channel is offline, ignore possible errors, since 1648 /* If the pci channel is offline, ignore possible errors, since
1645 * we cannot communicate with the pci card anyway. 1649 * we cannot communicate with the pci card anyway.
@@ -1647,6 +1651,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
1647 if (pci_channel_offline(phba->pcidev)) 1651 if (pci_channel_offline(phba->pcidev))
1648 return; 1652 return;
1649 1653
1654 memset(&portsmphr_reg, 0, sizeof(portsmphr_reg));
1650 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); 1655 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
1651 switch (if_type) { 1656 switch (if_type) {
1652 case LPFC_SLI_INTF_IF_TYPE_0: 1657 case LPFC_SLI_INTF_IF_TYPE_0:
@@ -1659,6 +1664,55 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
1659 /* consider PCI bus read error as pci_channel_offline */ 1664 /* consider PCI bus read error as pci_channel_offline */
1660 if (pci_rd_rc1 == -EIO && pci_rd_rc2 == -EIO) 1665 if (pci_rd_rc1 == -EIO && pci_rd_rc2 == -EIO)
1661 return; 1666 return;
1667 if (!(phba->hba_flag & HBA_RECOVERABLE_UE)) {
1668 lpfc_sli4_offline_eratt(phba);
1669 return;
1670 }
1671 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1672 "7623 Checking UE recoverable");
1673
1674 for (i = 0; i < phba->sli4_hba.ue_to_sr / 1000; i++) {
1675 if (lpfc_readl(phba->sli4_hba.PSMPHRregaddr,
1676 &portsmphr_reg.word0))
1677 continue;
1678
1679 smphr_port_status = bf_get(lpfc_port_smphr_port_status,
1680 &portsmphr_reg);
1681 if ((smphr_port_status & LPFC_PORT_SEM_MASK) ==
1682 LPFC_PORT_SEM_UE_RECOVERABLE)
1683 break;
1684 /*Sleep for 1Sec, before checking SEMAPHORE */
1685 msleep(1000);
1686 }
1687
1688 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1689 "4827 smphr_port_status x%x : Waited %dSec",
1690 smphr_port_status, i);
1691
1692 /* Recoverable UE, reset the HBA device */
1693 if ((smphr_port_status & LPFC_PORT_SEM_MASK) ==
1694 LPFC_PORT_SEM_UE_RECOVERABLE) {
1695 for (i = 0; i < 20; i++) {
1696 msleep(1000);
1697 if (!lpfc_readl(phba->sli4_hba.PSMPHRregaddr,
1698 &portsmphr_reg.word0) &&
1699 (LPFC_POST_STAGE_PORT_READY ==
1700 bf_get(lpfc_port_smphr_port_status,
1701 &portsmphr_reg))) {
1702 rc = lpfc_sli4_port_sta_fn_reset(phba,
1703 LPFC_MBX_NO_WAIT, en_rn_msg);
1704 if (rc == 0)
1705 return;
1706 lpfc_printf_log(phba,
1707 KERN_ERR, LOG_INIT,
1708 "4215 Failed to recover UE");
1709 break;
1710 }
1711 }
1712 }
1713 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1714 "7624 Firmware not ready: Failing UE recovery,"
1715 " waited %dSec", i);
1662 lpfc_sli4_offline_eratt(phba); 1716 lpfc_sli4_offline_eratt(phba);
1663 break; 1717 break;
1664 1718
@@ -5365,6 +5419,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
5365 goto out_free_bsmbx; 5419 goto out_free_bsmbx;
5366 } 5420 }
5367 } 5421 }
5422
5368 /* 5423 /*
5369 * Get sli4 parameters that override parameters from Port capabilities. 5424 * Get sli4 parameters that override parameters from Port capabilities.
5370 * If this call fails, it isn't critical unless the SLI4 parameters come 5425 * If this call fails, it isn't critical unless the SLI4 parameters come
@@ -6093,6 +6148,7 @@ lpfc_hba_alloc(struct pci_dev *pdev)
6093 kfree(phba); 6148 kfree(phba);
6094 return NULL; 6149 return NULL;
6095 } 6150 }
6151 phba->eratt_poll_interval = LPFC_ERATT_POLL_INTERVAL;
6096 6152
6097 spin_lock_init(&phba->ct_ev_lock); 6153 spin_lock_init(&phba->ct_ev_lock);
6098 INIT_LIST_HEAD(&phba->ct_ev_waiters); 6154 INIT_LIST_HEAD(&phba->ct_ev_waiters);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 70edf21ae1b9..b3a781d38fa8 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2947,8 +2947,8 @@ void lpfc_poll_eratt(unsigned long ptr)
2947 else 2947 else
2948 cnt = (sli_intr - phba->sli.slistat.sli_prev_intr); 2948 cnt = (sli_intr - phba->sli.slistat.sli_prev_intr);
2949 2949
2950 /* 64-bit integer division not supporte on 32-bit x86 - use do_div */ 2950 /* 64-bit integer division not supported on 32-bit x86 - use do_div */
2951 do_div(cnt, LPFC_ERATT_POLL_INTERVAL); 2951 do_div(cnt, phba->eratt_poll_interval);
2952 phba->sli.slistat.sli_ips = cnt; 2952 phba->sli.slistat.sli_ips = cnt;
2953 2953
2954 phba->sli.slistat.sli_prev_intr = sli_intr; 2954 phba->sli.slistat.sli_prev_intr = sli_intr;
@@ -2963,7 +2963,7 @@ void lpfc_poll_eratt(unsigned long ptr)
2963 /* Restart the timer for next eratt poll */ 2963 /* Restart the timer for next eratt poll */
2964 mod_timer(&phba->eratt_poll, 2964 mod_timer(&phba->eratt_poll,
2965 jiffies + 2965 jiffies +
2966 msecs_to_jiffies(1000 * LPFC_ERATT_POLL_INTERVAL)); 2966 msecs_to_jiffies(1000 * phba->eratt_poll_interval));
2967 return; 2967 return;
2968} 2968}
2969 2969
@@ -5690,6 +5690,40 @@ lpfc_sli4_dealloc_extent(struct lpfc_hba *phba, uint16_t type)
5690 return rc; 5690 return rc;
5691} 5691}
5692 5692
5693void
5694lpfc_set_features(struct lpfc_hba *phba)
5695{
5696 LPFC_MBOXQ_t *mbox = NULL;
5697 uint32_t len;
5698 int rc;
5699
5700 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
5701 if (!mbox)
5702 return;
5703 len = sizeof(struct lpfc_mbx_set_feature) -
5704 sizeof(struct lpfc_sli4_cfg_mhdr);
5705 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
5706 LPFC_MBOX_OPCODE_SET_FEATURES, len,
5707 LPFC_SLI4_MBX_EMBED);
5708 bf_set(lpfc_mbx_set_feature_UER,
5709 &mbox->u.mqe.un.set_feature, 1);
5710 mbox->u.mqe.un.set_feature.feature = LPFC_SET_UE_RECOVERY;
5711 mbox->u.mqe.un.set_feature.param_len = 8;
5712 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
5713
5714 if (rc != MBX_SUCCESS) {
5715 mempool_free(mbox, phba->mbox_mem_pool);
5716 return;
5717 }
5718 phba->hba_flag |= HBA_RECOVERABLE_UE;
5719 phba->eratt_poll_interval = 1; /* Set 1Sec interval to detect UE */
5720 phba->sli4_hba.ue_to_sr = bf_get(lpfc_mbx_set_feature_UESR,
5721 &mbox->u.mqe.un.set_feature);
5722 phba->sli4_hba.ue_to_rp = bf_get(lpfc_mbx_set_feature_UERP,
5723 &mbox->u.mqe.un.set_feature);
5724 mempool_free(mbox, phba->mbox_mem_pool);
5725}
5726
5693/** 5727/**
5694 * lpfc_sli4_alloc_resource_identifiers - Allocate all SLI4 resource extents. 5728 * lpfc_sli4_alloc_resource_identifiers - Allocate all SLI4 resource extents.
5695 * @phba: Pointer to HBA context object. 5729 * @phba: Pointer to HBA context object.
@@ -6414,6 +6448,9 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
6414 phba->pport->cfg_lun_queue_depth = rc; 6448 phba->pport->cfg_lun_queue_depth = rc;
6415 } 6449 }
6416 6450
6451 if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
6452 LPFC_SLI_INTF_IF_TYPE_0)
6453 lpfc_set_features(phba);
6417 6454
6418 /* 6455 /*
6419 * Discover the port's supported feature set and match it against the 6456 * Discover the port's supported feature set and match it against the
@@ -6612,7 +6649,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
6612 6649
6613 /* Start error attention (ERATT) polling timer */ 6650 /* Start error attention (ERATT) polling timer */
6614 mod_timer(&phba->eratt_poll, 6651 mod_timer(&phba->eratt_poll,
6615 jiffies + msecs_to_jiffies(1000 * LPFC_ERATT_POLL_INTERVAL)); 6652 jiffies + msecs_to_jiffies(1000 * phba->eratt_poll_interval));
6616 6653
6617 /* Enable PCIe device Advanced Error Reporting (AER) if configured */ 6654 /* Enable PCIe device Advanced Error Reporting (AER) if configured */
6618 if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) { 6655 if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) {
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index cd780c29495a..1f45723a21ed 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -511,6 +511,8 @@ struct lpfc_sli4_hba {
511 511
512 uint32_t ue_mask_lo; 512 uint32_t ue_mask_lo;
513 uint32_t ue_mask_hi; 513 uint32_t ue_mask_hi;
514 uint32_t ue_to_sr;
515 uint32_t ue_to_rp;
514 struct lpfc_register sli_intf; 516 struct lpfc_register sli_intf;
515 struct lpfc_pc_sli4_params pc_sli4_params; 517 struct lpfc_pc_sli4_params pc_sli4_params;
516 struct msix_entry *msix_entries; 518 struct msix_entry *msix_entries;