“8d44f2bd7554734913f1256e4f45c35454167161”上不存在“drivers/net/wireless/intel/iwlegacy/debug.c”
提交 6459a1e3 编写于 作者: L luojiaxing 提交者: Xie XiuQi

Fix magic number existed at hisi_sas

we found out some magic number within hisi_sas,
so fix it.

Also, we fix some other bugs as blow:
1. Force ptr type to unsigned long without using uintptr_t
2. Directly use input parameter at some operations
Signed-off-by: NLuo Jiaxing <luojiaxing@huawei.com>

Feature or Bugfix:Bugfix
Signed-off-by: Nluojiaxing <luojiaxing@huawei.com>
Reviewed-by: Nchenxiang <chenxiang66@hisilicon.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 bd937d53
...@@ -96,8 +96,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction) ...@@ -96,8 +96,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
return HISI_SAS_SATA_PROTOCOL_NONDATA; return HISI_SAS_SATA_PROTOCOL_NONDATA;
} }
default: default: {
{
if (direction == DMA_NONE) if (direction == DMA_NONE)
return HISI_SAS_SATA_PROTOCOL_NONDATA; return HISI_SAS_SATA_PROTOCOL_NONDATA;
return HISI_SAS_SATA_PROTOCOL_PIO; return HISI_SAS_SATA_PROTOCOL_PIO;
...@@ -146,9 +145,14 @@ u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max) ...@@ -146,9 +145,14 @@ u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max)
{ {
u8 rate = 0; u8 rate = 0;
int i; int i;
enum sas_linkrate max_linkrate = max;
max -= SAS_LINK_RATE_1_5_GBPS; /*
for (i = 0; i <= max; i++) * One bit represent one kind of link rate,
* So we shift one rate to other by multiply 2.
*/
max_linkrate -= SAS_LINK_RATE_1_5_GBPS;
for (i = 0; i <= max_linkrate; i++)
rate |= 1 << (i * 2); rate |= 1 << (i * 2);
return rate; return rate;
} }
...@@ -746,7 +750,7 @@ static int hisi_sas_init_device(struct domain_device *device) ...@@ -746,7 +750,7 @@ static int hisi_sas_init_device(struct domain_device *device)
case SAS_SATA_PENDING: case SAS_SATA_PENDING:
/* /*
* send HARD RESET to clear previous affiliation of * send HARD RESET to clear previous affiliation of
* STP target port * STP target port, sleep 2s after hard reset
*/ */
local_phy = sas_get_local_phy(device); local_phy = sas_get_local_phy(device);
if (!scsi_is_sas_phy_local(local_phy)) { if (!scsi_is_sas_phy_local(local_phy)) {
...@@ -831,6 +835,12 @@ int hisi_sas_slave_configure(struct scsi_device *sdev) ...@@ -831,6 +835,12 @@ int hisi_sas_slave_configure(struct scsi_device *sdev)
if (ret) if (ret)
return ret; return ret;
/*
* The queue depth for the sdev should be
* set as 64 to avoid SAS_QUEUE_FULL error
* in high-datarate aging tests
*/
if (!dev_is_sata(dev)) if (!dev_is_sata(dev))
sas_change_queue_depth(sdev, 64); sas_change_queue_depth(sdev, 64);
...@@ -1075,6 +1085,7 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, ...@@ -1075,6 +1085,7 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
sas_phy->phy->maximum_linkrate = max; sas_phy->phy->maximum_linkrate = max;
sas_phy->phy->minimum_linkrate = min; sas_phy->phy->minimum_linkrate = min;
hisi_hba->hw->phy_disable(hisi_hba, phy_no); hisi_hba->hw->phy_disable(hisi_hba, phy_no);
/* Sleep 100ms after disable phy to meet hw need */
msleep(100); msleep(100);
hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r); hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r);
hisi_hba->hw->phy_start(hisi_hba, phy_no); hisi_hba->hw->phy_start(hisi_hba, phy_no);
...@@ -1096,6 +1107,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, ...@@ -1096,6 +1107,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
case PHY_FUNC_LINK_RESET: case PHY_FUNC_LINK_RESET:
hisi_hba->hw->phy_disable(hisi_hba, phy_no); hisi_hba->hw->phy_disable(hisi_hba, phy_no);
/* Sleep 100ms after disable phy to meet hw need */
msleep(100); msleep(100);
hisi_hba->hw->phy_start(hisi_hba, phy_no); hisi_hba->hw->phy_start(hisi_hba, phy_no);
break; break;
...@@ -1272,7 +1284,7 @@ static void hisi_sas_fill_ata_reset_cmd(struct ata_device *dev, ...@@ -1272,7 +1284,7 @@ static void hisi_sas_fill_ata_reset_cmd(struct ata_device *dev,
static int hisi_sas_softreset_ata_disk(struct domain_device *device) static int hisi_sas_softreset_ata_disk(struct domain_device *device)
{ {
u8 fis[20] = {0}; struct host_to_dev_fis fis = {};
struct ata_port *ap = device->sata_dev.ap; struct ata_port *ap = device->sata_dev.ap;
struct ata_link *link; struct ata_link *link;
int rc = TMF_RESP_FUNC_FAILED; int rc = TMF_RESP_FUNC_FAILED;
...@@ -1283,8 +1295,8 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device) ...@@ -1283,8 +1295,8 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
ata_for_each_link(link, ap, EDGE) { ata_for_each_link(link, ap, EDGE) {
int pmp = sata_srst_pmp(link); int pmp = sata_srst_pmp(link);
hisi_sas_fill_ata_reset_cmd(link->device, 1, pmp, fis); hisi_sas_fill_ata_reset_cmd(link->device, 1, pmp, (u8 *)&fis);
rc = hisi_sas_exec_internal_tmf_task(device, fis, s, NULL); rc = hisi_sas_exec_internal_tmf_task(device, &fis, s, NULL);
if (rc != TMF_RESP_FUNC_COMPLETE) if (rc != TMF_RESP_FUNC_COMPLETE)
break; break;
} }
...@@ -1293,8 +1305,9 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device) ...@@ -1293,8 +1305,9 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
ata_for_each_link(link, ap, EDGE) { ata_for_each_link(link, ap, EDGE) {
int pmp = sata_srst_pmp(link); int pmp = sata_srst_pmp(link);
hisi_sas_fill_ata_reset_cmd(link->device, 0, pmp, fis); hisi_sas_fill_ata_reset_cmd(link->device, 0,
rc = hisi_sas_exec_internal_tmf_task(device, fis, pmp, (u8 *)&fis);
rc = hisi_sas_exec_internal_tmf_task(device, &fis,
s, NULL); s, NULL);
if (rc != TMF_RESP_FUNC_COMPLETE) if (rc != TMF_RESP_FUNC_COMPLETE)
dev_err(dev, "ata disk de-reset failed\n"); dev_err(dev, "ata disk de-reset failed\n");
...@@ -1317,6 +1330,7 @@ static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device, ...@@ -1317,6 +1330,7 @@ static int hisi_sas_debug_issue_ssp_tmf(struct domain_device *device,
if (!(device->tproto & SAS_PROTOCOL_SSP)) if (!(device->tproto & SAS_PROTOCOL_SSP))
return TMF_RESP_FUNC_ESUPP; return TMF_RESP_FUNC_ESUPP;
/* LUN is define as 8 bytes array at upper layer */
memcpy(ssp_task.LUN, lun, 8); memcpy(ssp_task.LUN, lun, 8);
return hisi_sas_exec_internal_tmf_task(device, &ssp_task, return hisi_sas_exec_internal_tmf_task(device, &ssp_task,
...@@ -1432,10 +1446,10 @@ static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba, ...@@ -1432,10 +1446,10 @@ static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba,
struct ata_port *ap = device->sata_dev.ap; struct ata_port *ap = device->sata_dev.ap;
struct device *dev = hisi_hba->dev; struct device *dev = hisi_hba->dev;
int s = sizeof(struct host_to_dev_fis); int s = sizeof(struct host_to_dev_fis);
struct host_to_dev_fis fis = {};
int rc = TMF_RESP_FUNC_FAILED; int rc = TMF_RESP_FUNC_FAILED;
struct asd_sas_phy *sas_phy; struct asd_sas_phy *sas_phy;
struct ata_link *link; struct ata_link *link;
u8 fis[20] = {0};
u32 state; u32 state;
state = hisi_hba->hw->get_phys_state(hisi_hba); state = hisi_hba->hw->get_phys_state(hisi_hba);
...@@ -1447,8 +1461,9 @@ static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba, ...@@ -1447,8 +1461,9 @@ static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba,
int pmp = sata_srst_pmp(link); int pmp = sata_srst_pmp(link);
tmf_task.phy_id = sas_phy->id; tmf_task.phy_id = sas_phy->id;
hisi_sas_fill_ata_reset_cmd(link->device, 1, pmp, fis); hisi_sas_fill_ata_reset_cmd(link->device, 1,
rc = hisi_sas_exec_internal_tmf_task(device, fis, s, pmp, (u8 *)&fis);
rc = hisi_sas_exec_internal_tmf_task(device, &fis, s,
&tmf_task); &tmf_task);
if (rc != TMF_RESP_FUNC_COMPLETE) { if (rc != TMF_RESP_FUNC_COMPLETE) {
dev_err(dev, "phy%d ata reset failed rc=%d\n", dev_err(dev, "phy%d ata reset failed rc=%d\n",
...@@ -1507,6 +1522,8 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba) ...@@ -1507,6 +1522,8 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba)
hisi_hba->phy_state = hisi_hba->hw->get_phys_state(hisi_hba); hisi_hba->phy_state = hisi_hba->hw->get_phys_state(hisi_hba);
scsi_block_requests(shost); scsi_block_requests(shost);
/* Delay: 100ms timeout: 5s */
hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000); hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000);
if (timer_pending(&hisi_hba->timer)) if (timer_pending(&hisi_hba->timer))
...@@ -1523,6 +1540,7 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) ...@@ -1523,6 +1540,7 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba)
/* Init and wait for PHYs to come up and all libsas event finished. */ /* Init and wait for PHYs to come up and all libsas event finished. */
hisi_hba->hw->phys_init(hisi_hba); hisi_hba->hw->phys_init(hisi_hba);
/* Sleep 1s to wait for phy up */
msleep(1000); msleep(1000);
hisi_sas_refresh_port_id(hisi_hba); hisi_sas_refresh_port_id(hisi_hba);
clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
...@@ -1550,10 +1568,10 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) ...@@ -1550,10 +1568,10 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
if (!hisi_hba->hw->soft_reset) if (!hisi_hba->hw->soft_reset)
return -1; return -EINVAL;
if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
return -1; return -EPERM;
dev_info(dev, "controller resetting...\n"); dev_info(dev, "controller resetting...\n");
hisi_sas_controller_reset_prepare(hisi_hba); hisi_sas_controller_reset_prepare(hisi_hba);
...@@ -1735,6 +1753,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) ...@@ -1735,6 +1753,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
sas_put_local_phy(local_phy); sas_put_local_phy(local_phy);
if (scsi_is_sas_phy_local(local_phy)) { if (scsi_is_sas_phy_local(local_phy)) {
/* Wait for I_T reset complete, time out after 2s */
int ret = wait_for_completion_timeout(&phyreset, 2 * HZ); int ret = wait_for_completion_timeout(&phyreset, 2 * HZ);
unsigned long flags; unsigned long flags;
...@@ -1747,6 +1766,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) ...@@ -1747,6 +1766,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
if (!ret) if (!ret)
hisi_sas_phy_down(hisi_hba, sas_phy->id, 0); hisi_sas_phy_down(hisi_hba, sas_phy->id, 0);
} else } else
/* Sleep 2s to wait for I_T reset at expander env */
msleep(2000); msleep(2000);
return rc; return rc;
...@@ -1908,7 +1928,7 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, ...@@ -1908,7 +1928,7 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba,
return -EINVAL; return -EINVAL;
if (!device->port) if (!device->port)
return -1; return -EPERM;
port = to_hisi_sas_port(sas_port); port = to_hisi_sas_port(sas_port);
...@@ -2322,7 +2342,10 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba) ...@@ -2322,7 +2342,10 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba)
if (!hisi_hba->slot_info) if (!hisi_hba->slot_info)
goto err_out; goto err_out;
/* roundup to avoid overly large block size */ /*
* roundup to avoid overly large block size
* 64 is a better setting after several repeated attempts
*/
max_command_entries_ru = roundup(max_command_entries, 64); max_command_entries_ru = roundup(max_command_entries, 64);
if (!hisi_hba->enable_dix_dif) if (!hisi_hba->enable_dix_dif)
sz_slot_buf_ru = roundup(sizeof( sz_slot_buf_ru = roundup(sizeof(
...@@ -2594,6 +2617,7 @@ int hisi_sas_probe(struct platform_device *pdev, ...@@ -2594,6 +2617,7 @@ int hisi_sas_probe(struct platform_device *pdev,
shost->max_id = HISI_SAS_MAX_DEVICES; shost->max_id = HISI_SAS_MAX_DEVICES;
shost->max_lun = ~0; shost->max_lun = ~0;
shost->max_channel = 1; shost->max_channel = 1;
/* shost support 16 bytes cmd len base on hw */
shost->max_cmd_len = 16; shost->max_cmd_len = 16;
if (hisi_hba->hw->slot_index_alloc) { if (hisi_hba->hw->slot_index_alloc) {
shost->can_queue = hisi_hba->hw->max_command_entries; shost->can_queue = hisi_hba->hw->max_command_entries;
...@@ -2817,6 +2841,7 @@ static int hisi_sas_show_row_64(struct seq_file *s, int index, ...@@ -2817,6 +2841,7 @@ static int hisi_sas_show_row_64(struct seq_file *s, int index,
/* completion header size not fixed per HW version */ /* completion header size not fixed per HW version */
seq_printf(s, "index %04d:\n\t", index); seq_printf(s, "index %04d:\n\t", index);
/* Convert unit of sz to 8 bytes before compare */
for (i = 1; i <= sz / 8; i++, ptr++) { for (i = 1; i <= sz / 8; i++, ptr++) {
seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr)); seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr));
if (!(i % 2)) if (!(i % 2))
...@@ -2835,6 +2860,7 @@ static int hisi_sas_show_row_32(struct seq_file *s, int index, ...@@ -2835,6 +2860,7 @@ static int hisi_sas_show_row_32(struct seq_file *s, int index,
/* completion header size not fixed per HW version */ /* completion header size not fixed per HW version */
seq_printf(s, "index %04d:\n\t", index); seq_printf(s, "index %04d:\n\t", index);
/* Convert unit of sz to 4 bytes before compare */
for (i = 1; i <= sz / 4; i++, ptr++) { for (i = 1; i <= sz / 4; i++, ptr++) {
seq_printf(s, " 0x%08x", le32_to_cpu(*ptr)); seq_printf(s, " 0x%08x", le32_to_cpu(*ptr));
if (!(i % 4)) if (!(i % 4))
...@@ -3005,7 +3031,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) ...@@ -3005,7 +3031,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba)
goto fail; goto fail;
for (p = 0; p < hisi_hba->n_phy; p++) { for (p = 0; p < hisi_hba->n_phy; p++) {
snprintf(name, 256, "%d", p); snprintf(name, sizeof(name), "%d", p);
if (!debugfs_create_file(name, 0400, dentry, if (!debugfs_create_file(name, 0400, dentry,
&hisi_hba->phy[p], &hisi_hba->phy[p],
&hisi_sas_debugfs_port_fops)) &hisi_sas_debugfs_port_fops))
...@@ -3018,7 +3044,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) ...@@ -3018,7 +3044,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba)
goto fail; goto fail;
for (c = 0; c < hisi_hba->queue_count; c++) { for (c = 0; c < hisi_hba->queue_count; c++) {
snprintf(name, 256, "%d", c); snprintf(name, sizeof(name), "%d", c);
if (!debugfs_create_file(name, 0400, dentry, if (!debugfs_create_file(name, 0400, dentry,
&hisi_hba->cq[c], &hisi_hba->cq[c],
...@@ -3032,7 +3058,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) ...@@ -3032,7 +3058,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba)
goto fail; goto fail;
for (d = 0; d < hisi_hba->queue_count; d++) { for (d = 0; d < hisi_hba->queue_count; d++) {
snprintf(name, 256, "%d", d); snprintf(name, sizeof(name), "%d", d);
if (!debugfs_create_file(name, 0400, dentry, if (!debugfs_create_file(name, 0400, dentry,
&hisi_hba->dq[d], &hisi_hba->dq[d],
...@@ -3087,7 +3113,7 @@ static ssize_t hisi_sas_debugfs_trigger_dump_write(struct file *file, ...@@ -3087,7 +3113,7 @@ static ssize_t hisi_sas_debugfs_trigger_dump_write(struct file *file,
*/ */
/* Not allow to input more than 8 char */ /* Not allow to input more than 8 char */
if (count > 8) if (count > sizeof(buf))
return -EFAULT; return -EFAULT;
if (copy_from_user(buf, user_buf, count)) if (copy_from_user(buf, user_buf, count))
......
...@@ -408,6 +408,18 @@ struct hisi_sas_err_record_v3 { ...@@ -408,6 +408,18 @@ struct hisi_sas_err_record_v3 {
#define HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW 16 #define HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW 16
#define HISI_SAS_MIN_VECTORS_V3_HW 17 #define HISI_SAS_MIN_VECTORS_V3_HW 17
#define NEXT_DQCQ_REG_OFF 0x14
#define HISI_SAS_BAR_TO_IOMAP 5
#define PCIDEV_REVISION_1620_ES 0x20
#define PCIDEV_REVISION_1620_CS 0x21
#define PCI_IRQ_PHY 1
#define PCI_IRQ_CHANNEL 2
#define PCI_IRQ_AXI_FATAL 11
#define PCI_IRQ_CQ_BASE HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW
#define HISI_SAS_IS_RW_CMD(op) \ #define HISI_SAS_IS_RW_CMD(op) \
((op == READ_6) || (op == WRITE_6) || \ ((op == READ_6) || (op == WRITE_6) || \
(op == READ_10) || (op == WRITE_10) || \ (op == READ_10) || (op == WRITE_10) || \
...@@ -453,6 +465,7 @@ static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val) ...@@ -453,6 +465,7 @@ static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val)
static void hisi_sas_phy_write32(struct hisi_hba *hisi_hba, int phy_no, static void hisi_sas_phy_write32(struct hisi_hba *hisi_hba, int phy_no,
u32 off, u32 val) u32 off, u32 val)
{ {
/* Each reg of phy cost 0x400 bytes memory to save */
void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off; void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off;
writel(val, regs); writel(val, regs);
...@@ -461,6 +474,7 @@ static void hisi_sas_phy_write32(struct hisi_hba *hisi_hba, int phy_no, ...@@ -461,6 +474,7 @@ static void hisi_sas_phy_write32(struct hisi_hba *hisi_hba, int phy_no,
static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba, static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
int phy_no, u32 off) int phy_no, u32 off)
{ {
/* Each reg of phy cost 0x400 bytes memory to save */
void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off; void __iomem *regs = hisi_hba->regs + (0x400 * phy_no) + off;
return readl(regs); return readl(regs);
...@@ -502,7 +516,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) ...@@ -502,7 +516,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff); hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe); hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe);
if (pdev->revision >= 0x21) if (pdev->revision >= PCIDEV_REVISION_1620_CS)
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7aff); hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7aff);
else else
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff); hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff);
...@@ -554,7 +568,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) ...@@ -554,7 +568,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); 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, RXOP_CHECK_CFG_H, 0x1000);
if (pdev->revision >= 0x21) if (pdev->revision >= PCIDEV_REVISION_1620_CS)
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK,
0xffffffff); 0xffffffff);
else else
...@@ -595,23 +609,29 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) ...@@ -595,23 +609,29 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
for (i = 0; i < hisi_hba->queue_count; i++) { for (i = 0; i < hisi_hba->queue_count; i++) {
/* Delivery queue */ /* Delivery queue */
hisi_sas_write32(hisi_hba, hisi_sas_write32(hisi_hba,
DLVRY_Q_0_BASE_ADDR_HI + (i * 0x14), DLVRY_Q_0_BASE_ADDR_HI +
(i * NEXT_DQCQ_REG_OFF),
upper_32_bits(hisi_hba->cmd_hdr_dma[i])); upper_32_bits(hisi_hba->cmd_hdr_dma[i]));
hisi_sas_write32(hisi_hba, DLVRY_Q_0_BASE_ADDR_LO + (i * 0x14), hisi_sas_write32(hisi_hba, DLVRY_Q_0_BASE_ADDR_LO +
(i * NEXT_DQCQ_REG_OFF),
lower_32_bits(hisi_hba->cmd_hdr_dma[i])); lower_32_bits(hisi_hba->cmd_hdr_dma[i]));
hisi_sas_write32(hisi_hba, DLVRY_Q_0_DEPTH + (i * 0x14), hisi_sas_write32(hisi_hba, DLVRY_Q_0_DEPTH +
(i * NEXT_DQCQ_REG_OFF),
HISI_SAS_QUEUE_SLOTS); HISI_SAS_QUEUE_SLOTS);
/* Completion queue */ /* Completion queue */
hisi_sas_write32(hisi_hba, COMPL_Q_0_BASE_ADDR_HI + (i * 0x14), hisi_sas_write32(hisi_hba, COMPL_Q_0_BASE_ADDR_HI +
(i * NEXT_DQCQ_REG_OFF),
upper_32_bits(hisi_hba->complete_hdr_dma[i])); upper_32_bits(hisi_hba->complete_hdr_dma[i]));
hisi_sas_write32(hisi_hba, COMPL_Q_0_BASE_ADDR_LO + (i * 0x14), hisi_sas_write32(hisi_hba, COMPL_Q_0_BASE_ADDR_LO +
(i * NEXT_DQCQ_REG_OFF),
lower_32_bits(hisi_hba->complete_hdr_dma[i])); lower_32_bits(hisi_hba->complete_hdr_dma[i]));
hisi_sas_write32(hisi_hba, COMPL_Q_0_DEPTH + (i * 0x14), hisi_sas_write32(hisi_hba, COMPL_Q_0_DEPTH +
(i * NEXT_DQCQ_REG_OFF),
HISI_SAS_QUEUE_SLOTS); HISI_SAS_QUEUE_SLOTS);
} }
...@@ -809,11 +829,14 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba) ...@@ -809,11 +829,14 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0); hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0);
/* Disable all of the PHYs */ /*
* Disable all of the PHYs,
* 50us delay is need for hw
*/
hisi_sas_stop_phys(hisi_hba); hisi_sas_stop_phys(hisi_hba);
udelay(50); udelay(50);
/* Ensure axi bus idle */ /* Ensure axi bus idle, with 20ms delay and 1s time out */
ret = hisi_sas_read32_poll_timeout(AXI_CFG, val, !val, ret = hisi_sas_read32_poll_timeout(AXI_CFG, val, !val,
20000, 1000000); 20000, 1000000);
if (ret) { if (ret) {
...@@ -848,6 +871,7 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba) ...@@ -848,6 +871,7 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba)
return rc; return rc;
} }
/* Delay 100ms to reset hw */
msleep(100); msleep(100);
init_reg_v3_hw(hisi_hba); init_reg_v3_hw(hisi_hba);
...@@ -871,6 +895,7 @@ static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) ...@@ -871,6 +895,7 @@ static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
cfg &= ~PHY_CFG_ENA_MSK; cfg &= ~PHY_CFG_ENA_MSK;
hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);
/* Delay 50ms after disable phy to meet hw need */
mdelay(50); mdelay(50);
state = hisi_sas_read32(hisi_hba, PHY_STATE); state = hisi_sas_read32(hisi_hba, PHY_STATE);
...@@ -898,6 +923,8 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no) ...@@ -898,6 +923,8 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO, hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO,
txid_auto | TX_HARDRST_MSK); txid_auto | TX_HARDRST_MSK);
} }
/* Delay 100ms after phy hard reset to meet hw need */
msleep(100); msleep(100);
start_phy_v3_hw(hisi_hba, phy_no); start_phy_v3_hw(hisi_hba, phy_no);
} }
...@@ -947,6 +974,7 @@ static int get_wideport_bitmap_v3_hw(struct hisi_hba *hisi_hba, int port_id) ...@@ -947,6 +974,7 @@ static int get_wideport_bitmap_v3_hw(struct hisi_hba *hisi_hba, int port_id)
for (i = 0; i < hisi_hba->n_phy; i++) for (i = 0; i < hisi_hba->n_phy; i++)
if (phy_state & BIT(i)) if (phy_state & BIT(i))
/* Each num ma of port cost 4 bit to save */
if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id) if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id)
bitmap |= BIT(i); bitmap |= BIT(i);
...@@ -966,7 +994,8 @@ get_free_slot_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq) ...@@ -966,7 +994,8 @@ get_free_slot_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq)
w = dq->wr_point; w = dq->wr_point;
r = hisi_sas_read32_relaxed(hisi_hba, r = hisi_sas_read32_relaxed(hisi_hba,
DLVRY_Q_0_RD_PTR + (queue * 0x14)); DLVRY_Q_0_RD_PTR +
(queue * NEXT_DQCQ_REG_OFF));
if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) {
dev_warn(dev, "full queue=%d r=%d w=%d\n", dev_warn(dev, "full queue=%d r=%d w=%d\n",
queue, r, w); queue, r, w);
...@@ -1001,7 +1030,9 @@ static void start_delivery_v3_hw(struct hisi_sas_dq *dq) ...@@ -1001,7 +1030,9 @@ static void start_delivery_v3_hw(struct hisi_sas_dq *dq)
smp_rmb(); smp_rmb();
wp = (s2->dlvry_queue_slot + 1) % HISI_SAS_QUEUE_SLOTS; wp = (s2->dlvry_queue_slot + 1) % HISI_SAS_QUEUE_SLOTS;
hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), wp); hisi_sas_write32(hisi_hba,
DLVRY_Q_0_WR_PTR +
(dlvry_queue * NEXT_DQCQ_REG_OFF), wp);
} }
static void prep_prd_sge_v3_hw(struct hisi_hba *hisi_hba, static void prep_prd_sge_v3_hw(struct hisi_hba *hisi_hba,
...@@ -1062,6 +1093,11 @@ static void hisi_sas_fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd, ...@@ -1062,6 +1093,11 @@ static void hisi_sas_fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd,
u32 prot_interval = scsi_prot_interval(scsi_cmnd); u32 prot_interval = scsi_prot_interval(scsi_cmnd);
u32 lbrt_chk_val; u32 lbrt_chk_val;
/*
* if interval of sector size equal to 4096,
* lbrt_chk_val should divided by 8 for it
* was base on 512.
*/
if (scsi_prot_interval(scsi_cmnd) == 4096) if (scsi_prot_interval(scsi_cmnd) == 4096)
lbrt_chk_val = (u32)(scsi_get_lba(scsi_cmnd) >> 3); lbrt_chk_val = (u32)(scsi_get_lba(scsi_cmnd) >> 3);
else else
...@@ -1109,6 +1145,7 @@ static void hisi_sas_fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd, ...@@ -1109,6 +1145,7 @@ static void hisi_sas_fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd,
break; break;
} }
/* Different Config base on interval of sector size */
switch (prot_interval) { switch (prot_interval) {
case 512: case 512:
break; break;
...@@ -1154,13 +1191,13 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, ...@@ -1154,13 +1191,13 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
u32 dw1 = 0, dw2 = 0, len = 0, priority = !!tmf; u32 dw1 = 0, dw2 = 0, len = 0, priority = !!tmf;
hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) | hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) |
(2 << CMD_HDR_TLR_CTRL_OFF) | (2 << CMD_HDR_TLR_CTRL_OFF) | /* no retransmit */
(port->id << CMD_HDR_PORT_OFF) | (port->id << CMD_HDR_PORT_OFF) |
(priority << CMD_HDR_PRIORITY_OFF) | (priority << CMD_HDR_PRIORITY_OFF) |
(1 << CMD_HDR_CMD_OFF)); /* ssp */ (1 << CMD_HDR_CMD_OFF)); /* ssp */
if (tmf) { if (tmf) {
dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF; dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF; /* task frame */
dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF; dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF;
} else { } else {
dw1 = set_hdr_vdtl(&scsi_cmnd->cmnd[0]); dw1 = set_hdr_vdtl(&scsi_cmnd->cmnd[0]);
...@@ -1183,6 +1220,10 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, ...@@ -1183,6 +1220,10 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF; dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
hdr->dw1 = cpu_to_le32(dw1); hdr->dw1 = cpu_to_le32(dw1);
/*
* The unit of CMD Frame LEN is Dwords
* Add extra 3 bytes to avoid Numerical loss after divided by 4
*/
dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr) dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr)
+ 3) / 4) << CMD_HDR_CFL_OFF) | + 3) / 4) << CMD_HDR_CFL_OFF) |
((HISI_SAS_MAX_SSP_RESP_SZ / 4) << CMD_HDR_MRFL_OFF) | ((HISI_SAS_MAX_SSP_RESP_SZ / 4) << CMD_HDR_MRFL_OFF) |
...@@ -1208,9 +1249,17 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, ...@@ -1208,9 +1249,17 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
memcpy(buf_cmd, &task->ssp_task.LUN, 8); memcpy(buf_cmd, &task->ssp_task.LUN, 8);
if (!tmf) { if (!tmf) {
/*
* Command frame
* Reference: SAS Protocol Layer,see chapter: Transport layer
*/
buf_cmd[9] = ssp_task->task_attr | (ssp_task->task_prio << 3); buf_cmd[9] = ssp_task->task_attr | (ssp_task->task_prio << 3);
memcpy(buf_cmd + 12, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); memcpy(buf_cmd + 12, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
} else { } else {
/*
* Task frame
* Reference: SAS Protocol Layer,see chapter: Transport layer
*/
buf_cmd[10] = tmf->tmf; buf_cmd[10] = tmf->tmf;
switch (tmf->tmf) { switch (tmf->tmf) {
case TMF_ABORT_TASK: case TMF_ABORT_TASK:
...@@ -1307,9 +1356,9 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba, ...@@ -1307,9 +1356,9 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF); hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF);
if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type))
hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF); hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF); /* STP */
else else
hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF); hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF); /* SATA */
switch (task->data_dir) { switch (task->data_dir) {
case DMA_TO_DEVICE: case DMA_TO_DEVICE:
...@@ -1340,12 +1389,13 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba, ...@@ -1340,12 +1389,13 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
/* dw2 */ /* dw2 */
if (task->ata_task.use_ncq && hisi_sas_get_ncq_tag(task, &hdr_tag)) { if (task->ata_task.use_ncq && hisi_sas_get_ncq_tag(task, &hdr_tag)) {
/* Reference: ATA-8 ACS */
task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3); task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF; dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF;
} }
dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / 4) << CMD_HDR_CFL_OFF | dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / 4) << CMD_HDR_CFL_OFF |
2 << CMD_HDR_SG_MOD_OFF; 2 << CMD_HDR_SG_MOD_OFF; /* SGE mode */
hdr->dw2 = cpu_to_le32(dw2); hdr->dw2 = cpu_to_le32(dw2);
/* dw3 */ /* dw3 */
...@@ -1407,6 +1457,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) ...@@ -1407,6 +1457,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
del_timer(&phy->timer); del_timer(&phy->timer);
hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);
/* Port id store in 4 bits */
port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA); port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);
port_id = (port_id >> (4 * phy_no)) & 0xf; port_id = (port_id >> (4 * phy_no)) & 0xf;
link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE); link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);
...@@ -1442,7 +1493,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) ...@@ -1442,7 +1493,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
} }
sas_phy->oob_mode = SATA_OOB_MODE; sas_phy->oob_mode = SATA_OOB_MODE;
attached_sas_addr[0] = 0x50; attached_sas_addr[0] = 0x50; /* sas address for SATA */
attached_sas_addr[7] = phy_no; attached_sas_addr[7] = phy_no;
memcpy(sas_phy->attached_sas_addr, memcpy(sas_phy->attached_sas_addr,
attached_sas_addr, attached_sas_addr,
...@@ -1459,6 +1510,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) ...@@ -1459,6 +1510,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
(struct sas_identify_frame *)frame_rcvd; (struct sas_identify_frame *)frame_rcvd;
dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate); dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
/* IDENTIFY Frame length: 7 Dwords, last Dwords reserved */
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no, u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no,
RX_IDAF_DWORD0 + (i * 4)); RX_IDAF_DWORD0 + (i * 4));
...@@ -1578,6 +1630,7 @@ static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p) ...@@ -1578,6 +1630,7 @@ static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p)
res = IRQ_HANDLED; res = IRQ_HANDLED;
} }
} }
/* Irq mask of each phy store in 4 bits */
irq_msk >>= 4; irq_msk >>= 4;
phy_no++; phy_no++;
} }
...@@ -1655,11 +1708,13 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) ...@@ -1655,11 +1708,13 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
dev_warn(dev, "phy%d stp link timeout (0x%x)\n", dev_warn(dev, "phy%d stp link timeout (0x%x)\n",
phy_no, reg_value); phy_no, reg_value);
/* if time out is happened at state: L_RCVCHKRDY */
if (reg_value & BIT(4)) if (reg_value & BIT(4))
hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
} }
if ((pci_dev->revision > 0x20) && (irq_value & msk)) { if (pci_dev->revision > PCIDEV_REVISION_1620_ES &&
(irq_value & msk)) {
struct asd_sas_phy *sas_phy = &phy->sas_phy; struct asd_sas_phy *sas_phy = &phy->sas_phy;
struct sas_phy *sphy = sas_phy->phy; struct sas_phy *sphy = sas_phy->phy;
...@@ -1679,10 +1734,11 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) ...@@ -1679,10 +1734,11 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
} }
if ((irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) && if ((irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) &&
(pci_dev->revision == 0x20)) { (pci_dev->revision == PCIDEV_REVISION_1620_ES)) {
u32 reg_value; u32 reg_value;
int rc; int rc;
/* Delay: 1ms timeout: 10ms */
rc = hisi_sas_read32_poll_timeout_atomic( rc = hisi_sas_read32_poll_timeout_atomic(
HILINK_ERR_DFX, reg_value, HILINK_ERR_DFX, reg_value,
!((reg_value >> 8) & BIT(phy_no)), !((reg_value >> 8) & BIT(phy_no)),
...@@ -1737,7 +1793,10 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p) ...@@ -1737,7 +1793,10 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS) irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS)
& 0xeeeeeeee; & 0xeeeeeeee;
/*
* These three irqs mask save at high 3 bit, the last bit
* is reserved. So we use 0xe to clear those after handle.
*/
while (irq_msk) { while (irq_msk) {
if (irq_msk & (2 << (phy_no * 4))) if (irq_msk & (2 << (phy_no * 4)))
handle_chl_int0_v3_hw(hisi_hba, phy_no); handle_chl_int0_v3_hw(hisi_hba, phy_no);
...@@ -1847,7 +1906,7 @@ static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p) ...@@ -1847,7 +1906,7 @@ static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p)
queue_work(hisi_hba->wq, &hisi_hba->rst_work); queue_work(hisi_hba->wq, &hisi_hba->rst_work);
} }
if (pdev->revision < 0x21) { if (pdev->revision < PCIDEV_REVISION_1620_CS) {
u32 reg_val; u32 reg_val;
reg_val = hisi_sas_read32(hisi_hba, reg_val = hisi_sas_read32(hisi_hba,
...@@ -1981,7 +2040,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) ...@@ -1981,7 +2040,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
break; break;
} }
/* check for erroneous completion */ /* check for erroneous completion, 0x3 means abnormal */
if ((complete_hdr->dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { if ((complete_hdr->dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) {
u32 *error_info = hisi_sas_status_buf_addr_mem(slot); u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
...@@ -2092,7 +2151,7 @@ static void cq_tasklet_v3_hw(unsigned long val) ...@@ -2092,7 +2151,7 @@ static void cq_tasklet_v3_hw(unsigned long val)
complete_queue = hisi_hba->complete_hdr[queue]; complete_queue = hisi_hba->complete_hdr[queue];
wr_point = hisi_sas_read32(hisi_hba, COMPL_Q_0_WR_PTR + wr_point = hisi_sas_read32(hisi_hba, COMPL_Q_0_WR_PTR +
(0x14 * queue)); (NEXT_DQCQ_REG_OFF * queue));
while (rd_point != wr_point) { while (rd_point != wr_point) {
struct hisi_sas_complete_v3_hdr *complete_hdr; struct hisi_sas_complete_v3_hdr *complete_hdr;
...@@ -2116,7 +2175,9 @@ static void cq_tasklet_v3_hw(unsigned long val) ...@@ -2116,7 +2175,9 @@ static void cq_tasklet_v3_hw(unsigned long val)
/* update rd_point */ /* update rd_point */
cq->rd_point = rd_point; cq->rd_point = rd_point;
hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); hisi_sas_write32(hisi_hba,
COMPL_Q_0_RD_PTR + (NEXT_DQCQ_REG_OFF * queue),
rd_point);
} }
static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p) static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p)
...@@ -2138,7 +2199,9 @@ static void setup_reply_map_v3_hw(struct hisi_hba *hisi_hba, int nvecs) ...@@ -2138,7 +2199,9 @@ static void setup_reply_map_v3_hw(struct hisi_hba *hisi_hba, int nvecs)
int queue, cpu; int queue, cpu;
for (queue = 0; queue < nvecs; queue++) { for (queue = 0; queue < nvecs; queue++) {
mask = pci_irq_get_affinity(hisi_hba->pci_dev, queue + 16); mask = pci_irq_get_affinity(hisi_hba->pci_dev,
queue +
HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW);
if (!mask) if (!mask)
goto fallback; goto fallback;
for_each_cpu(cpu, mask) for_each_cpu(cpu, mask)
...@@ -2182,7 +2245,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2182,7 +2245,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
} }
hisi_hba->nvecs = vectors - HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW; hisi_hba->nvecs = vectors - HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW;
rc = devm_request_irq(dev, pci_irq_vector(pdev, 1), rc = devm_request_irq(dev, pci_irq_vector(pdev, PCI_IRQ_PHY),
int_phy_up_down_bcast_v3_hw, 0, int_phy_up_down_bcast_v3_hw, 0,
DRV_NAME " phy", hisi_hba); DRV_NAME " phy", hisi_hba);
if (rc) { if (rc) {
...@@ -2191,7 +2254,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2191,7 +2254,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
goto free_irq_vectors; goto free_irq_vectors;
} }
rc = devm_request_irq(dev, pci_irq_vector(pdev, 2), rc = devm_request_irq(dev, pci_irq_vector(pdev, PCI_IRQ_CHANNEL),
int_chnl_int_v3_hw, 0, int_chnl_int_v3_hw, 0,
DRV_NAME " channel", hisi_hba); DRV_NAME " channel", hisi_hba);
if (rc) { if (rc) {
...@@ -2200,7 +2263,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2200,7 +2263,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
goto free_phy_irq; goto free_phy_irq;
} }
rc = devm_request_irq(dev, pci_irq_vector(pdev, 11), rc = devm_request_irq(dev, pci_irq_vector(pdev, PCI_IRQ_AXI_FATAL),
fatal_axi_int_v3_hw, 0, fatal_axi_int_v3_hw, 0,
DRV_NAME " fatal", hisi_hba); DRV_NAME " fatal", hisi_hba);
if (rc) { if (rc) {
...@@ -2213,7 +2276,8 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2213,7 +2276,8 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
for (i = 0; i < hisi_hba->nvecs; i++) { for (i = 0; i < hisi_hba->nvecs; i++) {
struct hisi_sas_cq *cq = &hisi_hba->cq[i]; struct hisi_sas_cq *cq = &hisi_hba->cq[i];
struct tasklet_struct *t = &cq->tasklet; struct tasklet_struct *t = &cq->tasklet;
int nr = hisi_sas_intr_conv ? 16 : 16 + i; int nr = hisi_sas_intr_conv ? PCI_IRQ_CQ_BASE :
PCI_IRQ_CQ_BASE + i;
unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0; unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0;
rc = devm_request_irq(dev, pci_irq_vector(pdev, nr), rc = devm_request_irq(dev, pci_irq_vector(pdev, nr),
...@@ -2227,7 +2291,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2227,7 +2291,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
goto free_cq_irqs; goto free_cq_irqs;
} }
tasklet_init(t, cq_tasklet_v3_hw, (unsigned long)cq); tasklet_init(t, cq_tasklet_v3_hw, (uintptr_t)cq);
} }
return 0; return 0;
...@@ -2235,15 +2299,16 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2235,15 +2299,16 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
free_cq_irqs: free_cq_irqs:
for (k = 0; k < i; k++) { for (k = 0; k < i; k++) {
struct hisi_sas_cq *cq = &hisi_hba->cq[k]; struct hisi_sas_cq *cq = &hisi_hba->cq[k];
int nr = hisi_sas_intr_conv ? 16 : 16 + k; int nr = hisi_sas_intr_conv ? PCI_IRQ_CQ_BASE :
PCI_IRQ_CQ_BASE + k;
free_irq(pci_irq_vector(pdev, nr), cq); free_irq(pci_irq_vector(pdev, nr), cq);
} }
free_irq(pci_irq_vector(pdev, 11), hisi_hba); free_irq(pci_irq_vector(pdev, PCI_IRQ_AXI_FATAL), hisi_hba);
free_chnl_interrupt: free_chnl_interrupt:
free_irq(pci_irq_vector(pdev, 2), hisi_hba); free_irq(pci_irq_vector(pdev, PCI_IRQ_CHANNEL), hisi_hba);
free_phy_irq: free_phy_irq:
free_irq(pci_irq_vector(pdev, 1), hisi_hba); free_irq(pci_irq_vector(pdev, PCI_IRQ_PHY), hisi_hba);
free_irq_vectors: free_irq_vectors:
pci_free_irq_vectors(pdev); pci_free_irq_vectors(pdev);
return rc; return rc;
...@@ -2268,6 +2333,7 @@ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no, ...@@ -2268,6 +2333,7 @@ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no,
struct sas_phy_linkrates *r) struct sas_phy_linkrates *r)
{ {
enum sas_linkrate max = r->maximum_linkrate; enum sas_linkrate max = r->maximum_linkrate;
/* init OOB link rate as 1.5 Gbits */
u32 prog_phy_link_rate = 0x800; u32 prog_phy_link_rate = 0x800;
prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max); prog_phy_link_rate |= hisi_sas_get_prog_phy_linkrate_mask(max);
...@@ -2280,12 +2346,12 @@ static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2280,12 +2346,12 @@ static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba)
struct pci_dev *pdev = hisi_hba->pci_dev; struct pci_dev *pdev = hisi_hba->pci_dev;
int i; int i;
synchronize_irq(pci_irq_vector(pdev, 1)); synchronize_irq(pci_irq_vector(pdev, PCI_IRQ_PHY));
synchronize_irq(pci_irq_vector(pdev, 2)); synchronize_irq(pci_irq_vector(pdev, PCI_IRQ_CHANNEL));
synchronize_irq(pci_irq_vector(pdev, 11)); synchronize_irq(pci_irq_vector(pdev, PCI_IRQ_AXI_FATAL));
for (i = 0; i < hisi_hba->queue_count; i++) { for (i = 0; i < hisi_hba->queue_count; i++) {
hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1); hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1);
synchronize_irq(pci_irq_vector(pdev, i + 16)); synchronize_irq(pci_irq_vector(pdev, i + PCI_IRQ_CQ_BASE));
} }
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff); hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff);
...@@ -2352,6 +2418,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2352,6 +2418,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_stop_phys(hisi_hba); hisi_sas_stop_phys(hisi_hba);
/* Delay 10ms after stop phys to meet hw need */
mdelay(10); mdelay(10);
reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE + reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE +
...@@ -2360,7 +2427,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2360,7 +2427,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE + hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE +
AM_CTRL_GLOBAL, reg_val); AM_CTRL_GLOBAL, reg_val);
/* wait until bus idle */ /* wait until bus idle, delay:10us, timeout:100us */
rc = hisi_sas_read32_poll_timeout(AXI_MASTER_CFG_BASE + rc = hisi_sas_read32_poll_timeout(AXI_MASTER_CFG_BASE +
AM_CURR_TRANS_RETURN, status, AM_CURR_TRANS_RETURN, status,
status == 0x3, 10, 100); status == 0x3, 10, 100);
...@@ -2397,6 +2464,10 @@ static int write_gpio_v3_hw(struct hisi_hba *hisi_hba, u8 reg_type, ...@@ -2397,6 +2464,10 @@ static int write_gpio_v3_hw(struct hisi_hba *hisi_hba, u8 reg_type,
switch (reg_type) { switch (reg_type) {
case SAS_GPIO_REG_TX: case SAS_GPIO_REG_TX:
/*
* One register of GPIO can control 4 phys
* Add extra 3 bytes to avoid Numerical loss after divided by 4
*/
if ((reg_index + reg_count) > ((hisi_hba->n_phy + 3) / 4)) { if ((reg_index + reg_count) > ((hisi_hba->n_phy + 3) / 4)) {
dev_err(dev, "write gpio: invalid reg range[%d, %d]\n", dev_err(dev, "write gpio: invalid reg range[%d, %d]\n",
reg_index, reg_index + reg_count - 1); reg_index, reg_index + reg_count - 1);
...@@ -2456,7 +2527,7 @@ static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2456,7 +2527,7 @@ static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1); hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1); hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1); hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
} else { } else { /* intr coal */
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3); hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME,
hisi_hba->intr_coal_ticks); hisi_hba->intr_coal_ticks);
...@@ -2596,7 +2667,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = { ...@@ -2596,7 +2667,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = {
static const struct hisi_sas_debugfs_reg debugfs_port_reg = { static const struct hisi_sas_debugfs_reg debugfs_port_reg = {
.lu = debugfs_port_reg_lu, .lu = debugfs_port_reg_lu,
.count = 0x100, .count = 0x100, /* number of port regs */
.base_off = PORT_BASE, .base_off = PORT_BASE,
.read_port_reg = hisi_sas_phy_read32, .read_port_reg = hisi_sas_phy_read32,
}; };
...@@ -2680,7 +2751,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = { ...@@ -2680,7 +2751,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = {
static const struct hisi_sas_debugfs_reg debugfs_global_reg = { static const struct hisi_sas_debugfs_reg debugfs_global_reg = {
.lu = debugfs_global_reg_lu, .lu = debugfs_global_reg_lu,
.count = 0x800, .count = 0x800, /* number of global regs */
.read_global_reg = hisi_sas_read32, .read_global_reg = hisi_sas_read32,
}; };
...@@ -2692,6 +2763,7 @@ static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) ...@@ -2692,6 +2763,7 @@ static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0); hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0);
/* delay:100ms, timeout:5s */
if (wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000) == -ETIMEDOUT) if (wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000) == -ETIMEDOUT)
dev_dbg(dev, "Wait commands complete timeout!\n"); dev_dbg(dev, "Wait commands complete timeout!\n");
...@@ -2864,7 +2936,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2864,7 +2936,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hisi_hba = shost_priv(shost); hisi_hba = shost_priv(shost);
dev_set_drvdata(dev, sha); dev_set_drvdata(dev, sha);
hisi_hba->regs = pcim_iomap(pdev, 5, 0); hisi_hba->regs = pcim_iomap(pdev, HISI_SAS_BAR_TO_IOMAP, 0);
if (!hisi_hba->regs) { if (!hisi_hba->regs) {
dev_err(dev, "cannot map register.\n"); dev_err(dev, "cannot map register.\n");
rc = -ENOMEM; rc = -ENOMEM;
...@@ -2889,6 +2961,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2889,6 +2961,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
shost->max_id = HISI_SAS_MAX_DEVICES; shost->max_id = HISI_SAS_MAX_DEVICES;
shost->max_lun = ~0; shost->max_lun = ~0;
shost->max_channel = 1; shost->max_channel = 1;
/* shost support 16 bytes cmd len base on hw */
shost->max_cmd_len = 16; shost->max_cmd_len = 16;
shost->can_queue = hisi_hba->hw->max_command_entries - shost->can_queue = hisi_hba->hw->max_command_entries -
HISI_SAS_RESERVED_IPTT_CNT; HISI_SAS_RESERVED_IPTT_CNT;
...@@ -2950,12 +3023,13 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba) ...@@ -2950,12 +3023,13 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba)
{ {
int i; int i;
free_irq(pci_irq_vector(pdev, 1), hisi_hba); free_irq(pci_irq_vector(pdev, PCI_IRQ_PHY), hisi_hba);
free_irq(pci_irq_vector(pdev, 2), hisi_hba); free_irq(pci_irq_vector(pdev, PCI_IRQ_CHANNEL), hisi_hba);
free_irq(pci_irq_vector(pdev, 11), hisi_hba); free_irq(pci_irq_vector(pdev, PCI_IRQ_AXI_FATAL), hisi_hba);
for (i = 0; i < hisi_hba->nvecs; i++) { for (i = 0; i < hisi_hba->nvecs; i++) {
struct hisi_sas_cq *cq = &hisi_hba->cq[i]; struct hisi_sas_cq *cq = &hisi_hba->cq[i];
int nr = hisi_sas_intr_conv ? 16 : 16 + i; int nr = hisi_sas_intr_conv ? PCI_IRQ_CQ_BASE :
PCI_IRQ_CQ_BASE + i;
free_irq(pci_irq_vector(pdev, nr), cq); free_irq(pci_irq_vector(pdev, nr), cq);
} }
...@@ -3195,7 +3269,7 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -3195,7 +3269,7 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state)
} }
if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
return -1; return -EPERM;
scsi_block_requests(shost); scsi_block_requests(shost);
set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册