]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
scsi: hisi_sas: Add support for interrupt converge for v3 hw
authorXiang Chen <chenxiang66@hisilicon.com>
Fri, 9 Nov 2018 14:06:33 +0000 (22:06 +0800)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Mon, 14 Jan 2019 09:28:55 +0000 (09:28 +0000)
BugLink: https://bugs.launchpad.net/bugs/1810457
If CQ_INT_CONVERGE_EN is enabled, the interrupts of all the 16 CQ queues
will be reported by CQ0.

So we need to change the process of CQ tasklet for this situation.

Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
(cherry picked from commit 488cf558e3d7c95daf737d9cae165019ee3f2840)
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c

index 2fd5a83850f39e61d1b084f3fd9b8a9af0b43c54..546eaf99ffc426ef39fb1593cfc2590e60dd2f8a 100644 (file)
@@ -42,6 +42,7 @@
 #define MAX_CON_TIME_LIMIT_TIME                0xa4
 #define BUS_INACTIVE_LIMIT_TIME                0xa8
 #define REJECT_TO_OPEN_LIMIT_TIME      0xac
+#define CQ_INT_CONVERGE_EN             0xb0
 #define CFG_AGING_TIME                 0xbc
 #define HGC_DFX_CFG2                   0xc0
 #define CFG_ABT_SET_QUERY_IPTT 0xd4
@@ -371,6 +372,9 @@ struct hisi_sas_err_record_v3 {
        ((fis.command == ATA_CMD_DEV_RESET) && \
        ((fis.control & ATA_SRST) != 0)))
 
+static bool hisi_sas_intr_conv;
+MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)");
+
 static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
 {
        void __iomem *regs = hisi_hba->regs + off;
@@ -436,6 +440,8 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
        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);
+       hisi_sas_write32(hisi_hba, CQ_INT_CONVERGE_EN,
+                        hisi_sas_intr_conv);
        hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff);
        hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff);
        hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff);
@@ -1878,10 +1884,12 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
        for (i = 0; i < hisi_hba->queue_count; i++) {
                struct hisi_sas_cq *cq = &hisi_hba->cq[i];
                struct tasklet_struct *t = &cq->tasklet;
+               int nr = hisi_sas_intr_conv ? 16 : 16 + i;
+               unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0;
 
-               rc = devm_request_irq(dev, pci_irq_vector(pdev, i+16),
-                                         cq_interrupt_v3_hw, 0,
-                                         DRV_NAME " cq", cq);
+               rc = devm_request_irq(dev, pci_irq_vector(pdev, nr),
+                                     cq_interrupt_v3_hw, irqflags,
+                                     DRV_NAME " cq", cq);
                if (rc) {
                        dev_err(dev,
                                "could not request cq%d interrupt, rc=%d\n",
@@ -1898,8 +1906,9 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
 free_cq_irqs:
        for (k = 0; k < i; k++) {
                struct hisi_sas_cq *cq = &hisi_hba->cq[k];
+               int nr = hisi_sas_intr_conv ? 16 : 16 + k;
 
-               free_irq(pci_irq_vector(pdev, k+16), cq);
+               free_irq(pci_irq_vector(pdev, nr), cq);
        }
        free_irq(pci_irq_vector(pdev, 11), hisi_hba);
 free_chnl_interrupt:
@@ -2089,8 +2098,16 @@ static void wait_cmds_complete_timeout_v3_hw(struct hisi_hba *hisi_hba,
        dev_dbg(dev, "wait commands complete %dms\n", time);
 }
 
+static ssize_t intr_conv_v3_hw_show(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       return scnprintf(buf, PAGE_SIZE, "%u\n", hisi_sas_intr_conv);
+}
+static DEVICE_ATTR_RO(intr_conv_v3_hw);
+
 struct device_attribute *host_attrs_v3_hw[] = {
        &dev_attr_phy_event_threshold,
+       &dev_attr_intr_conv_v3_hw,
        NULL
 };
 
@@ -2303,8 +2320,9 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba)
        free_irq(pci_irq_vector(pdev, 11), hisi_hba);
        for (i = 0; i < hisi_hba->queue_count; i++) {
                struct hisi_sas_cq *cq = &hisi_hba->cq[i];
+               int nr = hisi_sas_intr_conv ? 16 : 16 + i;
 
-               free_irq(pci_irq_vector(pdev, i+16), cq);
+               free_irq(pci_irq_vector(pdev, nr), cq);
        }
        pci_free_irq_vectors(pdev);
 }
@@ -2626,6 +2644,7 @@ static struct pci_driver sas_v3_pci_driver = {
 };
 
 module_pci_driver(sas_v3_pci_driver);
+module_param_named(intr_conv, hisi_sas_intr_conv, bool, 0444);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("John Garry <john.garry@huawei.com>");