[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fd4109a250ec65c93a541c3b4088fe265c74cd7f.1756195078.git.zhuyikai1@h-partners.com>
Date: Tue, 26 Aug 2025 17:05:44 +0800
From: Fan Gong <gongfan1@...wei.com>
To: Fan Gong <gongfan1@...wei.com>, Zhu Yikai <zhuyikai1@...artners.com>
CC: <netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org>, "David S.
Miller" <davem@...emloft.net>, Eric Dumazet <edumazet@...gle.com>, Jakub
Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>, Simon Horman
<horms@...nel.org>, Andrew Lunn <andrew+netdev@...n.ch>,
<linux-doc@...r.kernel.org>, Jonathan Corbet <corbet@....net>, Bjorn Helgaas
<helgaas@...nel.org>, luosifu <luosifu@...wei.com>, Xin Guo
<guoxin09@...wei.com>, Shen Chenyang <shenchenyang1@...ilicon.com>, Zhou
Shuai <zhoushuai28@...wei.com>, Wu Like <wulike1@...wei.com>, Shi Jing
<shijing34@...wei.com>, Meny Yossefi <meny.yossefi@...wei.com>, Gur Stavi
<gur.stavi@...wei.com>, Lee Trager <lee@...ger.us>, Michael Ellerman
<mpe@...erman.id.au>, Vadim Fedorenko <vadim.fedorenko@...ux.dev>, Suman
Ghosh <sumang@...vell.com>, Przemek Kitszel <przemyslaw.kitszel@...el.com>,
Joe Damato <jdamato@...tly.com>, Christophe JAILLET
<christophe.jaillet@...adoo.fr>
Subject: [PATCH net-next v01 02/12] hinic3: HW management interfaces
Initialize hardware management config of irq, aeq and ceq.
These will send hardware messages to driver.
Co-developed-by: Xin Guo <guoxin09@...wei.com>
Signed-off-by: Xin Guo <guoxin09@...wei.com>
Co-developed-by: Zhu Yikai <zhuyikai1@...artners.com>
Signed-off-by: Zhu Yikai <zhuyikai1@...artners.com>
Signed-off-by: Fan Gong <gongfan1@...wei.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
.../ethernet/huawei/hinic3/hinic3_hw_cfg.c | 129 ++++++++++++++++++
.../ethernet/huawei/hinic3/hinic3_hw_cfg.h | 3 +
.../net/ethernet/huawei/hinic3/hinic3_hwdev.c | 11 ++
.../net/ethernet/huawei/hinic3/hinic3_lld.c | 1 +
.../net/ethernet/huawei/hinic3/hinic3_mgmt.c | 21 +++
.../net/ethernet/huawei/hinic3/hinic3_mgmt.h | 2 +
7 files changed, 168 insertions(+)
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 2a0ed8e2c63e..a9f055cfef52 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -14,6 +14,7 @@ hinic3-objs := hinic3_cmdq.o \
hinic3_lld.o \
hinic3_main.o \
hinic3_mbox.o \
+ hinic3_mgmt.o \
hinic3_netdev_ops.o \
hinic3_nic_cfg.o \
hinic3_nic_io.o \
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c
index 0599fc4f3fb0..e7ef450c4971 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c
@@ -8,6 +8,135 @@
#include "hinic3_hwif.h"
#include "hinic3_mbox.h"
+static int hinic3_init_irq_info(struct hinic3_hwdev *hwdev)
+{
+ struct hinic3_cfg_mgmt_info *cfg_mgmt = hwdev->cfg_mgmt;
+ struct hinic3_hwif *hwif = hwdev->hwif;
+ u16 intr_num = hwif->attr.num_irqs;
+ struct hinic3_irq_info *irq_info;
+ u16 intr_needed;
+
+ if (!intr_num) {
+ dev_err(hwdev->dev, "Irq num cfg in fw is zero, msix_flex_en %d\n",
+ hwif->attr.msix_flex_en);
+ return -EFAULT;
+ }
+
+ intr_needed = hwif->attr.msix_flex_en ? (hwif->attr.num_aeqs +
+ hwif->attr.num_ceqs + hwif->attr.num_sq) : intr_num;
+ if (intr_needed > intr_num) {
+ dev_warn(hwdev->dev, "Irq num cfg %d is less than the needed irq num %d msix_flex_en %d\n",
+ intr_num, intr_needed, hwdev->hwif->attr.msix_flex_en);
+ intr_needed = intr_num;
+ }
+
+ irq_info = &cfg_mgmt->irq_info;
+ irq_info->irq = kcalloc(intr_num, sizeof(struct hinic3_irq),
+ GFP_KERNEL);
+ if (!irq_info->irq)
+ return -ENOMEM;
+
+ irq_info->num_irq_hw = intr_needed;
+ mutex_init(&irq_info->irq_mutex);
+
+ return 0;
+}
+
+static int hinic3_init_irq_alloc_info(struct hinic3_hwdev *hwdev)
+{
+ struct hinic3_cfg_mgmt_info *cfg_mgmt = hwdev->cfg_mgmt;
+ struct hinic3_irq *irq = cfg_mgmt->irq_info.irq;
+ u16 nreq = cfg_mgmt->irq_info.num_irq_hw;
+ struct pci_dev *pdev = hwdev->pdev;
+ struct msix_entry *msix_entries;
+ int actual_irq;
+ u16 i;
+
+ if (!nreq) {
+ dev_err(hwdev->dev, "Number of interrupts must not be zero\n");
+ return -EINVAL;
+ }
+ msix_entries = kcalloc(nreq, sizeof(*msix_entries), GFP_KERNEL);
+ if (!msix_entries)
+ return -ENOMEM;
+
+ for (i = 0; i < nreq; i++)
+ msix_entries[i].entry = i;
+
+ actual_irq = pci_enable_msix_range(pdev, msix_entries, 2, nreq);
+ if (actual_irq < 0) {
+ dev_err(hwdev->dev, "Alloc msix entries with threshold 2 failed. actual_irq: %d\n",
+ actual_irq);
+ kfree(msix_entries);
+ return -ENOMEM;
+ }
+
+ nreq = actual_irq;
+ cfg_mgmt->irq_info.num_irq = nreq;
+
+ for (i = 0; i < nreq; ++i) {
+ irq[i].msix_entry_idx = msix_entries[i].entry;
+ irq[i].irq_id = msix_entries[i].vector;
+ irq[i].allocated = false;
+ }
+
+ kfree(msix_entries);
+
+ return 0;
+}
+
+int hinic3_init_cfg_mgmt(struct hinic3_hwdev *hwdev)
+{
+ struct hinic3_cfg_mgmt_info *cfg_mgmt;
+ int err;
+
+ if (!hwdev->hwif->attr.num_ceqs) {
+ dev_err(hwdev->dev, "Ceq num cfg in fw is zero\n");
+ return -EINVAL;
+ }
+
+ cfg_mgmt = kzalloc(sizeof(*cfg_mgmt), GFP_KERNEL);
+ if (!cfg_mgmt)
+ return -ENOMEM;
+
+ hwdev->cfg_mgmt = cfg_mgmt;
+
+ err = hinic3_init_irq_info(hwdev);
+ if (err) {
+ dev_err(hwdev->dev, "Failed to init hinic3_irq_mgmt_info, err: %d\n",
+ err);
+ goto err_free_cfg_mgmt;
+ }
+
+ err = hinic3_init_irq_alloc_info(hwdev);
+ if (err) {
+ dev_err(hwdev->dev, "Failed to init hinic3_irq_info, err: %d\n",
+ err);
+ goto err_free_irq_info;
+ }
+
+ return 0;
+
+err_free_irq_info:
+ kfree(cfg_mgmt->irq_info.irq);
+ cfg_mgmt->irq_info.irq = NULL;
+
+err_free_cfg_mgmt:
+ kfree(cfg_mgmt);
+
+ return err;
+}
+
+void hinic3_free_cfg_mgmt(struct hinic3_hwdev *hwdev)
+{
+ struct hinic3_cfg_mgmt_info *cfg_mgmt = hwdev->cfg_mgmt;
+
+ pci_disable_msix(hwdev->pdev);
+ kfree(cfg_mgmt->irq_info.irq);
+ cfg_mgmt->irq_info.irq = NULL;
+ kfree(cfg_mgmt);
+}
+
int hinic3_alloc_irqs(struct hinic3_hwdev *hwdev, u16 num,
struct msix_entry *alloc_arr, u16 *act_num)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.h
index e017b1ae9f05..5978cbd56fb2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.h
@@ -42,6 +42,9 @@ struct hinic3_cfg_mgmt_info {
struct hinic3_dev_cap cap;
};
+int hinic3_init_cfg_mgmt(struct hinic3_hwdev *hwdev);
+void hinic3_free_cfg_mgmt(struct hinic3_hwdev *hwdev);
+
int hinic3_alloc_irqs(struct hinic3_hwdev *hwdev, u16 num,
struct msix_entry *alloc_arr, u16 *act_num);
void hinic3_free_irq(struct hinic3_hwdev *hwdev, u32 irq_id);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c
index d145d3b05e19..345f570abc1e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
+#include "hinic3_eqs.h"
#include "hinic3_hw_comm.h"
#include "hinic3_hwdev.h"
#include "hinic3_hwif.h"
@@ -60,8 +61,17 @@ int hinic3_init_hwdev(struct pci_dev *pdev)
goto err_free_hwif;
}
+ err = hinic3_init_cfg_mgmt(hwdev);
+ if (err) {
+ dev_err(hwdev->dev, "Failed to init config mgmt\n");
+ goto err_destroy_workqueue;
+ }
+
return 0;
+err_destroy_workqueue:
+ destroy_workqueue(hwdev->workq);
+
err_free_hwif:
hinic3_free_hwif(hwdev);
@@ -74,6 +84,7 @@ int hinic3_init_hwdev(struct pci_dev *pdev)
void hinic3_free_hwdev(struct hinic3_hwdev *hwdev)
{
+ hinic3_free_cfg_mgmt(hwdev);
destroy_workqueue(hwdev->workq);
hinic3_free_hwif(hwdev);
kfree(hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c
index 0df6b3ae5805..3db8241a3b0c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c
@@ -311,6 +311,7 @@ static void hinic3_func_uninit(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ hinic3_flush_mgmt_workq(pci_adapter->hwdev);
hinic3_detach_aux_devices(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c
new file mode 100644
index 000000000000..c38d10cd7fac
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
+
+#include "hinic3_eqs.h"
+#include "hinic3_hwdev.h"
+#include "hinic3_mbox.h"
+#include "hinic3_mgmt.h"
+
+void hinic3_flush_mgmt_workq(struct hinic3_hwdev *hwdev)
+{
+ if (hwdev->aeqs)
+ flush_workqueue(hwdev->aeqs->workq);
+}
+
+void hinic3_mgmt_msg_aeqe_handler(struct hinic3_hwdev *hwdev, u8 *header,
+ u8 size)
+{
+ if (MBOX_MSG_HEADER_GET(*(__force __le64 *)header, SOURCE) ==
+ MBOX_MSG_FROM_MBOX)
+ hinic3_mbox_func_aeqe_handler(hwdev, header, size);
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.h
index 4edabeb32112..bbef3b32a6ec 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.h
@@ -9,5 +9,7 @@
struct hinic3_hwdev;
void hinic3_flush_mgmt_workq(struct hinic3_hwdev *hwdev);
+void hinic3_mgmt_msg_aeqe_handler(struct hinic3_hwdev *hwdev,
+ u8 *header, u8 size);
#endif
--
2.43.0
Powered by blists - more mailing lists