]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
net: hns3: Add enable and process hw errors from IGU, EGU and NCSI
authorShiju Jose <shiju.jose@huawei.com>
Fri, 19 Oct 2018 19:15:30 +0000 (20:15 +0100)
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
This patch adds enable and processing of hw errors from IGU(Ingress Unit),
EGU(Egress Unit) and NCSI(Network Controller Sideband Interface).

Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit bf1faf9415ddbfaa6d6a56a4bc594c92ca0f7309)
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/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.h

index 8525f18f3f5a34b2f90aa5a38fd049c82d69708f..97c90aa8345c666f211c13c1967842422e3be1d4 100644 (file)
@@ -212,6 +212,15 @@ enum hclge_opcode_type {
 
        /* Error INT commands */
        HCLGE_COMMON_ECC_INT_CFG        = 0x1505,
+       HCLGE_IGU_EGU_TNL_INT_QUERY     = 0x1802,
+       HCLGE_IGU_EGU_TNL_INT_EN        = 0x1803,
+       HCLGE_IGU_EGU_TNL_INT_CLR       = 0x1804,
+       HCLGE_IGU_COMMON_INT_QUERY      = 0x1805,
+       HCLGE_IGU_COMMON_INT_EN         = 0x1806,
+       HCLGE_IGU_COMMON_INT_CLR        = 0x1807,
+       HCLGE_NCSI_INT_QUERY            = 0x2400,
+       HCLGE_NCSI_INT_EN               = 0x2401,
+       HCLGE_NCSI_INT_CLR              = 0x2402,
 };
 
 #define HCLGE_TQP_REG_OFFSET           0x80000
index 8b37de49e416537619785b128166950a3bcd485e..34c4edd311c55186babf36534b8419961c0b8255 100644 (file)
@@ -85,6 +85,30 @@ static const struct hclge_hw_error hclge_tqp_int_ecc_int[] = {
        { /* sentinel */ }
 };
 
+static const struct hclge_hw_error hclge_igu_com_err_int[] = {
+       { .int_msk = BIT(0), .msg = "igu_rx_buf0_ecc_mbit_err" },
+       { .int_msk = BIT(1), .msg = "igu_rx_buf0_ecc_1bit_err" },
+       { .int_msk = BIT(2), .msg = "igu_rx_buf1_ecc_mbit_err" },
+       { .int_msk = BIT(3), .msg = "igu_rx_buf1_ecc_1bit_err" },
+       { /* sentinel */ }
+};
+
+static const struct hclge_hw_error hclge_igu_egu_tnl_err_int[] = {
+       { .int_msk = BIT(0), .msg = "rx_buf_overflow" },
+       { .int_msk = BIT(1), .msg = "rx_stp_fifo_overflow" },
+       { .int_msk = BIT(2), .msg = "rx_stp_fifo_undeflow" },
+       { .int_msk = BIT(3), .msg = "tx_buf_overflow" },
+       { .int_msk = BIT(4), .msg = "tx_buf_underrun" },
+       { .int_msk = BIT(5), .msg = "rx_stp_buf_overflow" },
+       { /* sentinel */ }
+};
+
+static const struct hclge_hw_error hclge_ncsi_err_int[] = {
+       { .int_msk = BIT(0), .msg = "ncsi_tx_ecc_1bit_err" },
+       { .int_msk = BIT(1), .msg = "ncsi_tx_ecc_mbit_err" },
+       { /* sentinel */ }
+};
+
 static void hclge_log_error(struct device *dev,
                            const struct hclge_hw_error *err_list,
                            u32 err_sts)
@@ -229,6 +253,75 @@ static int hclge_enable_common_error(struct hclge_dev *hdev, bool en)
        return ret;
 }
 
