]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
net-next/hinic: replace disable_irq_nosync/enable_irq
authorXue Chaojing <xuechaojing@huawei.com>
Mon, 18 Mar 2019 08:30:35 +0000 (16:30 +0800)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 1 Apr 2019 12:37:29 +0000 (14:37 +0200)
BugLink: https://bugs.launchpad.net/bugs/1820187
In order to avoid frequent system interrupts when sending and
receiving packets. we replace disable_irq_nosync/enable_irq
with hinic_set_msix_state(), hinic_set_msix_state is used to
access memory mapped hinic devices.

Signed-off-by: Xue Chaojing <xuechaojing@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 905b464ad9008905db099f90ae20f373c7051804)
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
Acked-by: Kleber Souza <kleber.souza@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h
drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
drivers/net/ethernet/huawei/hinic/hinic_rx.c
drivers/net/ethernet/huawei/hinic/hinic_tx.c

index 79b56744708427eb741a1fc8f964f28beb3f0961..368db2009ba91edca6d291293f632b9dbb0e2672 100644 (file)
@@ -1011,3 +1011,16 @@ int hinic_hwdev_hw_ci_addr_set(struct hinic_hwdev *hwdev, struct hinic_sq *sq,
                                 &hw_ci, sizeof(hw_ci), NULL,
                                 NULL, HINIC_MGMT_MSG_SYNC);
 }
