aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas.h1
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v3_hw.c84
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
1583static 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
1579static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) 1616static 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
2234static 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
2259static int disable_host_v3_hw(struct hisi_hba *hisi_hba) 2293static 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;