提交 4d31d6b5 编写于 作者: C chenxiang 提交者: Xie XiuQi

scsi: hisi_sas: add support for interrupt aggregation

If INT_COAL_EN is enabled, config time and count of interrupt aggregation.
Then if CQ collects count of CQ entries in time, it will report the
interrupt. Or if CQ doesn't collect enough CQ entries in time, it Will
report the interrupt until timeout.

As all the registers are not supported to be changed dynamically, so
need to config those register between disable and enable PHYs.
Signed-off-by: NXiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: NJohn Garry <john.garry@huawei.com>
上级 fd36723f
......@@ -323,6 +323,8 @@ struct hisi_hba {
unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
struct work_struct rst_work;
u32 phy_state;
u32 intr_coal_ticks; /* time of interrupt coalesce, unit:1us */
u32 intr_coal_count; /* count of interrupt coalesce */
};
/* Generic HW DMA host memory structures */
......
......@@ -2141,9 +2141,107 @@ static ssize_t intr_conv_show(struct device *dev,
}
static DEVICE_ATTR_RO(intr_conv);
static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba)
{
/* config those registers between enable and disable PHYs */
hisi_sas_stop_phys(hisi_hba);
if (hisi_hba->intr_coal_ticks == 0 ||
hisi_hba->intr_coal_count == 0) {
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_CNT, 0x1);
} else {
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME,
hisi_hba->intr_coal_ticks);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT,
hisi_hba->intr_coal_count);
}
phys_init_v3_hw(hisi_hba);
}
static ssize_t intr_coal_ticks_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct hisi_hba *hisi_hba = shost_priv(shost);
return scnprintf(buf, PAGE_SIZE, "%u\n",
hisi_hba->intr_coal_ticks);
}
static ssize_t intr_coal_ticks_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
u32 intr_coal_ticks;
struct Scsi_Host *shost = class_to_shost(dev);
struct hisi_hba *hisi_hba = shost_priv(shost);
int ret;
ret = kstrtou32(buf, 10, &intr_coal_ticks);
if (ret) {
dev_err(dev, "Input data of interrupt coalesce unmatch\n");
return -EINVAL;
}
if (intr_coal_ticks >= BIT(24)) {
dev_err(dev, "intr_coal_ticks must be less than 2^24!\n");
return -EINVAL;
}
hisi_hba->intr_coal_ticks = intr_coal_ticks;
config_intr_coal_v3_hw(hisi_hba);
return count;
}
static DEVICE_ATTR_RW(intr_coal_ticks);
static ssize_t intr_coal_count_show(struct device *dev,
struct device_attribute
*attr, char *buf)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct hisi_hba *hisi_hba = shost_priv(shost);
return scnprintf(buf, PAGE_SIZE, "%u\n",
hisi_hba->intr_coal_count);
}
static ssize_t intr_coal_count_store(struct device *dev,
struct device_attribute
*attr, const char *buf, size_t count)
{
u32 intr_coal_count;
struct Scsi_Host *shost = class_to_shost(dev);
struct hisi_hba *hisi_hba = shost_priv(shost);
int ret;
ret = kstrtou32(buf, 10, &intr_coal_count);
if (ret) {
dev_err(dev, "Input data of interrupt coalesce unmatch\n");
return -EINVAL;
}
if (intr_coal_count >= BIT(8)) {
dev_err(dev, "intr_coal_count must be less than 2^8!\n");
return -EINVAL;
}
hisi_hba->intr_coal_count = intr_coal_count;
config_intr_coal_v3_hw(hisi_hba);
return count;
}
static DEVICE_ATTR_RW(intr_coal_count);
struct device_attribute *host_attrs_v3_hw[] = {
&dev_attr_phy_event_threshold,
&dev_attr_intr_conv,
&dev_attr_intr_coal_ticks,
&dev_attr_intr_coal_count,
NULL
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册