mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 09:14:19 +08:00
scsi: hisi_sas: do link reset for some CHL_INT2 ints
We should do link reset of PHY when identify timeout or STP link timeout. They are internal events of SOC and are notified to driver through interrupts of CHL_INT2. Besides, we should add an delay work to do link reset as it needs sleep. So, this patch add an new PHY event HISI_PHYE_LINK_RESET for this. Notes: v2 HW doesn't report the event of STP link timeout. So, we only need to handle event of identify timeout for v2 HW. Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com> Signed-off-by: John Garry <john.garry@huawei.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
e537b62b07
commit
057c3d1f07
@ -126,6 +126,7 @@ enum hisi_sas_bit_err_type {
|
||||
|
||||
enum hisi_sas_phy_event {
|
||||
HISI_PHYE_PHY_UP = 0U,
|
||||
HISI_PHYE_LINK_RESET,
|
||||
HISI_PHYES_NUM,
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,8 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
|
||||
struct domain_device *device,
|
||||
int abort_flag, int tag);
|
||||
static int hisi_sas_softreset_ata_disk(struct domain_device *device);
|
||||
static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
|
||||
void *funcdata);
|
||||
|
||||
u8 hisi_sas_get_ata_protocol(u8 cmd, int direction)
|
||||
{
|
||||
@ -631,8 +633,18 @@ static void hisi_sas_phyup_work(struct work_struct *work)
|
||||
hisi_sas_bytes_dmaed(hisi_hba, phy_no);
|
||||
}
|
||||
|
||||
static void hisi_sas_linkreset_work(struct work_struct *work)
|
||||
{
|
||||
struct hisi_sas_phy *phy =
|
||||
container_of(work, typeof(*phy), works[HISI_PHYE_LINK_RESET]);
|
||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||
|
||||
hisi_sas_control_phy(sas_phy, PHY_FUNC_LINK_RESET, NULL);
|
||||
}
|
||||
|
||||
static const work_func_t hisi_sas_phye_fns[HISI_PHYES_NUM] = {
|
||||
[HISI_PHYE_PHY_UP] = hisi_sas_phyup_work,
|
||||
[HISI_PHYE_LINK_RESET] = hisi_sas_linkreset_work,
|
||||
};
|
||||
|
||||
bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy,
|
||||
|
@ -245,6 +245,7 @@
|
||||
#define CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF 21
|
||||
#define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22
|
||||
#define CHL_INT2 (PORT_BASE + 0x1bc)
|
||||
#define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0
|
||||
#define CHL_INT0_MSK (PORT_BASE + 0x1c0)
|
||||
#define CHL_INT1_MSK (PORT_BASE + 0x1c4)
|
||||
#define CHL_INT2_MSK (PORT_BASE + 0x1c8)
|
||||
@ -1187,7 +1188,7 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
|
||||
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xfff87fff);
|
||||
hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);
|
||||
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xff857fff);
|
||||
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbff);
|
||||
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbfe);
|
||||
hisi_sas_phy_write32(hisi_hba, i, SL_CFG, 0x13f801fc);
|
||||
hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
|
||||
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0);
|
||||
@ -2905,10 +2906,19 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p)
|
||||
CHL_INT1, irq_value1);
|
||||
}
|
||||
|
||||
if ((irq_msk & (1 << phy_no)) && irq_value2)
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no,
|
||||
CHL_INT2, irq_value2);
|
||||
if ((irq_msk & (1 << phy_no)) && irq_value2) {
|
||||
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||
|
||||
if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) {
|
||||
dev_warn(dev, "phy%d identify timeout\n",
|
||||
phy_no);
|
||||
hisi_sas_notify_phy_event(phy,
|
||||
HISI_PHYE_LINK_RESET);
|
||||
}
|
||||
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no,
|
||||
CHL_INT2, irq_value2);
|
||||
}
|
||||
|
||||
if ((irq_msk & (1 << phy_no)) && irq_value0) {
|
||||
if (irq_value0 & CHL_INT0_SL_RX_BCST_ACK_MSK)
|
||||
|
@ -140,6 +140,7 @@
|
||||
#define RX_IDAF_DWORD0 (PORT_BASE + 0xc4)
|
||||
#define RXOP_CHECK_CFG_H (PORT_BASE + 0xfc)
|
||||
#define STP_LINK_TIMER (PORT_BASE + 0x120)
|
||||
#define STP_LINK_TIMEOUT_STATE (PORT_BASE + 0x124)
|
||||
#define CON_CFG_DRIVER (PORT_BASE + 0x130)
|
||||
#define SAS_SSP_CON_TIMER_CFG (PORT_BASE + 0x134)
|
||||
#define SAS_SMP_CON_TIMER_CFG (PORT_BASE + 0x138)
|
||||
@ -165,6 +166,8 @@
|
||||
#define CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF 21
|
||||
#define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22
|
||||
#define CHL_INT2 (PORT_BASE + 0x1bc)
|
||||
#define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0
|
||||
#define CHL_INT2_STP_LINK_TIMEOUT_OFF 31
|
||||
#define CHL_INT0_MSK (PORT_BASE + 0x1c0)
|
||||
#define CHL_INT1_MSK (PORT_BASE + 0x1c4)
|
||||
#define CHL_INT2_MSK (PORT_BASE + 0x1c8)
|
||||
@ -429,7 +432,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
|
||||
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff);
|
||||
hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);
|
||||
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xff87ffff);
|
||||
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x8ffffbff);
|
||||
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe);
|
||||
hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
|
||||
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0);
|
||||
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0);
|
||||
@ -1342,9 +1345,31 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
|
||||
CHL_INT1, irq_value1);
|
||||
}
|
||||
|
||||
if (irq_msk & (8 << (phy_no * 4)) && irq_value2)
|
||||
if (irq_msk & (8 << (phy_no * 4)) && irq_value2) {
|
||||
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||
|
||||
if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) {
|
||||
dev_warn(dev, "phy%d identify timeout\n",
|
||||
phy_no);
|
||||
hisi_sas_notify_phy_event(phy,
|
||||
HISI_PHYE_LINK_RESET);
|
||||
|
||||
}
|
||||
|
||||
if (irq_value2 & BIT(CHL_INT2_STP_LINK_TIMEOUT_OFF)) {
|
||||
u32 reg_value = hisi_sas_phy_read32(hisi_hba,
|
||||
phy_no, STP_LINK_TIMEOUT_STATE);
|
||||
|
||||
dev_warn(dev, "phy%d stp link timeout (0x%x)\n",
|
||||
phy_no, reg_value);
|
||||
if (reg_value & BIT(4))
|
||||
hisi_sas_notify_phy_event(phy,
|
||||
HISI_PHYE_LINK_RESET);
|
||||
}
|
||||
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no,
|
||||
CHL_INT2, irq_value2);
|
||||
}
|
||||
|
||||
|
||||
if (irq_msk & (2 << (phy_no * 4)) && irq_value0) {
|
||||
|
Loading…
Reference in New Issue
Block a user