+static int hclge_enable_ncsi_error(struct hclge_dev *hdev, bool en)
+{
+       struct device *dev = &hdev->pdev->dev;
+       struct hclge_desc desc;
+       int ret;
+
+       if (hdev->pdev->revision < 0x21)
+               return 0;
+
+       /* enable/disable NCSI  error interrupts */
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_NCSI_INT_EN, false);
+       if (en)
+               desc.data[0] = cpu_to_le32(HCLGE_NCSI_ERR_INT_EN);
+       else
+               desc.data[0] = 0;
+
+       ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+       if (ret)
+               dev_err(dev,
+                       "failed(%d) to enable/disable NCSI error interrupts\n",
+                       ret);
+
+       return ret;
+}
+
+static int hclge_enable_igu_egu_error(struct hclge_dev *hdev, bool en)
+{
+       struct device *dev = &hdev->pdev->dev;
+       struct hclge_desc desc;
+       int ret;
+
+       /* enable/disable error interrupts */
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_IGU_COMMON_INT_EN, false);
+       if (en)
+               desc.data[0] = cpu_to_le32(HCLGE_IGU_ERR_INT_EN);
+       else
+               desc.data[0] = 0;
+       desc.data[1] = cpu_to_le32(HCLGE_IGU_ERR_INT_EN_MASK);
+
+       ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+       if (ret) {
+               dev_err(dev,
+                       "failed(%d) to enable/disable IGU common interrupts\n",
+                       ret);
+               return ret;
+       }
+
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_IGU_EGU_TNL_INT_EN, false);
+       if (en)
+               desc.data[0] = cpu_to_le32(HCLGE_IGU_TNL_ERR_INT_EN);
+       else
+               desc.data[0] = 0;
+       desc.data[1] = cpu_to_le32(HCLGE_IGU_TNL_ERR_INT_EN_MASK);
+
+       ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+       if (ret) {
+               dev_err(dev,
+                       "failed(%d) to enable/disable IGU-EGU TNL interrupts\n",
+                       ret);
+               return ret;
+       }
+
+       ret = hclge_enable_ncsi_error(hdev, en);
+       if (ret)
+               dev_err(dev, "fail(%d) to en/disable err int\n", ret);
+
+       return ret;
+}
+
 static void hclge_process_common_error(struct hclge_dev *hdev,
                                       enum hclge_err_int_type type)
 {
@@ -285,7 +378,104 @@ static void hclge_process_common_error(struct hclge_dev *hdev,
                        ret);
 }
 
