diff options
| -rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas.h | 1 | ||||
| -rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 84 |
2 files changed, 60 insertions, 25 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 6c87bd34509a..515aee9318a4 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h | |||
| @@ -161,6 +161,7 @@ struct hisi_sas_phy { | |||
| 161 | u8 in_reset; | 161 | u8 in_reset; |
| 162 | u8 reserved[2]; | 162 | u8 reserved[2]; |
| 163 | u32 phy_type; | 163 | u32 phy_type; |
| 164 | u32 code_violation_err_count; | ||
| 164 | enum sas_linkrate minimum_linkrate; | 165 | enum sas_linkrate minimum_linkrate; |
| 165 | enum sas_linkrate maximum_linkrate; | 166 | enum sas_linkrate maximum_linkrate; |
| 166 | }; | 167 | }; |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 151a102c4cc7..720721196b12 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | |||
| @@ -181,6 +181,8 @@ | |||
| 181 | #define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22 | 181 | #define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22 |
| 182 | #define CHL_INT2 (PORT_BASE + 0x1bc) | 182 | #define CHL_INT2 (PORT_BASE + 0x1bc) |
| 183 | #define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0 | 183 | #define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0 |
| 184 | #define CHL_INT2_RX_DISP_ERR_OFF 28 | ||
| 185 | #define CHL_INT2_RX_CODE_ERR_OFF 29 | ||
| 184 | #define CHL_INT2_RX_INVLD_DW_OFF 30 | 186 | #define CHL_INT2_RX_INVLD_DW_OFF 30 |
| 185 | #define CHL_INT2_STP_LINK_TIMEOUT_OFF 31 | 187 | #define CHL_INT2_STP_LINK_TIMEOUT_OFF 31 |
| 186 | #define CHL_INT0_MSK (PORT_BASE + 0x1c0) | 188 | #define CHL_INT0_MSK (PORT_BASE + 0x1c0) |
| @@ -544,6 +546,8 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) | |||
| 544 | hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120); | 546 | hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120); |
| 545 | hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01); | 547 | hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01); |
| 546 | hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, 0x32); | 548 | hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, 0x32); |
| 549 | hisi_sas_phy_write32(hisi_hba, i, SAS_EC_INT_COAL_TIME, | ||
| 550 | 0x30f4240); | ||
| 547 | /* used for 12G negotiate */ | 551 | /* used for 12G negotiate */ |
| 548 | hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e); | 552 | hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e); |
| 549 | hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff); | 553 | hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff); |
| @@ -1576,6 +1580,39 @@ static void handle_chl_int1_v3_hw(struct hisi_hba *hisi_hba, int phy_no) | |||
| 1576 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT1, irq_value); | 1580 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT1, irq_value); |
| 1577 | } | 1581 | } |
| 1578 | 1582 | ||
| 1583 | static void phy_get_events_v3_hw(struct hisi_hba *hisi_hba, int phy_no) | ||
| 1584 | { | ||
| 1585 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | ||
| 1586 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | ||
| 1587 | struct sas_phy *sphy = sas_phy->phy; | ||
| 1588 | unsigned long flags; | ||
| 1589 | u32 reg_value; | ||
| 1590 | |||
| 1591 | spin_lock_irqsave(&phy->lock, flags); | ||
| 1592 | |||
| 1593 | /* loss dword sync */ | ||
| 1594 | reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DWS_LOST); | ||
| 1595 | sphy->loss_of_dword_sync_count += reg_value; | ||
| 1596 | |||
| 1597 | /* phy reset problem */ | ||
| 1598 | reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_RESET_PROB); | ||
| 1599 | sphy->phy_reset_problem_count += reg_value; | ||
| 1600 | |||
| 1601 | /* invalid dword */ | ||
| 1602 | reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW); | ||
| 1603 | sphy->invalid_dword_count += reg_value; | ||
| 1604 | |||
| 1605 | /* disparity err */ | ||
| 1606 | reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR); | ||
| 1607 | sphy->running_disparity_error_count += reg_value; | ||
| 1608 | |||
| 1609 | /* code violation error */ | ||
| 1610 | reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_CODE_ERR); | ||
| 1611 | phy->code_violation_err_count += reg_value; | ||
| 1612 | |||
| 1613 | spin_unlock_irqrestore(&phy->lock, flags); | ||
| 1614 | } | ||
| 1615 | |||
| 1579 | static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) | 1616 | static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
| 1580 | { | 1617 | { |
| 1581 | u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK); | 1618 | u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK); |
| @@ -1583,6 +1620,9 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) | |||
| 1583 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | 1620 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
| 1584 | struct pci_dev *pci_dev = hisi_hba->pci_dev; | 1621 | struct pci_dev *pci_dev = hisi_hba->pci_dev; |
| 1585 | struct device *dev = hisi_hba->dev; | 1622 | struct device *dev = hisi_hba->dev; |
| 1623 | static const u32 msk = BIT(CHL_INT2_RX_DISP_ERR_OFF) | | ||
| 1624 | BIT(CHL_INT2_RX_CODE_ERR_OFF) | | ||
| 1625 | BIT(CHL_INT2_RX_INVLD_DW_OFF); | ||
| 1586 | 1626 | ||
| 1587 | irq_value &= ~irq_msk; | 1627 | irq_value &= ~irq_msk; |
| 1588 | if (!irq_value) | 1628 | if (!irq_value) |
| @@ -1603,6 +1643,25 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) | |||
| 1603 | hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); | 1643 | hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); |
| 1604 | } | 1644 | } |
| 1605 | 1645 | ||
| 1646 | if (pci_dev->revision > 0x20 && (irq_value & msk)) { | ||
| 1647 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | ||
| 1648 | struct sas_phy *sphy = sas_phy->phy; | ||
| 1649 | |||
| 1650 | phy_get_events_v3_hw(hisi_hba, phy_no); | ||
| 1651 | |||
| 1652 | if (irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) | ||
| 1653 | dev_info(dev, "phy%d invalid dword cnt: %u\n", phy_no, | ||
| 1654 | sphy->invalid_dword_count); | ||
| 1655 | |||
| 1656 | if (irq_value & BIT(CHL_INT2_RX_CODE_ERR_OFF)) | ||
| 1657 | dev_info(dev, "phy%d code violation cnt: %u\n", phy_no, | ||
| 1658 | phy->code_violation_err_count); | ||
| 1659 | |||
| 1660 | if (irq_value & BIT(CHL_INT2_RX_DISP_ERR_OFF)) | ||
| 1661 | dev_info(dev, "phy%d disparity error cnt: %u\n", phy_no, | ||
| 1662 | sphy->running_disparity_error_count); | ||
| 1663 | } | ||
| 1664 | |||
| 1606 | if ((irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) && | 1665 | if ((irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) && |
| 1607 | (pci_dev->revision == 0x20)) { | 1666 | (pci_dev->revision == 0x20)) { |
| 1608 | u32 reg_value; | 1667 | u32 reg_value; |
| @@ -2231,31 +2290,6 @@ static u32 get_phys_state_v3_hw(struct hisi_hba *hisi_hba) | |||
| 2231 | return hisi_sas_read32(hisi_hba, PHY_STATE); | 2290 | return hisi_sas_read32(hisi_hba, PHY_STATE); |
| 2232 | } | 2291 | } |
| 2233 | 2292 | ||
| 2234 | static void phy_get_events_v3_hw(struct hisi_hba *hisi_hba, int phy_no) | ||
| 2235 | { | ||
| 2236 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | ||
| 2237 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | ||
| 2238 | struct sas_phy *sphy = sas_phy->phy; | ||
| 2239 | u32 reg_value; | ||
| 2240 | |||
| 2241 | /* loss dword sync */ | ||
| 2242 | reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DWS_LOST); | ||
| 2243 | sphy->loss_of_dword_sync_count += reg_value; | ||
| 2244 | |||
| 2245 | /* phy reset problem */ | ||
| 2246 | reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_RESET_PROB); | ||
| 2247 | sphy->phy_reset_problem_count += reg_value; | ||
| 2248 | |||
| 2249 | /* invalid dword */ | ||
| 2250 | reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW); | ||
| 2251 | sphy->invalid_dword_count += reg_value; | ||
| 2252 | |||
| 2253 | /* disparity err */ | ||
| 2254 | reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR); | ||
| 2255 | sphy->running_disparity_error_count += reg_value; | ||
| 2256 | |||
| 2257 | } | ||
| 2258 | |||
| 2259 | static int disable_host_v3_hw(struct hisi_hba *hisi_hba) | 2293 | static int disable_host_v3_hw(struct hisi_hba *hisi_hba) |
| 2260 | { | 2294 | { |
| 2261 | struct device *dev = hisi_hba->dev; | 2295 | struct device *dev = hisi_hba->dev; |