+
+/**
+ * hinic_hwdev_set_msix_state- set msix state
+ * @hwdev: the NIC HW device
+ * @msix_index: IRQ corresponding index number
+ * @flag: msix state
+ *
+ **/
+void hinic_hwdev_set_msix_state(struct hinic_hwdev *hwdev, u16 msix_index,
+                               enum hinic_msix_state flag)
+{
+       hinic_set_msix_state(hwdev->hwif, msix_index, flag);
+}
index d1a7d2522d828ec9471fa3b6cb3e13b17b0a7470..c9e621e19dd023118f8eb0727612df3a95712b31 100644 (file)
@@ -240,4 +240,7 @@ int hinic_hwdev_msix_set(struct hinic_hwdev *hwdev, u16 msix_index,
 int hinic_hwdev_hw_ci_addr_set(struct hinic_hwdev *hwdev, struct hinic_sq *sq,
                               u8 pending_limit, u8 coalesc_timer);
 
+void hinic_hwdev_set_msix_state(struct hinic_hwdev *hwdev, u16 msix_index,
+                               enum hinic_msix_state flag);
+
 #endif
index 823a17061a97970b2a25fabdf8bd4505e3e3f02d..9b160f07690419560d2712e74467cc338ff59fa8 100644 (file)
@@ -168,6 +168,22 @@ void hinic_db_state_set(struct hinic_hwif *hwif,
        hinic_hwif_write_reg(hwif, HINIC_CSR_FUNC_ATTR4_ADDR, attr4);
 }
 
+void hinic_set_msix_state(struct hinic_hwif *hwif, u16 msix_idx,
+                         enum hinic_msix_state flag)
+{
+       u32 offset = msix_idx * HINIC_PCI_MSIX_ENTRY_SIZE +
+                       HINIC_PCI_MSIX_ENTRY_VECTOR_CTRL;
+       u32 mask_bits;
+
+       mask_bits = readl(hwif->intr_regs_base + offset);
+       mask_bits &= ~HINIC_PCI_MSIX_ENTRY_CTRL_MASKBIT;
+
+       if (flag)
+               mask_bits |= HINIC_PCI_MSIX_ENTRY_CTRL_MASKBIT;
+
+       writel(mask_bits, hwif->intr_regs_base + offset);
+}
+
 /**
  * hwif_ready - test if the HW is ready for use
  * @hwif: the HW interface of a pci function device
@@ -321,6 +337,13 @@ int hinic_init_hwif(struct hinic_hwif *hwif, struct pci_dev *pdev)
                return -ENOMEM;
        }
 
+       hwif->intr_regs_base = pci_ioremap_bar(pdev, HINIC_PCI_INTR_REGS_BAR);
+       if (!hwif->intr_regs_base) {
+               dev_err(&pdev->dev, "Failed to map configuration regs\n");
+               err = -ENOMEM;
+               goto err_map_intr_bar;
+       }
+
        err = hwif_ready(hwif);
        if (err) {
                dev_err(&pdev->dev, "HW interface is not ready\n");
@@ -337,7 +360,11 @@ int hinic_init_hwif(struct hinic_hwif *hwif, struct pci_dev *pdev)
        return 0;
 
 err_hwif_ready:
+       iounmap(hwif->intr_regs_base);
+
+err_map_intr_bar:
        iounmap(hwif->cfg_regs_bar);
+
        return err;
 }
 
@@ -347,5 +374,6 @@ err_hwif_ready:
  **/
 void hinic_free_hwif(struct hinic_hwif *hwif)
 {
+       iounmap(hwif->intr_regs_base);
        iounmap(hwif->cfg_regs_bar);
 }
index 5b4760c0e9f531301db219de567198b01b81c995..22ec7f73e0a6b7089157723648559b32dac35a92 100644 (file)
 #define HINIC_IS_PPF(hwif)              (HINIC_FUNC_TYPE(hwif) == HINIC_PPF)
 
 #define HINIC_PCI_CFG_REGS_BAR          0
+#define HINIC_PCI_INTR_REGS_BAR         2
 #define HINIC_PCI_DB_BAR                4
 
 #define HINIC_PCIE_ST_DISABLE           0
 #define HINIC_EQ_MSIX_LLI_CREDIT_LIMIT_DEFAULT  0       /* Disabled */
 #define HINIC_EQ_MSIX_RESEND_TIMER_DEFAULT      7       /* max */
 
+#define HINIC_PCI_MSIX_ENTRY_SIZE               16
+#define HINIC_PCI_MSIX_ENTRY_VECTOR_CTRL        12
+#define HINIC_PCI_MSIX_ENTRY_CTRL_MASKBIT       1
+
 enum hinic_pcie_nosnoop {
        HINIC_PCIE_SNOOP        = 0,
        HINIC_PCIE_NO_SNOOP     = 1,
@@ -207,6 +212,11 @@ enum hinic_db_state {
        HINIC_DB_DISABLE = 1,
 };
 
+enum hinic_msix_state {
+       HINIC_MSIX_ENABLE,
+       HINIC_MSIX_DISABLE,
+};
+
 struct hinic_func_attr {
        u16                     func_idx;
        u8                      pf_idx;
@@ -226,6 +236,7 @@ struct hinic_func_attr {
 struct hinic_hwif {
        struct pci_dev          *pdev;
        void __iomem            *cfg_regs_bar;
+       void __iomem            *intr_regs_base;
 
        struct hinic_func_attr  attr;
 };
@@ -251,6 +262,9 @@ int hinic_msix_attr_get(struct hinic_hwif *hwif, u16 msix_index,
                        u8 *lli_timer, u8 *lli_credit_limit,
                        u8 *resend_timer);
 
+void hinic_set_msix_state(struct hinic_hwif *hwif, u16 msix_idx,
+                         enum hinic_msix_state flag);
+
 int hinic_msix_attr_cnt_clear(struct hinic_hwif *hwif, u16 msix_index);
 
 void hinic_set_pf_action(struct hinic_hwif *hwif, enum hinic_pf_action action);
index 0098b206e7e9412e4e626b59d60827a69f6640ea..b6d218768ec1e3cff1d715e2c8278c623dbfdf6c 100644 (file)
@@ -381,6 +381,7 @@ static int rxq_recv(struct hinic_rxq *rxq, int budget)
 static int rx_poll(struct napi_struct *napi, int budget)
 {
        struct hinic_rxq *rxq = container_of(napi, struct hinic_rxq, napi);
+       struct hinic_dev *nic_dev = netdev_priv(rxq->netdev);
        struct hinic_rq *rq = rxq->rq;
        int pkts;
 
@@ -389,7 +390,10 @@ static int rx_poll(struct napi_struct *napi, int budget)
                return budget;
 
        napi_complete(napi);
-       enable_irq(rq->irq);
+       hinic_hwdev_set_msix_state(nic_dev->hwdev,
+                                  rq->msix_entry,
+                                  HINIC_MSIX_ENABLE);
+
        return pkts;
 }
 
@@ -414,7 +418,10 @@ static irqreturn_t rx_irq(int irq, void *data)
        struct hinic_dev *nic_dev;
 
        /* Disable the interrupt until napi will be completed */
-       disable_irq_nosync(rq->irq);
+       nic_dev = netdev_priv(rxq->netdev);
+       hinic_hwdev_set_msix_state(nic_dev->hwdev,
+                                  rq->msix_entry,
+                                  HINIC_MSIX_DISABLE);
 
        nic_dev = netdev_priv(rxq->netdev);
        hinic_hwdev_msix_cnt_set(nic_dev->hwdev, rq->msix_entry);
index 11e73e67358d1ff728bbbd650a22f8bf6942a455..e17bf33eba0c5e09f7708dc52566b342f4777dc6 100644 (file)
@@ -655,7 +655,9 @@ static int free_tx_poll(struct napi_struct *napi, int budget)
 
        if (pkts < budget) {
                napi_complete(napi);
-               enable_irq(sq->irq);
+               hinic_hwdev_set_msix_state(nic_dev->hwdev,
+                                          sq->msix_entry,
+                                          HINIC_MSIX_ENABLE);
                return pkts;
        }
 
@@ -682,7 +684,9 @@ static irqreturn_t tx_irq(int irq, void *data)
        nic_dev = netdev_priv(txq->netdev);
 
        /* Disable the interrupt until napi will be completed */
-       disable_irq_nosync(txq->sq->irq);
+       hinic_hwdev_set_msix_state(nic_dev->hwdev,
+                                  txq->sq->msix_entry,
+                                  HINIC_MSIX_DISABLE);
 
        hinic_hwdev_msix_cnt_set(nic_dev->hwdev, txq->sq->msix_entry);