+static void hclge_process_ncsi_error(struct hclge_dev *hdev,
+                                    enum hclge_err_int_type type)
+{
+       struct device *dev = &hdev->pdev->dev;
+       struct hclge_desc desc_rd;
+       struct hclge_desc desc_wr;
+       u32 err_sts;
+       int ret;
+
+       if (hdev->pdev->revision < 0x21)
+               return;
+
+       /* read NCSI error status */
+       ret = hclge_cmd_query_error(hdev, &desc_rd, HCLGE_NCSI_INT_QUERY,
+                                   0, 1, HCLGE_NCSI_ERR_INT_TYPE);
+       if (ret) {
+               dev_err(dev,
+                       "failed(=%d) to query NCSI error interrupt status\n",
+                       ret);
+               return;
+       }
+
+       /* log err */
+       err_sts = le32_to_cpu(desc_rd.data[0]);
+       hclge_log_error(dev, &hclge_ncsi_err_int[0], err_sts);
+
+       /* clear err int */
+       ret = hclge_cmd_clear_error(hdev, &desc_wr, &desc_rd,
+                                   HCLGE_NCSI_INT_CLR, 0);
+       if (ret)
+               dev_err(dev, "failed(=%d) to clear NCSI intrerrupt status\n",
+                       ret);
+}
+
+static void hclge_process_igu_egu_error(struct hclge_dev *hdev,
+                                       enum hclge_err_int_type int_type)
+{
+       struct device *dev = &hdev->pdev->dev;
+       struct hclge_desc desc_rd;
+       struct hclge_desc desc_wr;
+       u32 err_sts;
+       int ret;
+
+       /* read IGU common err sts */
+       ret = hclge_cmd_query_error(hdev, &desc_rd,
+                                   HCLGE_IGU_COMMON_INT_QUERY,
+                                   0, 1, int_type);
+       if (ret) {
+               dev_err(dev, "failed(=%d) to query IGU common int status\n",
+                       ret);
+               return;
+       }
+
+       /* log err */
+       err_sts = le32_to_cpu(desc_rd.data[0]) &
+                                  HCLGE_IGU_COM_INT_MASK;
+       hclge_log_error(dev, &hclge_igu_com_err_int[0], err_sts);
+
+       /* clear err int */
+       ret = hclge_cmd_clear_error(hdev, &desc_wr, &desc_rd,
+                                   HCLGE_IGU_COMMON_INT_CLR, 0);
+       if (ret) {
+               dev_err(dev, "failed(=%d) to clear IGU common int status\n",
+                       ret);
+               return;
+       }
+
+       /* read IGU-EGU TNL err sts */
+       ret = hclge_cmd_query_error(hdev, &desc_rd,
+                                   HCLGE_IGU_EGU_TNL_INT_QUERY,
+                                   0, 1, int_type);
+       if (ret) {
+               dev_err(dev, "failed(=%d) to query IGU-EGU TNL int status\n",
+                       ret);
+               return;
+       }
+
+       /* log err */
+       err_sts = le32_to_cpu(desc_rd.data[0]) &
+                                  HCLGE_IGU_EGU_TNL_INT_MASK;
+       hclge_log_error(dev, &hclge_igu_egu_tnl_err_int[0], err_sts);
+
+       /* clear err int */
+       ret = hclge_cmd_clear_error(hdev, &desc_wr, &desc_rd,
+                                   HCLGE_IGU_EGU_TNL_INT_CLR, 0);
+       if (ret) {
+               dev_err(dev, "failed(=%d) to clear IGU-EGU TNL int status\n",
+                       ret);
+               return;
+       }
+
+       hclge_process_ncsi_error(hdev, HCLGE_ERR_INT_RAS_NFE);
+}
+
 static const struct hclge_hw_blk hw_blk[] = {
+       { .msk = BIT(0), .name = "IGU_EGU",
+         .enable_error = hclge_enable_igu_egu_error,
+         .process_error = hclge_process_igu_egu_error, },
        { .msk = BIT(5), .name = "COMMON",
          .enable_error = hclge_enable_common_error,
          .process_error = hclge_process_common_error, },
index b413141085a54d30403911d0ce66d17aa9c10fc0..f46c8c29a17e88980a13640259d2d4a5be7fda97 100644 (file)
 #define HCLGE_IMP_RD_POISON_ERR_INT_EN_MASK    0x0100
 #define HCLGE_TQP_ECC_ERR_INT_EN       0x0FFF
 #define HCLGE_TQP_ECC_ERR_INT_EN_MASK  0x0FFF
+#define HCLGE_IGU_ERR_INT_EN   0x0000066F
+#define HCLGE_IGU_ERR_INT_EN_MASK      0x000F
+#define HCLGE_IGU_TNL_ERR_INT_EN    0x0002AABF
+#define HCLGE_IGU_TNL_ERR_INT_EN_MASK  0x003F
+#define HCLGE_NCSI_ERR_INT_EN  0x3
+#define HCLGE_NCSI_ERR_INT_TYPE        0x9
 
 #define HCLGE_IMP_TCM_ECC_INT_MASK     0xFFFF
 #define HCLGE_IMP_ITCM4_ECC_INT_MASK   0x3
@@ -35,6 +41,8 @@
 #define HCLGE_CMDQ_NIC_ECC_CLR_MASK    0xFFFF
 #define HCLGE_CMDQ_ROCEE_ECC_CLR_MASK  0xFFFF0000
 #define HCLGE_TQP_IMP_ERR_CLR_MASK     0x0FFF0001
+#define HCLGE_IGU_COM_INT_MASK         0xF
+#define HCLGE_IGU_EGU_TNL_INT_MASK     0x3F
 
 enum hclge_err_int_type {
        HCLGE_ERR_INT_MSIX = 0,