* [PATCH v5 0/5] Add driver for 1Gbe network chips from MUCSE
@ 2025-08-18 11:28 Dong Yibo
2025-08-18 11:28 ` [PATCH v5 1/5] net: rnpgbe: Add build support for rnpgbe Dong Yibo
` (4 more replies)
0 siblings, 5 replies; 29+ messages in thread
From: Dong Yibo @ 2025-08-18 11:28 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran
Cc: netdev, linux-doc, linux-kernel, dong100
Hi maintainers,
This patch series is v5 to introduce support for MUCSE N500/N210 1Gbps
Ethernet controllers. I divide codes into multiple series, this is the
first one which only register netdev without true tx/rx functions.
The driver has been tested on the following platform:
- Kernel version: 6.16.0
- Intel Xeon Processor
Changelog:
v4 -> v5:
[patch 1/5]:
1. Remove system state and Wol code.
[patch 2/5]:
1. Use define for mbx offset registers.
2. Remove 'switch (hw->hw_type)' in rnpgbe_add_adapter.
3. Remove 'hw->driver_version' in hw structure.
[patch 3/5]:
1. Return -EINVAL if 'size > mbx->size' in mucse_read_mbx.
2. Remove mbx->ops, call the functions directly.
3. Rewrite mbx_wr32, mbx_rd32.
[patch 4/5]:
1. Change laber 'quit' to 'out' in mucse_fw_send_cmd_wait.
2. Fix 'mucse_mbx_fw_post_req' to follow 'one lock statement and
3. Use "timeout_jiffies" instead of "timeout_jiffes".
4. Fix 'pfvfnum' in define structure to improve padding problem.
5. Fix 'build_phy_abilities_req' pass the same parameter twice.
6. Use wait_event_timeout, not wait_event_interruptible_timeout.
7. Move 'build**' functions to .c.
8. Remove L_WD, do it in the lowest layer.
9. Add MBX_REQ_HDR_LEN in build**.
[patch 5/5]:
1. Remove no-use define dma_wr32.
2. Rename dma_rd32 to rnpgbe_dma_rd32.
3. Fix extra indentation in 'rnpgbe_xmit_frame'.
4. Return -EINVAL if get perm_addr failed in 'rnpgbe_get_permanent_mac'.
5. Remove flags 'M_FLAGS_INIT_MAC_ADDRESS'.
6. Remove 'netdev->reg_state' in rnpgbe_rm_adapter.
links:
v4: https://lore.kernel.org/netdev/20250814073855.1060601-1-dong100@mucse.com/
v3: https://lore.kernel.org/netdev/20250812093937.882045-1-dong100@mucse.com/
v2: https://lore.kernel.org/netdev/20250721113238.18615-1-dong100@mucse.com/
v1: https://lore.kernel.org/netdev/20250703014859.210110-1-dong100@mucse.com/
Dong Yibo (5):
net: rnpgbe: Add build support for rnpgbe
net: rnpgbe: Add n500/n210 chip support
net: rnpgbe: Add basic mbx ops support
net: rnpgbe: Add basic mbx_fw support
net: rnpgbe: Add register_netdev
.../device_drivers/ethernet/index.rst | 1 +
.../device_drivers/ethernet/mucse/rnpgbe.rst | 21 +
MAINTAINERS | 8 +
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/mucse/Kconfig | 34 ++
drivers/net/ethernet/mucse/Makefile | 7 +
drivers/net/ethernet/mucse/rnpgbe/Makefile | 11 +
drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h | 117 +++++
.../net/ethernet/mucse/rnpgbe/rnpgbe_chip.c | 160 ++++++
drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h | 26 +
.../net/ethernet/mucse/rnpgbe/rnpgbe_main.c | 310 +++++++++++
.../net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c | 481 ++++++++++++++++++
.../net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h | 31 ++
.../net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c | 333 ++++++++++++
.../net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h | 155 ++++++
16 files changed, 1697 insertions(+)
create mode 100644 Documentation/networking/device_drivers/ethernet/mucse/rnpgbe.rst
create mode 100644 drivers/net/ethernet/mucse/Kconfig
create mode 100644 drivers/net/ethernet/mucse/Makefile
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/Makefile
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h
--
2.25.1
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH v5 1/5] net: rnpgbe: Add build support for rnpgbe
2025-08-18 11:28 [PATCH v5 0/5] Add driver for 1Gbe network chips from MUCSE Dong Yibo
@ 2025-08-18 11:28 ` Dong Yibo
2025-08-20 20:06 ` Andrew Lunn
2025-08-18 11:28 ` [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support Dong Yibo
` (3 subsequent siblings)
4 siblings, 1 reply; 29+ messages in thread
From: Dong Yibo @ 2025-08-18 11:28 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran
Cc: netdev, linux-doc, linux-kernel, dong100
Add build options and doc for mucse.
Initialize pci device access for MUCSE devices.
Signed-off-by: Dong Yibo <dong100@mucse.com>
---
.../device_drivers/ethernet/index.rst | 1 +
.../device_drivers/ethernet/mucse/rnpgbe.rst | 21 +++
MAINTAINERS | 8 +
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/mucse/Kconfig | 34 +++++
drivers/net/ethernet/mucse/Makefile | 7 +
drivers/net/ethernet/mucse/rnpgbe/Makefile | 8 +
drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h | 24 +++
.../net/ethernet/mucse/rnpgbe/rnpgbe_main.c | 144 ++++++++++++++++++
10 files changed, 249 insertions(+)
create mode 100644 Documentation/networking/device_drivers/ethernet/mucse/rnpgbe.rst
create mode 100644 drivers/net/ethernet/mucse/Kconfig
create mode 100644 drivers/net/ethernet/mucse/Makefile
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/Makefile
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
diff --git a/Documentation/networking/device_drivers/ethernet/index.rst b/Documentation/networking/device_drivers/ethernet/index.rst
index 40ac552641a3..c8abadbe15ee 100644
--- a/Documentation/networking/device_drivers/ethernet/index.rst
+++ b/Documentation/networking/device_drivers/ethernet/index.rst
@@ -47,6 +47,7 @@ Contents:
mellanox/mlx5/index
meta/fbnic
microsoft/netvsc
+ mucse/rnpgbe
neterion/s2io
netronome/nfp
pensando/ionic
diff --git a/Documentation/networking/device_drivers/ethernet/mucse/rnpgbe.rst b/Documentation/networking/device_drivers/ethernet/mucse/rnpgbe.rst
new file mode 100644
index 000000000000..7562fb6b8f61
--- /dev/null
+++ b/Documentation/networking/device_drivers/ethernet/mucse/rnpgbe.rst
@@ -0,0 +1,21 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================================================
+Linux Base Driver for MUCSE(R) Gigabit PCI Express Adapters
+===========================================================
+
+MUCSE Gigabit Linux driver.
+Copyright (c) 2020 - 2025 MUCSE Co.,Ltd.
+
+Identifying Your Adapter
+========================
+The driver is compatible with devices based on the following:
+
+ * MUCSE(R) Ethernet Controller N500 series
+ * MUCSE(R) Ethernet Controller N210 series
+
+Support
+=======
+ If you have problems with the software or hardware, please contact our
+ customer support team via email at techsupport@mucse.com or check our
+ website at https://www.mucse.com/en/
diff --git a/MAINTAINERS b/MAINTAINERS
index 4dcce7a5894b..edfb0a6a811d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17276,6 +17276,14 @@ T: git git://linuxtv.org/media.git
F: Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.yaml
F: drivers/media/i2c/mt9v111.c
+MUCSE ETHERNET DRIVER
+M: Yibo Dong <dong100@mucse.com>
+L: netdev@vger.kernel.org
+S: Maintained
+W: https://www.mucse.com/en/
+F: Documentation/networking/device_drivers/ethernet/mucse/
+F: drivers/net/ethernet/mucse/
+
MULTIFUNCTION DEVICES (MFD)
M: Lee Jones <lee@kernel.org>
S: Maintained
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index f86d4557d8d7..167388f9c744 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -129,6 +129,7 @@ source "drivers/net/ethernet/microchip/Kconfig"
source "drivers/net/ethernet/mscc/Kconfig"
source "drivers/net/ethernet/microsoft/Kconfig"
source "drivers/net/ethernet/moxa/Kconfig"
+source "drivers/net/ethernet/mucse/Kconfig"
source "drivers/net/ethernet/myricom/Kconfig"
config FEALNX
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 67182339469a..1b8c4df3f594 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_NET_VENDOR_MICREL) += micrel/
obj-$(CONFIG_NET_VENDOR_MICROCHIP) += microchip/
obj-$(CONFIG_NET_VENDOR_MICROSEMI) += mscc/
obj-$(CONFIG_NET_VENDOR_MOXART) += moxa/
+obj-$(CONFIG_NET_VENDOR_MUCSE) += mucse/
obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/
obj-$(CONFIG_FEALNX) += fealnx.o
obj-$(CONFIG_NET_VENDOR_NATSEMI) += natsemi/
diff --git a/drivers/net/ethernet/mucse/Kconfig b/drivers/net/ethernet/mucse/Kconfig
new file mode 100644
index 000000000000..be0fdf268484
--- /dev/null
+++ b/drivers/net/ethernet/mucse/Kconfig
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Mucse network device configuration
+#
+
+config NET_VENDOR_MUCSE
+ bool "Mucse devices"
+ default y
+ help
+ If you have a network (Ethernet) card from Mucse(R), say Y.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Mucse(R) cards. If you say Y, you will
+ be asked for your specific card in the following questions.
+
+if NET_VENDOR_MUCSE
+
+config MGBE
+ tristate "Mucse(R) 1GbE PCI Express adapters support"
+ depends on PCI
+ select PAGE_POOL
+ help
+ This driver supports Mucse(R) 1GbE PCI Express family of
+ adapters.
+
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/device_drivers/ethernet/mucse/rnpgbe.rst>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called rnpgbe.
+
+endif # NET_VENDOR_MUCSE
+
diff --git a/drivers/net/ethernet/mucse/Makefile b/drivers/net/ethernet/mucse/Makefile
new file mode 100644
index 000000000000..675173fa05f7
--- /dev/null
+++ b/drivers/net/ethernet/mucse/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2020 - 2025 MUCSE Corporation.
+#
+# Makefile for the MUCSE(R) network device drivers
+#
+
+obj-$(CONFIG_MGBE) += rnpgbe/
diff --git a/drivers/net/ethernet/mucse/rnpgbe/Makefile b/drivers/net/ethernet/mucse/rnpgbe/Makefile
new file mode 100644
index 000000000000..9df536f0d04c
--- /dev/null
+++ b/drivers/net/ethernet/mucse/rnpgbe/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2020 - 2025 MUCSE Corporation.
+#
+# Makefile for the MUCSE(R) 1GbE PCI Express ethernet driver
+#
+
+obj-$(CONFIG_MGBE) += rnpgbe.o
+rnpgbe-objs := rnpgbe_main.o
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
new file mode 100644
index 000000000000..64b2c093bc6e
--- /dev/null
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2020 - 2025 Mucse Corporation. */
+
+#ifndef _RNPGBE_H
+#define _RNPGBE_H
+
+enum rnpgbe_boards {
+ board_n500,
+ board_n210,
+ board_n210L,
+};
+
+struct mucse {
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+};
+
+/* Device IDs */
+#define PCI_VENDOR_ID_MUCSE 0x8848
+#define PCI_DEVICE_ID_N500_QUAD_PORT 0x8308
+#define PCI_DEVICE_ID_N500_DUAL_PORT 0x8318
+#define PCI_DEVICE_ID_N210 0x8208
+#define PCI_DEVICE_ID_N210L 0x820a
+#endif /* _RNPGBE_H */
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
new file mode 100644
index 000000000000..2090942ef633
--- /dev/null
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2020 - 2025 Mucse Corporation. */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "rnpgbe.h"
+
+static const char rnpgbe_driver_name[] = "rnpgbe";
+
+/* rnpgbe_pci_tbl - PCI Device ID Table
+ *
+ * { PCI_DEVICE(Vendor ID, Device ID),
+ * driver_data (used for different hw chip) }
+ */
+static struct pci_device_id rnpgbe_pci_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_MUCSE, PCI_DEVICE_ID_N500_QUAD_PORT),
+ .driver_data = board_n500},
+ { PCI_DEVICE(PCI_VENDOR_ID_MUCSE, PCI_DEVICE_ID_N500_DUAL_PORT),
+ .driver_data = board_n500},
+ { PCI_DEVICE(PCI_VENDOR_ID_MUCSE, PCI_DEVICE_ID_N210),
+ .driver_data = board_n210},
+ { PCI_DEVICE(PCI_VENDOR_ID_MUCSE, PCI_DEVICE_ID_N210L),
+ .driver_data = board_n210L},
+ /* required last entry */
+ {0, },
+};
+
+/**
+ * rnpgbe_probe - Device initialization routine
+ * @pdev: PCI device information struct
+ * @id: entry in rnpgbe_pci_tbl
+ *
+ * rnpgbe_probe initializes a PF adapter identified by a pci_dev
+ * structure.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+static int rnpgbe_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ int err;
+
+ err = pci_enable_device_mem(pdev);
+ if (err)
+ return err;
+
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(56));
+ if (err) {
+ dev_err(&pdev->dev,
+ "No usable DMA configuration, aborting %d\n", err);
+ goto err_dma;
+ }
+
+ err = pci_request_mem_regions(pdev, rnpgbe_driver_name);
+ if (err) {
+ dev_err(&pdev->dev,
+ "pci_request_selected_regions failed 0x%x\n", err);
+ goto err_dma;
+ }
+
+ pci_set_master(pdev);
+ pci_save_state(pdev);
+
+ return 0;
+err_dma:
+ pci_disable_device(pdev);
+ return err;
+}
+
+/**
+ * rnpgbe_remove - Device removal routine
+ * @pdev: PCI device information struct
+ *
+ * rnpgbe_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device. This could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ **/
+static void rnpgbe_remove(struct pci_dev *pdev)
+{
+ pci_release_mem_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+/**
+ * rnpgbe_dev_shutdown - Device shutdown routine
+ * @pdev: PCI device information struct
+ **/
+static void rnpgbe_dev_shutdown(struct pci_dev *pdev)
+{
+ pci_disable_device(pdev);
+}
+
+/**
+ * rnpgbe_shutdown - Device shutdown routine
+ * @pdev: PCI device information struct
+ *
+ * rnpgbe_shutdown is called by the PCI subsystem to alert the driver
+ * that os shutdown. Device should setup wakeup state here.
+ **/
+static void rnpgbe_shutdown(struct pci_dev *pdev)
+{
+ rnpgbe_dev_shutdown(pdev);
+}
+
+static struct pci_driver rnpgbe_driver = {
+ .name = rnpgbe_driver_name,
+ .id_table = rnpgbe_pci_tbl,
+ .probe = rnpgbe_probe,
+ .remove = rnpgbe_remove,
+ .shutdown = rnpgbe_shutdown,
+};
+
+/**
+ * rnpgbe_init_module - Driver init routine
+ *
+ * rnpgbe_init_module is called when driver insmod
+ *
+ * @return: 0 on success, negative on failure
+ **/
+static int __init rnpgbe_init_module(void)
+{
+ return pci_register_driver(&rnpgbe_driver);
+}
+
+module_init(rnpgbe_init_module);
+
+/**
+ * rnpgbe_exit_module - Driver remove routine
+ *
+ * rnpgbe_exit_module is called when driver is removed
+ **/
+static void __exit rnpgbe_exit_module(void)
+{
+ pci_unregister_driver(&rnpgbe_driver);
+}
+
+module_exit(rnpgbe_exit_module);
+
+MODULE_DEVICE_TABLE(pci, rnpgbe_pci_tbl);
+MODULE_AUTHOR("Mucse Corporation, <techsupport@mucse.com>");
+MODULE_DESCRIPTION("Mucse(R) 1 Gigabit PCI Express Network Driver");
+MODULE_LICENSE("GPL");
--
2.25.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support
2025-08-18 11:28 [PATCH v5 0/5] Add driver for 1Gbe network chips from MUCSE Dong Yibo
2025-08-18 11:28 ` [PATCH v5 1/5] net: rnpgbe: Add build support for rnpgbe Dong Yibo
@ 2025-08-18 11:28 ` Dong Yibo
2025-08-19 13:59 ` Vadim Fedorenko
2025-08-20 20:16 ` Andrew Lunn
2025-08-18 11:28 ` [PATCH v5 3/5] net: rnpgbe: Add basic mbx ops support Dong Yibo
` (2 subsequent siblings)
4 siblings, 2 replies; 29+ messages in thread
From: Dong Yibo @ 2025-08-18 11:28 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran
Cc: netdev, linux-doc, linux-kernel, dong100
Initialize n500/n210 chip bar resource map and
dma, eth, mbx ... info for future use.
Signed-off-by: Dong Yibo <dong100@mucse.com>
---
drivers/net/ethernet/mucse/rnpgbe/Makefile | 3 +-
drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h | 54 +++++++++++
.../net/ethernet/mucse/rnpgbe/rnpgbe_chip.c | 85 +++++++++++++++++
drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h | 23 +++++
.../net/ethernet/mucse/rnpgbe/rnpgbe_main.c | 91 +++++++++++++++++++
5 files changed, 255 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
diff --git a/drivers/net/ethernet/mucse/rnpgbe/Makefile b/drivers/net/ethernet/mucse/rnpgbe/Makefile
index 9df536f0d04c..42c359f459d9 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/Makefile
+++ b/drivers/net/ethernet/mucse/rnpgbe/Makefile
@@ -5,4 +5,5 @@
#
obj-$(CONFIG_MGBE) += rnpgbe.o
-rnpgbe-objs := rnpgbe_main.o
+rnpgbe-objs := rnpgbe_main.o\
+ rnpgbe_chip.o
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
index 64b2c093bc6e..a1553c1efa86 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
@@ -4,15 +4,69 @@
#ifndef _RNPGBE_H
#define _RNPGBE_H
+#include <linux/types.h>
+
+extern const struct rnpgbe_info rnpgbe_n500_info;
+extern const struct rnpgbe_info rnpgbe_n210_info;
+extern const struct rnpgbe_info rnpgbe_n210L_info;
+
enum rnpgbe_boards {
board_n500,
board_n210,
board_n210L,
};
+enum rnpgbe_hw_type {
+ rnpgbe_hw_n500 = 0,
+ rnpgbe_hw_n210,
+ rnpgbe_hw_n210L,
+ rnpgbe_hw_unknown
+};
+
+struct mucse_dma_info {
+ void __iomem *dma_base_addr;
+ void __iomem *dma_ring_addr;
+ u32 dma_version;
+};
+
+struct mucse_eth_info {
+ void __iomem *eth_base_addr;
+};
+
+struct mucse_mac_info {
+ void __iomem *mac_addr;
+};
+
+struct mucse_mbx_info {
+ /* fw <--> pf mbx */
+ u32 fw_pf_shm_base;
+ u32 pf2fw_mbox_ctrl;
+ u32 fw_pf_mbox_mask;
+ u32 fw2pf_mbox_vec;
+};
+
+struct mucse_hw {
+ void __iomem *hw_addr;
+ void __iomem *ring_msix_base;
+ struct pci_dev *pdev;
+ enum rnpgbe_hw_type hw_type;
+ struct mucse_dma_info dma;
+ struct mucse_eth_info eth;
+ struct mucse_mac_info mac;
+ struct mucse_mbx_info mbx;
+ u32 usecstocount;
+};
+
struct mucse {
struct net_device *netdev;
struct pci_dev *pdev;
+ struct mucse_hw hw;
+};
+
+struct rnpgbe_info {
+ int total_queue_pair_cnts;
+ enum rnpgbe_hw_type hw_type;
+ void (*init)(struct mucse_hw *hw);
};
/* Device IDs */
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
new file mode 100644
index 000000000000..4db5c910065e
--- /dev/null
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2020 - 2025 Mucse Corporation. */
+
+#include "rnpgbe.h"
+#include "rnpgbe_hw.h"
+
+/**
+ * rnpgbe_init_common - Setup common attribute
+ * @hw: hw information structure
+ **/
+static void rnpgbe_init_common(struct mucse_hw *hw)
+{
+ struct mucse_dma_info *dma = &hw->dma;
+ struct mucse_eth_info *eth = &hw->eth;
+ struct mucse_mac_info *mac = &hw->mac;
+ struct mucse_mbx_info *mbx = &hw->mbx;
+
+ dma->dma_base_addr = hw->hw_addr;
+ dma->dma_ring_addr = hw->hw_addr + RNPGBE_RING_BASE;
+
+ eth->eth_base_addr = hw->hw_addr + RNPGBE_ETH_BASE;
+
+ mac->mac_addr = hw->hw_addr + RNPGBE_MAC_BASE;
+
+ mbx->pf2fw_mbox_ctrl = GBE_PF2FW_MBX_MASK_OFFSET;
+ mbx->fw_pf_mbox_mask = GBE_FWPF_MBX_MASK;
+}
+
+/**
+ * rnpgbe_init_n500 - Setup n500 hw info
+ * @hw: hw information structure
+ *
+ * rnpgbe_init_n500 initializes all private
+ * structure, such as dma, eth, mac and mbx base on
+ * hw->hw_addr for n500
+ **/
+static void rnpgbe_init_n500(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+
+ rnpgbe_init_common(hw);
+
+ mbx->fw2pf_mbox_vec = N500_FW2PF_MBX_VEC_OFFSET;
+ mbx->fw_pf_shm_base = N500_FWPF_SHM_BASE_OFFSET;
+ hw->ring_msix_base = hw->hw_addr + N500_RING_MSIX_OFFSET;
+ hw->usecstocount = N500_DEFAULT_USECSTOCOUNT;
+}
+
+/**
+ * rnpgbe_init_n210 - Setup n210 hw info
+ * @hw: hw information structure
+ *
+ * rnpgbe_init_n210 initializes all private
+ * structure, such as dma, eth, mac and mbx base on
+ * hw->hw_addr for n210
+ **/
+static void rnpgbe_init_n210(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+
+ rnpgbe_init_common(hw);
+
+ mbx->fw2pf_mbox_vec = N210_FW2PF_MBX_VEC_OFFSET;
+ mbx->fw_pf_shm_base = N210_FWPF_SHM_BASE_OFFSET;
+ hw->ring_msix_base = hw->hw_addr + N210_RING_MSIX_OFFSET;
+ hw->usecstocount = N210_DEFAULT_USECSTOCOUNT;
+}
+
+const struct rnpgbe_info rnpgbe_n500_info = {
+ .total_queue_pair_cnts = RNPGBE_MAX_QUEUES,
+ .hw_type = rnpgbe_hw_n500,
+ .init = &rnpgbe_init_n500,
+};
+
+const struct rnpgbe_info rnpgbe_n210_info = {
+ .total_queue_pair_cnts = RNPGBE_MAX_QUEUES,
+ .hw_type = rnpgbe_hw_n210,
+ .init = &rnpgbe_init_n210,
+};
+
+const struct rnpgbe_info rnpgbe_n210L_info = {
+ .total_queue_pair_cnts = RNPGBE_MAX_QUEUES,
+ .hw_type = rnpgbe_hw_n210L,
+ .init = &rnpgbe_init_n210,
+};
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
new file mode 100644
index 000000000000..8ce0094a88c9
--- /dev/null
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2020 - 2025 Mucse Corporation. */
+
+#ifndef _RNPGBE_HW_H
+#define _RNPGBE_HW_H
+
+#define RNPGBE_RING_BASE 0x1000
+#define RNPGBE_MAC_BASE 0x20000
+#define RNPGBE_ETH_BASE 0x10000
+/**************** MBX Resource ****************************/
+#define N500_FW2PF_MBX_VEC_OFFSET 0x28b00
+#define N500_FWPF_SHM_BASE_OFFSET 0x2d000
+#define GBE_PF2FW_MBX_MASK_OFFSET 0x5500
+#define GBE_FWPF_MBX_MASK 0x5700
+#define N500_RING_MSIX_OFFSET 0x28700
+#define N500_DEFAULT_USECSTOCOUNT 125
+#define N210_FW2PF_MBX_VEC_OFFSET 0x29400
+#define N210_FWPF_SHM_BASE_OFFSET 0x2d900
+#define N210_RING_MSIX_OFFSET 0x29000
+#define N210_DEFAULT_USECSTOCOUNT 62
+/**************** CHIP Resource ****************************/
+#define RNPGBE_MAX_QUEUES 8
+#endif /* _RNPGBE_HW_H */
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
index 2090942ef633..89d8f78af146 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
@@ -4,10 +4,17 @@
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include "rnpgbe.h"
static const char rnpgbe_driver_name[] = "rnpgbe";
+static const struct rnpgbe_info *rnpgbe_info_tbl[] = {
+ [board_n500] = &rnpgbe_n500_info,
+ [board_n210] = &rnpgbe_n210_info,
+ [board_n210L] = &rnpgbe_n210L_info,
+};
/* rnpgbe_pci_tbl - PCI Device ID Table
*
@@ -27,6 +34,61 @@ static struct pci_device_id rnpgbe_pci_tbl[] = {
{0, },
};
+/**
+ * rnpgbe_add_adapter - Add netdev for this pci_dev
+ * @pdev: PCI device information structure
+ * @info: chip info structure
+ *
+ * rnpgbe_add_adapter initializes a netdev for this pci_dev
+ * structure. Initializes Bar map, private structure, and a
+ * hardware reset occur.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+static int rnpgbe_add_adapter(struct pci_dev *pdev,
+ const struct rnpgbe_info *info)
+{
+ struct net_device *netdev;
+ void __iomem *hw_addr;
+ struct mucse *mucse;
+ struct mucse_hw *hw;
+ u32 dma_version;
+ u32 queues;
+ int err;
+
+ queues = info->total_queue_pair_cnts;
+ netdev = alloc_etherdev_mq(sizeof(struct mucse), queues);
+ if (!netdev)
+ return -ENOMEM;
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ mucse = netdev_priv(netdev);
+ mucse->netdev = netdev;
+ mucse->pdev = pdev;
+ pci_set_drvdata(pdev, mucse);
+
+ hw = &mucse->hw;
+ hw->hw_type = info->hw_type;
+ hw->pdev = pdev;
+ hw_addr = devm_ioremap(&pdev->dev,
+ pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+ if (!hw_addr) {
+ err = -EIO;
+ goto err_free_net;
+ }
+
+ dma_version = readl(hw_addr);
+ hw->hw_addr = hw_addr;
+ hw->dma.dma_version = dma_version;
+ info->init(hw);
+ return 0;
+
+err_free_net:
+ free_netdev(netdev);
+ return err;
+}
+
/**
* rnpgbe_probe - Device initialization routine
* @pdev: PCI device information struct
@@ -39,6 +101,7 @@ static struct pci_device_id rnpgbe_pci_tbl[] = {
**/
static int rnpgbe_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
+ const struct rnpgbe_info *info = rnpgbe_info_tbl[id->driver_data];
int err;
err = pci_enable_device_mem(pdev);
@@ -61,13 +124,36 @@ static int rnpgbe_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_master(pdev);
pci_save_state(pdev);
+ err = rnpgbe_add_adapter(pdev, info);
+ if (err)
+ goto err_regions;
return 0;
+err_regions:
+ pci_release_mem_regions(pdev);
err_dma:
pci_disable_device(pdev);
return err;
}
+/**
+ * rnpgbe_rm_adapter - Remove netdev for this mucse structure
+ * @pdev: PCI device information struct
+ *
+ * rnpgbe_rm_adapter remove a netdev for this mucse structure
+ **/
+static void rnpgbe_rm_adapter(struct pci_dev *pdev)
+{
+ struct mucse *mucse = pci_get_drvdata(pdev);
+ struct net_device *netdev;
+
+ if (!mucse)
+ return;
+ netdev = mucse->netdev;
+ mucse->netdev = NULL;
+ free_netdev(netdev);
+}
+
/**
* rnpgbe_remove - Device removal routine
* @pdev: PCI device information struct
@@ -79,6 +165,7 @@ static int rnpgbe_probe(struct pci_dev *pdev, const struct pci_device_id *id)
**/
static void rnpgbe_remove(struct pci_dev *pdev)
{
+ rnpgbe_rm_adapter(pdev);
pci_release_mem_regions(pdev);
pci_disable_device(pdev);
}
@@ -89,6 +176,10 @@ static void rnpgbe_remove(struct pci_dev *pdev)
**/
static void rnpgbe_dev_shutdown(struct pci_dev *pdev)
{
+ struct mucse *mucse = pci_get_drvdata(pdev);
+ struct net_device *netdev = mucse->netdev;
+
+ netif_device_detach(netdev);
pci_disable_device(pdev);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v5 3/5] net: rnpgbe: Add basic mbx ops support
2025-08-18 11:28 [PATCH v5 0/5] Add driver for 1Gbe network chips from MUCSE Dong Yibo
2025-08-18 11:28 ` [PATCH v5 1/5] net: rnpgbe: Add build support for rnpgbe Dong Yibo
2025-08-18 11:28 ` [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support Dong Yibo
@ 2025-08-18 11:28 ` Dong Yibo
2025-08-20 20:23 ` Andrew Lunn
2025-08-18 11:28 ` [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support Dong Yibo
2025-08-18 11:28 ` [PATCH v5 5/5] net: rnpgbe: Add register_netdev Dong Yibo
4 siblings, 1 reply; 29+ messages in thread
From: Dong Yibo @ 2025-08-18 11:28 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran
Cc: netdev, linux-doc, linux-kernel, dong100
Initialize basic mbx function.
Signed-off-by: Dong Yibo <dong100@mucse.com>
---
drivers/net/ethernet/mucse/rnpgbe/Makefile | 3 +-
drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h | 18 +
.../net/ethernet/mucse/rnpgbe/rnpgbe_chip.c | 3 +
drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h | 2 +
.../net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c | 481 ++++++++++++++++++
.../net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h | 31 ++
6 files changed, 537 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h
diff --git a/drivers/net/ethernet/mucse/rnpgbe/Makefile b/drivers/net/ethernet/mucse/rnpgbe/Makefile
index 42c359f459d9..5fc878ada4b1 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/Makefile
+++ b/drivers/net/ethernet/mucse/rnpgbe/Makefile
@@ -6,4 +6,5 @@
obj-$(CONFIG_MGBE) += rnpgbe.o
rnpgbe-objs := rnpgbe_main.o\
- rnpgbe_chip.o
+ rnpgbe_chip.o\
+ rnpgbe_mbx.o
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
index a1553c1efa86..73c2aa5e778b 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
@@ -5,6 +5,7 @@
#define _RNPGBE_H
#include <linux/types.h>
+#include <linux/mutex.h>
extern const struct rnpgbe_info rnpgbe_n500_info;
extern const struct rnpgbe_info rnpgbe_n210_info;
@@ -37,7 +38,24 @@ struct mucse_mac_info {
void __iomem *mac_addr;
};
+struct mucse_mbx_stats {
+ u32 msgs_tx;
+ u32 msgs_rx;
+ u32 acks;
+ u32 reqs;
+ u32 rsts;
+};
+
struct mucse_mbx_info {
+ struct mucse_mbx_stats stats;
+ u32 timeout;
+ u32 usec_delay;
+ u16 size;
+ u16 fw_req;
+ u16 fw_ack;
+ /* lock for only one use mbx */
+ struct mutex lock;
+ bool irq_enabled;
/* fw <--> pf mbx */
u32 fw_pf_shm_base;
u32 pf2fw_mbox_ctrl;
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
index 4db5c910065e..452541c9e1e9 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
@@ -1,8 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2020 - 2025 Mucse Corporation. */
+#include <linux/string.h>
+
#include "rnpgbe.h"
#include "rnpgbe_hw.h"
+#include "rnpgbe_mbx.h"
/**
* rnpgbe_init_common - Setup common attribute
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
index 8ce0094a88c9..cb3eb53b804d 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
@@ -18,6 +18,8 @@
#define N210_FWPF_SHM_BASE_OFFSET 0x2d900
#define N210_RING_MSIX_OFFSET 0x29000
#define N210_DEFAULT_USECSTOCOUNT 62
+/**************** DMA Registers ****************************/
+#define RNPGBE_DMA_DUMY 0x000c
/**************** CHIP Resource ****************************/
#define RNPGBE_MAX_QUEUES 8
#endif /* _RNPGBE_HW_H */
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c
new file mode 100644
index 000000000000..6cd1affd7756
--- /dev/null
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c
@@ -0,0 +1,481 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2022 - 2025 Mucse Corporation. */
+
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+
+#include "rnpgbe.h"
+#include "rnpgbe_mbx.h"
+#include "rnpgbe_hw.h"
+
+/**
+ * mbx_data_rd32 - Reads reg with base mbx->fw_pf_shm_base
+ * @mbx: pointer to the MBX structure
+ * @reg: register offset
+ *
+ * @return: register value
+ **/
+static u32 mbx_data_rd32(struct mucse_mbx_info *mbx, u32 reg)
+{
+ struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx);
+
+ return readl(hw->hw_addr + mbx->fw_pf_shm_base + reg);
+}
+
+/**
+ * mbx_data_wr32 - Writes value to reg with base mbx->fw_pf_shm_base
+ * @mbx: pointer to the MBX structure
+ * @reg: register offset
+ * @value: value to be write
+ *
+ **/
+static void mbx_data_wr32(struct mucse_mbx_info *mbx, u32 reg, u32 value)
+{
+ struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx);
+
+ writel(value, hw->hw_addr + mbx->fw_pf_shm_base + reg);
+}
+
+/**
+ * mbx_ctrl_rd32 - Reads reg with base mbx->fw2pf_mbox_vec
+ * @mbx: pointer to the MBX structure
+ * @reg: register offset
+ *
+ * @return: register value
+ **/
+static u32 mbx_ctrl_rd32(struct mucse_mbx_info *mbx, u32 reg)
+{
+ struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx);
+
+ return readl(hw->hw_addr + mbx->fw2pf_mbox_vec + reg);
+}
+
+/**
+ * mbx_ctrl_wr32 - Writes value to reg with base mbx->fw2pf_mbox_vec
+ * @mbx: pointer to the MBX structure
+ * @reg: register offset
+ * @value: value to be write
+ *
+ **/
+static void mbx_ctrl_wr32(struct mucse_mbx_info *mbx, u32 reg, u32 value)
+{
+ struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx);
+
+ writel(value, hw->hw_addr + mbx->fw2pf_mbox_vec + reg);
+}
+
+/**
+ * mucse_mbx_get_req - Read req from reg
+ * @mbx: pointer to the mbx structure
+ * @reg: register to read
+ *
+ * @return: the req value
+ **/
+static u16 mucse_mbx_get_req(struct mucse_mbx_info *mbx, int reg)
+{
+ return mbx_data_rd32(mbx, reg) & GENMASK(15, 0);
+}
+
+/**
+ * mucse_mbx_get_ack - Read ack from reg
+ * @mbx: pointer to the MBX structure
+ * @reg: register to read
+ *
+ * @return: the ack value
+ **/
+static u16 mucse_mbx_get_ack(struct mucse_mbx_info *mbx, int reg)
+{
+ return (mbx_data_rd32(mbx, reg) >> 16);
+}
+
+/**
+ * mucse_mbx_inc_pf_req - Increase req
+ * @hw: pointer to the HW structure
+ *
+ * mucse_mbx_inc_pf_req read pf_req from hw, then write
+ * new value back after increase
+ **/
+static void mucse_mbx_inc_pf_req(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ u16 req;
+ u32 v;
+
+ v = mbx_data_rd32(mbx, MBX_PF2FW_COUNTER);
+ req = (v & GENMASK(15, 0));
+ req++;
+ v &= GENMASK(31, 16);
+ v |= req;
+ mbx_data_wr32(mbx, MBX_PF2FW_COUNTER, v);
+ hw->mbx.stats.msgs_tx++;
+}
+
+/**
+ * mucse_mbx_inc_pf_ack - Increase ack
+ * @hw: pointer to the HW structure
+ *
+ * mucse_mbx_inc_pf_ack read pf_ack from hw, then write
+ * new value back after increase
+ **/
+static void mucse_mbx_inc_pf_ack(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ u16 ack;
+ u32 v;
+
+ v = mbx_data_rd32(mbx, MBX_PF2FW_COUNTER);
+ ack = (v >> 16) & GENMASK(15, 0);
+ ack++;
+ v &= GENMASK(15, 0);
+ v |= (ack << 16);
+ mbx_data_wr32(mbx, MBX_PF2FW_COUNTER, v);
+ hw->mbx.stats.msgs_rx++;
+}
+
+/**
+ * mucse_check_for_msg_pf - Check to see if the fw has sent mail
+ * @hw: pointer to the HW structure
+ *
+ * @return: 0 if the fw has set the Status bit or else
+ * -EIO
+ **/
+static int mucse_check_for_msg_pf(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ u16 hw_req_count = 0;
+
+ hw_req_count = mucse_mbx_get_req(mbx, MBX_FW2PF_COUNTER);
+ /* chip's register is reset to 0 when rc send reset
+ * mbx command. This causes 'hw_req_count != hw->mbx.fw_req'
+ * be TRUE before fw really reply. Driver must wait fw reset
+ * done reply before using chip, we must check no-zero.
+ **/
+ if (hw_req_count != 0 && hw_req_count != hw->mbx.fw_req) {
+ hw->mbx.stats.reqs++;
+ return 0;
+ }
+
+ return -EIO;
+}
+
+/**
+ * mucse_poll_for_msg - Wait for message notification
+ * @hw: pointer to the HW structure
+ *
+ * @return: 0 on success, negative on failure
+ **/
+static int mucse_poll_for_msg(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+ int val;
+
+ return read_poll_timeout(mucse_check_for_msg_pf,
+ val, val == 0, mbx->usec_delay,
+ countdown * mbx->usec_delay,
+ false, hw);
+}
+
+/**
+ * mucse_check_for_ack_pf - Check to see if the VF has ACKed
+ * @hw: pointer to the HW structure
+ *
+ * @return: 0 if the fw has set the Status bit or else
+ * -EIO
+ **/
+static int mucse_check_for_ack_pf(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ u16 hw_fw_ack;
+
+ hw_fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
+ /* chip's register is reset to 0 when rc send reset
+ * mbx command. This causes 'hw_fw_ack != hw->mbx.fw_ack'
+ * be TRUE before fw really reply. Driver must wait fw reset
+ * done reply before using chip, we must check no-zero.
+ **/
+ if (hw_fw_ack != 0 && hw_fw_ack != hw->mbx.fw_ack) {
+ hw->mbx.stats.acks++;
+ return 0;
+ }
+
+ return -EIO;
+}
+
+/**
+ * mucse_poll_for_ack - Wait for message acknowledgment
+ * @hw: pointer to the HW structure
+ *
+ * @return: 0 if it successfully received a message acknowledgment
+ **/
+static int mucse_poll_for_ack(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+ int val;
+
+ return read_poll_timeout(mucse_check_for_ack_pf,
+ val, val == 0, mbx->usec_delay,
+ countdown * mbx->usec_delay,
+ false, hw);
+}
+
+/**
+ * mucse_obtain_mbx_lock_pf - Obtain mailbox lock
+ * @hw: pointer to the HW structure
+ *
+ * This function maybe used in an irq handler.
+ *
+ * @return: 0 if we obtained the mailbox lock
+ **/
+static int mucse_obtain_mbx_lock_pf(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ int try_cnt = 5000;
+ u32 reg;
+
+ reg = PF2FW_MBOX_CTRL(mbx);
+ while (try_cnt-- > 0) {
+ mbx_ctrl_wr32(mbx, reg, MBOX_PF_HOLD);
+ /* force write back before check */
+ wmb();
+ if (mbx_ctrl_rd32(mbx, reg) & MBOX_PF_HOLD)
+ return 0;
+ udelay(100);
+ }
+ return -EIO;
+}
+
+/**
+ * mucse_read_mbx_pf - Read a message from the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: the message buffer
+ * @size: length of buffer
+ *
+ * This function copies a message from the mailbox buffer to the caller's
+ * memory buffer. The presumption is that the caller knows that there was
+ * a message due to a fw request so no polling for message is needed.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+static int mucse_read_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ int size_inwords = size / 4;
+ u32 ctrl_reg;
+ int ret;
+ int i;
+
+ ctrl_reg = PF2FW_MBOX_CTRL(mbx);
+
+ ret = mucse_obtain_mbx_lock_pf(hw);
+ if (ret)
+ return ret;
+ for (i = 0; i < size_inwords; i++)
+ msg[i] = mbx_data_rd32(mbx, MBX_FW_PF_SHM_DATA + 4 * i);
+ /* Hw need write data_reg at last */
+ mbx_data_wr32(mbx, MBX_FW_PF_SHM_DATA, 0);
+ hw->mbx.fw_req = mucse_mbx_get_req(mbx, MBX_FW2PF_COUNTER);
+ mucse_mbx_inc_pf_ack(hw);
+ mbx_ctrl_wr32(mbx, ctrl_reg, 0);
+
+ return 0;
+}
+
+/**
+ * mucse_read_posted_mbx - Wait for message notification and receive message
+ * @hw: pointer to the HW structure
+ * @msg: the message buffer
+ * @size: length of buffer
+ *
+ * @return: 0 if it successfully received a message notification and
+ * copied it into the receive buffer.
+ **/
+int mucse_read_posted_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
+{
+ int ret;
+
+ ret = mucse_poll_for_msg(hw);
+ if (ret)
+ return ret;
+
+ return mucse_read_mbx_pf(hw, msg, size);
+}
+
+/**
+ * mucse_mbx_reset - Reset mbx info, sync info from regs
+ * @hw: pointer to the HW structure
+ *
+ * This function reset all mbx variables to default.
+ **/
+static void mucse_mbx_reset(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ u32 v;
+
+ v = mbx_data_rd32(mbx, MBX_FW2PF_COUNTER);
+ hw->mbx.fw_req = v & GENMASK(15, 0);
+ hw->mbx.fw_ack = (v >> 16) & GENMASK(15, 0);
+ mbx_ctrl_wr32(mbx, PF2FW_MBOX_CTRL(mbx), 0);
+ mbx_ctrl_wr32(mbx, FW_PF_MBOX_MASK(mbx), GENMASK(31, 16));
+}
+
+/**
+ * mucse_mbx_configure_pf - Configure mbx to use nr_vec interrupt
+ * @hw: pointer to the HW structure
+ * @nr_vec: vector number for mbx
+ * @enable: TRUE for enable, FALSE for disable
+ *
+ * This function configure mbx to use interrupt nr_vec.
+ **/
+void mucse_mbx_configure_pf(struct mucse_hw *hw, int nr_vec,
+ bool enable)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ u32 v;
+
+ if (enable) {
+ v = mbx_data_rd32(mbx, MBX_FW2PF_COUNTER);
+ hw->mbx.fw_req = v & GENMASK(15, 0);
+ hw->mbx.fw_ack = (v >> 16) & GENMASK(15, 0);
+ mbx_ctrl_wr32(mbx, PF2FW_MBOX_CTRL(mbx), 0);
+ mbx_ctrl_wr32(mbx, FW2PF_MBOX_VEC, nr_vec);
+ mbx_ctrl_wr32(mbx, FW_PF_MBOX_MASK(mbx), GENMASK(31, 16));
+ } else {
+ mbx_ctrl_wr32(mbx, FW_PF_MBOX_MASK(mbx), 0xfffffffe);
+ mbx_ctrl_wr32(mbx, PF2FW_MBOX_CTRL(mbx), 0);
+ mbx_ctrl_wr32(mbx, RNPGBE_DMA_DUMY, 0);
+ }
+}
+
+/**
+ * mucse_init_mbx_params_pf - Set initial values for pf mailbox
+ * @hw: pointer to the HW structure
+ *
+ * Initializes the hw->mbx struct to correct values for pf mailbox
+ */
+void mucse_init_mbx_params_pf(struct mucse_hw *hw)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+
+ mbx->usec_delay = 100;
+ mbx->timeout = (4 * USEC_PER_SEC) / mbx->usec_delay;
+ mbx->stats.msgs_tx = 0;
+ mbx->stats.msgs_rx = 0;
+ mbx->stats.reqs = 0;
+ mbx->stats.acks = 0;
+ mbx->stats.rsts = 0;
+ mbx->size = MUCSE_MAILBOX_BYTES;
+ mutex_init(&mbx->lock);
+ mucse_mbx_reset(hw);
+}
+
+/**
+ * mucse_read_mbx - Reads a message from the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: the message buffer
+ * @size: length of buffer
+ *
+ * @return: 0 on success, negative on failure
+ **/
+int mucse_read_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ struct device *dev = &hw->pdev->dev;
+
+ if (size > mbx->size) {
+ dev_err(dev, "mbx read size too large\n");
+ return -EINVAL;
+ }
+ return mucse_read_mbx_pf(hw, msg, size);
+}
+
+/**
+ * mucse_write_mbx_pf - Place a message in the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: the message buffer
+ * @size: length of buffer
+ *
+ * This function maybe used in an irq handler.
+ *
+ * @return: 0 if it successfully copied message into the buffer
+ **/
+int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
+{
+ struct mucse_mbx_info *mbx = &hw->mbx;
+ int size_inwords = size / 4;
+ u32 ctrl_reg;
+ int ret;
+ int i;
+
+ ctrl_reg = PF2FW_MBOX_CTRL(mbx);
+ ret = mucse_obtain_mbx_lock_pf(hw);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < size_inwords; i++)
+ mbx_data_wr32(mbx, MBX_FW_PF_SHM_DATA + i * 4, msg[i]);
+
+ /* flush msg and acks as we are overwriting the message buffer */
+ hw->mbx.fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
+ mucse_mbx_inc_pf_req(hw);
+ mbx_ctrl_wr32(mbx, ctrl_reg, MBOX_CTRL_REQ);
+
+ return 0;
+}
+
+/**
+ * mucse_write_mbx - Write a message to the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: the message buffer
+ * @size: length of buffer
+ *
+ * @return: 0 on success, negative on failure
+ **/
+int mucse_write_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
+{
+ return mucse_write_mbx_pf(hw, msg, size);
+}
+
+/**
+ * mucse_write_posted_mbx - Write a message to the mailbox, wait for ack
+ * @hw: pointer to the HW structure
+ * @msg: the message buffer
+ * @size: length of buffer
+ *
+ * @return: 0 if it successfully copied message into the buffer and
+ * received an ack to that message within delay * timeout period
+ **/
+int mucse_write_posted_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
+{
+ int ret;
+
+ ret = mucse_write_mbx_pf(hw, msg, size);
+ if (ret)
+ return ret;
+ return mucse_poll_for_ack(hw);
+}
+
+/**
+ * mucse_check_for_msg - Check to see if fw sent us mail
+ * @hw: pointer to the HW structure
+ *
+ * @return: 0 on success, negative on failure
+ **/
+int mucse_check_for_msg(struct mucse_hw *hw)
+{
+ return mucse_check_for_msg_pf(hw);
+}
+
+/**
+ * mucse_check_for_ack - Check to see if fw sent us ACK
+ * @hw: pointer to the HW structure
+ *
+ * @return: 0 on success, negative on failure
+ **/
+int mucse_check_for_ack(struct mucse_hw *hw)
+{
+ return mucse_check_for_ack_pf(hw);
+}
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h
new file mode 100644
index 000000000000..8fb3131d4221
--- /dev/null
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2020 - 2025 Mucse Corporation. */
+
+#ifndef _RNPGBE_MBX_H
+#define _RNPGBE_MBX_H
+
+#include "rnpgbe.h"
+
+#define MUCSE_MAILBOX_BYTES 56
+#define MBX_FW2PF_COUNTER 0
+#define MBX_PF2FW_COUNTER 4
+#define MBX_FW_PF_SHM_DATA 8
+#define FW2PF_MBOX_VEC 0
+#define PF2FW_MBOX_CTRL(mbx) ((mbx)->pf2fw_mbox_ctrl)
+#define FW_PF_MBOX_MASK(mbx) ((mbx)->fw_pf_mbox_mask)
+#define MBOX_CTRL_REQ BIT(0)
+#define MBOX_PF_HOLD BIT(3)
+#define MBOX_IRQ_EN 0
+#define MBOX_IRQ_DISABLE 1
+
+int mucse_read_mbx(struct mucse_hw *hw, u32 *msg, u16 size);
+int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size);
+int mucse_write_mbx(struct mucse_hw *hw, u32 *msg, u16 size);
+int mucse_write_posted_mbx(struct mucse_hw *hw, u32 *msg, u16 size);
+int mucse_check_for_msg(struct mucse_hw *hw);
+int mucse_check_for_ack(struct mucse_hw *hw);
+void mucse_init_mbx_params_pf(struct mucse_hw *hw);
+void mucse_mbx_configure_pf(struct mucse_hw *hw, int nr_vec,
+ bool enable);
+int mucse_read_posted_mbx(struct mucse_hw *hw, u32 *msg, u16 size);
+#endif /* _RNPGBE_MBX_H */
--
2.25.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support
2025-08-18 11:28 [PATCH v5 0/5] Add driver for 1Gbe network chips from MUCSE Dong Yibo
` (2 preceding siblings ...)
2025-08-18 11:28 ` [PATCH v5 3/5] net: rnpgbe: Add basic mbx ops support Dong Yibo
@ 2025-08-18 11:28 ` Dong Yibo
2025-08-20 20:30 ` Andrew Lunn
2025-08-20 20:37 ` Andrew Lunn
2025-08-18 11:28 ` [PATCH v5 5/5] net: rnpgbe: Add register_netdev Dong Yibo
4 siblings, 2 replies; 29+ messages in thread
From: Dong Yibo @ 2025-08-18 11:28 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran
Cc: netdev, linux-doc, linux-kernel, dong100
Initialize basic mbx_fw ops, such as get_capability, reset phy
and so on.
Signed-off-by: Dong Yibo <dong100@mucse.com>
---
drivers/net/ethernet/mucse/rnpgbe/Makefile | 3 +-
drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h | 3 +
.../net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c | 333 ++++++++++++++++++
.../net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h | 155 ++++++++
4 files changed, 493 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c
create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h
diff --git a/drivers/net/ethernet/mucse/rnpgbe/Makefile b/drivers/net/ethernet/mucse/rnpgbe/Makefile
index 5fc878ada4b1..de8bcb7772ab 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/Makefile
+++ b/drivers/net/ethernet/mucse/rnpgbe/Makefile
@@ -7,4 +7,5 @@
obj-$(CONFIG_MGBE) += rnpgbe.o
rnpgbe-objs := rnpgbe_main.o\
rnpgbe_chip.o\
- rnpgbe_mbx.o
+ rnpgbe_mbx.o\
+ rnpgbe_mbx_fw.o
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
index 73c2aa5e778b..6a77fcfa0b09 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
@@ -67,7 +67,10 @@ struct mucse_hw {
void __iomem *hw_addr;
void __iomem *ring_msix_base;
struct pci_dev *pdev;
+ u32 fw_version;
+ u32 bd_uid;
enum rnpgbe_hw_type hw_type;
+ u8 pfvfnum;
struct mucse_dma_info dma;
struct mucse_eth_info eth;
struct mucse_mac_info mac;
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c
new file mode 100644
index 000000000000..305b5da717be
--- /dev/null
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2020 - 2025 Mucse Corporation. */
+
+#include <linux/pci.h>
+#include <linux/if_ether.h>
+
+#include "rnpgbe.h"
+#include "rnpgbe_hw.h"
+#include "rnpgbe_mbx.h"
+#include "rnpgbe_mbx_fw.h"
+
+/**
+ * mucse_fw_send_cmd_wait - Send cmd req and wait for response
+ * @hw: pointer to the HW structure
+ * @req: pointer to the cmd req structure
+ * @reply: pointer to the fw reply structure
+ *
+ * mucse_fw_send_cmd_wait sends req to pf-fw mailbox and wait
+ * reply from fw.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+static int mucse_fw_send_cmd_wait(struct mucse_hw *hw,
+ struct mbx_fw_cmd_req *req,
+ struct mbx_fw_cmd_reply *reply)
+{
+ int len = le16_to_cpu(req->datalen);
+ int retry_cnt = 3;
+ int err;
+
+ err = mutex_lock_interruptible(&hw->mbx.lock);
+ if (err)
+ return err;
+ err = mucse_write_posted_mbx(hw, (u32 *)req, len);
+ if (err)
+ goto out;
+ do {
+ err = mucse_read_posted_mbx(hw, (u32 *)reply,
+ sizeof(*reply));
+ if (err)
+ goto out;
+ /* mucse_write_posted_mbx return 0 means fw has
+ * received request, wait for the expect opcode
+ * reply with 'retry_cnt' times.
+ */
+ } while (--retry_cnt >= 0 && reply->opcode != req->opcode);
+out:
+ mutex_unlock(&hw->mbx.lock);
+ if (!err && retry_cnt < 0)
+ return -ETIMEDOUT;
+ if (!err && reply->error_code)
+ return -EIO;
+ return err;
+}
+
+/**
+ * build_phy_abilities_req - build req with get_phy_ability opcode
+ * @req: pointer to the cmd req structure
+ **/
+static void build_phy_abilities_req(struct mbx_fw_cmd_req *req)
+{
+ req->flags = 0;
+ req->opcode = cpu_to_le16(GET_PHY_ABILITY);
+ req->datalen = cpu_to_le16(MBX_REQ_HDR_LEN);
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+}
+
+/**
+ * mucse_fw_get_capability - Get hw abilities from fw
+ * @hw: pointer to the HW structure
+ * @abil: pointer to the hw_abilities structure
+ *
+ * mucse_fw_get_capability tries to get hw abilities from
+ * hw.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+static int mucse_fw_get_capability(struct mucse_hw *hw,
+ struct hw_abilities *abil)
+{
+ struct mbx_fw_cmd_reply reply = {};
+ struct mbx_fw_cmd_req req = {};
+ int err;
+
+ build_phy_abilities_req(&req);
+ err = mucse_fw_send_cmd_wait(hw, &req, &reply);
+ if (!err)
+ memcpy(abil, &reply.hw_abilities, sizeof(*abil));
+ return err;
+}
+
+/**
+ * mucse_mbx_get_capability - Get hw abilities from fw
+ * @hw: pointer to the HW structure
+ *
+ * mucse_mbx_get_capability tries to get capabities from
+ * hw. Many retrys will do if it is failed.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+int mucse_mbx_get_capability(struct mucse_hw *hw)
+{
+ struct hw_abilities ability = {};
+ int try_cnt = 3;
+ int err = -EIO;
+
+ while (try_cnt--) {
+ err = mucse_fw_get_capability(hw, &ability);
+ if (err)
+ continue;
+ hw->pfvfnum = le16_to_cpu(ability.pfnum);
+ hw->fw_version = le32_to_cpu(ability.fw_version);
+ hw->usecstocount = le32_to_cpu(ability.axi_mhz);
+ hw->bd_uid = le32_to_cpu(ability.bd_uid);
+ return 0;
+ }
+ return err;
+}
+
+/**
+ * mbx_cookie_zalloc - Alloc a cookie structure
+ * @priv_len: private length for this cookie
+ *
+ * @return: cookie structure on success
+ **/
+static struct mbx_req_cookie *mbx_cookie_zalloc(int priv_len)
+{
+ struct mbx_req_cookie *cookie;
+
+ cookie = kzalloc(struct_size(cookie, priv, priv_len), GFP_KERNEL);
+ if (cookie) {
+ cookie->timeout_jiffies = 30 * HZ;
+ cookie->magic = COOKIE_MAGIC;
+ cookie->priv_len = priv_len;
+ }
+ return cookie;
+}
+
+/**
+ * mucse_mbx_fw_post_req - Posts a mbx req to firmware and wait reply
+ * @hw: pointer to the HW structure
+ * @req: pointer to the cmd req structure
+ * @cookie: pointer to the req cookie
+ *
+ * mucse_mbx_fw_post_req posts a mbx req to firmware and wait for the
+ * reply. cookie->wait will be set in irq handler.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+static int mucse_mbx_fw_post_req(struct mucse_hw *hw,
+ struct mbx_fw_cmd_req *req,
+ struct mbx_req_cookie *cookie)
+{
+ int len = le16_to_cpu(req->datalen);
+ int err;
+
+ cookie->errcode = 0;
+ cookie->done = 0;
+ init_waitqueue_head(&cookie->wait);
+ err = mutex_lock_interruptible(&hw->mbx.lock);
+ if (err)
+ return err;
+ err = mucse_write_mbx(hw, (u32 *)req, len);
+ if (err)
+ goto out;
+ err = wait_event_timeout(cookie->wait,
+ cookie->done == 1,
+ cookie->timeout_jiffies);
+
+ if (!err)
+ err = -ETIMEDOUT;
+ else
+ err = 0;
+ if (!err && cookie->errcode)
+ err = cookie->errcode;
+out:
+ mutex_unlock(&hw->mbx.lock);
+ return err;
+}
+
+/**
+ * build_ifinsmod - build req with insmod opcode
+ * @req: pointer to the cmd req structure
+ * @status: true for insmod, false for rmmod
+ **/
+static void build_ifinsmod(struct mbx_fw_cmd_req *req,
+ int status)
+{
+ req->flags = 0;
+ req->opcode = cpu_to_le16(DRIVER_INSMOD);
+ req->datalen = cpu_to_le16(sizeof(req->ifinsmod) +
+ MBX_REQ_HDR_LEN);
+ req->cookie = NULL;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+#define FIXED_VERSION 0xFFFFFFFF
+ req->ifinsmod.version = cpu_to_le32(FIXED_VERSION);
+ req->ifinsmod.status = cpu_to_le32(status);
+}
+
+/**
+ * mucse_mbx_ifinsmod - Echo driver insmod status to hw
+ * @hw: pointer to the HW structure
+ * @status: true for insmod, false for rmmod
+ *
+ * @return: 0 on success, negative on failure
+ **/
+int mucse_mbx_ifinsmod(struct mucse_hw *hw, int status)
+{
+ struct mbx_fw_cmd_req req = {};
+ int len;
+ int err;
+
+ build_ifinsmod(&req, status);
+ len = le16_to_cpu(req.datalen);
+ err = mutex_lock_interruptible(&hw->mbx.lock);
+ if (err)
+ return err;
+
+ if (status) {
+ err = mucse_write_posted_mbx(hw, (u32 *)&req,
+ len);
+ } else {
+ err = mucse_write_mbx_pf(hw, (u32 *)&req,
+ len);
+ }
+
+ mutex_unlock(&hw->mbx.lock);
+ return err;
+}
+
+/**
+ * build_reset_phy_req - build req with reset_phy opcode
+ * @req: pointer to the cmd req structure
+ * @cookie: pointer of cookie for this cmd
+ **/
+static void build_reset_phy_req(struct mbx_fw_cmd_req *req,
+ void *cookie)
+{
+ req->flags = 0;
+ req->opcode = cpu_to_le16(RESET_PHY);
+ req->datalen = cpu_to_le16(MBX_REQ_HDR_LEN);
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+ req->cookie = cookie;
+}
+
+/**
+ * mucse_mbx_fw_reset_phy - Posts a mbx req to reset hw
+ * @hw: pointer to the HW structure
+ *
+ * mucse_mbx_fw_reset_phy posts a mbx req to firmware to reset hw.
+ * It uses mucse_fw_send_cmd_wait if no irq, and mucse_mbx_fw_post_req
+ * if other irq is registered.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+int mucse_mbx_fw_reset_phy(struct mucse_hw *hw)
+{
+ struct mbx_fw_cmd_reply reply = {};
+ struct mbx_fw_cmd_req req = {};
+ int ret;
+
+ if (hw->mbx.irq_enabled) {
+ struct mbx_req_cookie *cookie = mbx_cookie_zalloc(0);
+
+ if (!cookie)
+ return -ENOMEM;
+
+ build_reset_phy_req(&req, cookie);
+ ret = mucse_mbx_fw_post_req(hw, &req, cookie);
+ kfree(cookie);
+ return ret;
+ }
+
+ build_reset_phy_req(&req, &req);
+ return mucse_fw_send_cmd_wait(hw, &req, &reply);
+}
+
+/**
+ * build_get_macaddress_req - build req with get_mac opcode
+ * @req: pointer to the cmd req structure
+ * @port_mask: port valid for this cmd
+ * @pfvfnum: pfvfnum for this cmd
+ * @cookie: pointer of cookie for this cmd
+ **/
+static void build_get_macaddress_req(struct mbx_fw_cmd_req *req,
+ int port_mask, int pfvfnum,
+ void *cookie)
+{
+ req->flags = 0;
+ req->opcode = cpu_to_le16(GET_MAC_ADDRES);
+ req->datalen = cpu_to_le16(sizeof(req->get_mac_addr) +
+ MBX_REQ_HDR_LEN);
+ req->cookie = cookie;
+ req->reply_lo = 0;
+ req->reply_hi = 0;
+ req->get_mac_addr.port_mask = cpu_to_le32(port_mask);
+ req->get_mac_addr.pfvf_num = cpu_to_le32(pfvfnum);
+}
+
+/**
+ * mucse_fw_get_macaddr - Posts a mbx req to request macaddr
+ * @hw: pointer to the HW structure
+ * @pfvfnum: index of pf/vf num
+ * @mac_addr: pointer to store mac_addr
+ * @port: port index
+ *
+ * mucse_fw_get_macaddr posts a mbx req to firmware to get mac_addr.
+ * It uses mucse_fw_send_cmd_wait if no irq, and mucse_mbx_fw_post_req
+ * if other irq is registered.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+int mucse_fw_get_macaddr(struct mucse_hw *hw, int pfvfnum,
+ u8 *mac_addr,
+ int port)
+{
+ struct mbx_fw_cmd_reply reply = {};
+ struct mbx_fw_cmd_req req = {};
+ int err;
+
+ build_get_macaddress_req(&req, BIT(port), pfvfnum, &req);
+ err = mucse_fw_send_cmd_wait(hw, &req, &reply);
+ if (err)
+ return err;
+ if (le32_to_cpu(reply.mac_addr.ports) & BIT(port))
+ memcpy(mac_addr, reply.mac_addr.addrs[port].mac, ETH_ALEN);
+ else
+ return -ENODATA;
+ return 0;
+}
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h
new file mode 100644
index 000000000000..e826ef5570ee
--- /dev/null
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2020 - 2025 Mucse Corporation. */
+
+#ifndef _RNPGBE_MBX_FW_H
+#define _RNPGBE_MBX_FW_H
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+
+#include "rnpgbe.h"
+
+#define MBX_REQ_HDR_LEN 24
+#define M_DEFAULT_DUMY 0xa0000000
+#define M_DUMY_MASK 0x0f000f11
+#define EVT_LINK_UP 1
+
+struct mbx_fw_cmd_reply;
+typedef void (*cookie_cb)(struct mbx_fw_cmd_reply *reply, void *priv);
+
+struct mbx_req_cookie {
+ int magic;
+#define COOKIE_MAGIC 0xCE
+ cookie_cb cb;
+ int timeout_jiffies;
+ int errcode;
+ wait_queue_head_t wait;
+ int done;
+ int priv_len;
+ char priv[] __counted_by(priv_len);
+};
+
+enum MUCSE_FW_CMD {
+ GET_PHY_ABILITY = 0x0601,
+ GET_MAC_ADDRES = 0x0602,
+ RESET_PHY = 0x0603,
+ DRIVER_INSMOD = 0x0803,
+};
+
+struct hw_abilities {
+ u8 link_stat;
+ u8 port_mask;
+ __le32 speed;
+ __le16 phy_type;
+ __le16 nic_mode;
+ __le16 pfnum;
+ __le32 fw_version;
+ __le32 axi_mhz;
+ union {
+ u8 port_id[4];
+ __le32 port_ids;
+ };
+ __le32 bd_uid;
+ __le32 phy_id;
+ __le32 wol_status;
+ union {
+ __le32 ext_ability;
+ struct {
+ u32 valid : 1;
+ u32 wol_en : 1;
+ u32 pci_preset_runtime_en : 1;
+ u32 smbus_en : 1;
+ u32 ncsi_en : 1;
+ u32 rpu_en : 1;
+ u32 v2 : 1;
+ u32 pxe_en : 1;
+ u32 mctp_en : 1;
+ u32 yt8614 : 1;
+ u32 pci_ext_reset : 1;
+ u32 rpu_availble : 1;
+ u32 fw_lldp_ability : 1;
+ u32 lldp_enabled : 1;
+ u32 only_1g : 1;
+ u32 force_down_en: 1;
+ } e_host;
+ };
+} __packed;
+
+/* FW stores extended ability information in 'ext_ability' as a 32-bit
+ * little-endian value. To make these flags easily accessible in the
+ * kernel (via named 'bitfields' instead of raw bitmask operations),
+ * we use the union's 'e_host' struct, which provides named bits
+ * (e.g., 'wol_en', 'smbus_en')
+ */
+static inline void ability_update_host_endian(struct hw_abilities *abi)
+{
+ u32 host_val = le32_to_cpu(abi->ext_ability);
+
+ abi->e_host = *(typeof(abi->e_host) *)&host_val;
+}
+
+#define FLAGS_DD BIT(0)
+#define FLAGS_ERR BIT(2)
+
+struct mbx_fw_cmd_req {
+ __le16 flags;
+ __le16 opcode;
+ __le16 datalen;
+ __le16 ret_value;
+ union {
+ struct {
+ __le32 cookie_lo;
+ __le32 cookie_hi;
+ };
+
+ void *cookie;
+ };
+ __le32 reply_lo;
+ __le32 reply_hi;
+ union {
+ u8 data[32];
+ struct {
+ __le32 version;
+ __le32 status;
+ } ifinsmod;
+ struct {
+ __le32 port_mask;
+ __le32 pfvf_num;
+ } get_mac_addr;
+ };
+} __packed;
+
+struct mbx_fw_cmd_reply {
+ __le16 flags;
+ __le16 opcode;
+ __le16 error_code;
+ __le16 datalen;
+ union {
+ struct {
+ __le32 cookie_lo;
+ __le32 cookie_hi;
+ };
+ void *cookie;
+ };
+ union {
+ u8 data[40];
+ struct mac_addr {
+ __le32 ports;
+ struct _addr {
+ /* for macaddr:01:02:03:04:05:06
+ * mac-hi=0x01020304 mac-lo=0x05060000
+ */
+ u8 mac[8];
+ } addrs[4];
+ } mac_addr;
+ struct hw_abilities hw_abilities;
+ };
+} __packed;
+
+int mucse_mbx_get_capability(struct mucse_hw *hw);
+int mucse_mbx_ifinsmod(struct mucse_hw *hw, int status);
+int mucse_mbx_fw_reset_phy(struct mucse_hw *hw);
+int mucse_fw_get_macaddr(struct mucse_hw *hw, int pfvfnum,
+ u8 *mac_addr, int port);
+#endif /* _RNPGBE_MBX_FW_H */
--
2.25.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v5 5/5] net: rnpgbe: Add register_netdev
2025-08-18 11:28 [PATCH v5 0/5] Add driver for 1Gbe network chips from MUCSE Dong Yibo
` (3 preceding siblings ...)
2025-08-18 11:28 ` [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support Dong Yibo
@ 2025-08-18 11:28 ` Dong Yibo
2025-08-20 20:42 ` Andrew Lunn
4 siblings, 1 reply; 29+ messages in thread
From: Dong Yibo @ 2025-08-18 11:28 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran
Cc: netdev, linux-doc, linux-kernel, dong100
Initialize get mac from hw, register the netdev.
Signed-off-by: Dong Yibo <dong100@mucse.com>
---
drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h | 18 +++++
.../net/ethernet/mucse/rnpgbe/rnpgbe_chip.c | 72 ++++++++++++++++++
drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h | 1 +
.../net/ethernet/mucse/rnpgbe/rnpgbe_main.c | 75 +++++++++++++++++++
4 files changed, 166 insertions(+)
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
index 6a77fcfa0b09..1630885366cf 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h
@@ -6,6 +6,7 @@
#include <linux/types.h>
#include <linux/mutex.h>
+#include <linux/netdevice.h>
extern const struct rnpgbe_info rnpgbe_n500_info;
extern const struct rnpgbe_info rnpgbe_n210_info;
@@ -63,6 +64,17 @@ struct mucse_mbx_info {
u32 fw2pf_mbox_vec;
};
+struct mucse_hw;
+
+struct mucse_hw_operations {
+ int (*reset_hw)(struct mucse_hw *hw);
+ void (*driver_status)(struct mucse_hw *hw, bool enable, int mode);
+};
+
+enum {
+ mucse_driver_insmod,
+};
+
struct mucse_hw {
void __iomem *hw_addr;
void __iomem *ring_msix_base;
@@ -71,11 +83,15 @@ struct mucse_hw {
u32 bd_uid;
enum rnpgbe_hw_type hw_type;
u8 pfvfnum;
+ const struct mucse_hw_operations *ops;
struct mucse_dma_info dma;
struct mucse_eth_info eth;
struct mucse_mac_info mac;
struct mucse_mbx_info mbx;
+ u32 flags;
u32 usecstocount;
+ int port;
+ u8 perm_addr[ETH_ALEN];
};
struct mucse {
@@ -96,4 +112,6 @@ struct rnpgbe_info {
#define PCI_DEVICE_ID_N500_DUAL_PORT 0x8318
#define PCI_DEVICE_ID_N210 0x8208
#define PCI_DEVICE_ID_N210L 0x820a
+
+#define rnpgbe_dma_wr32(dma, reg, val) writel((val), (dma)->dma_base_addr + (reg))
#endif /* _RNPGBE_H */
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
index 452541c9e1e9..d3da4ad760a4 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_chip.c
@@ -1,11 +1,81 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2020 - 2025 Mucse Corporation. */
+#include <linux/pci.h>
#include <linux/string.h>
+#include <linux/etherdevice.h>
#include "rnpgbe.h"
#include "rnpgbe_hw.h"
#include "rnpgbe_mbx.h"
+#include "rnpgbe_mbx_fw.h"
+
+/**
+ * rnpgbe_get_permanent_mac - Get permanent mac
+ * @hw: hw information structure
+ * @mac_addr: pointer to store mac
+ *
+ * rnpgbe_get_permanent_mac tries to get mac from hw.
+ * It use eth_random_addr if failed.
+ *
+ * @return: 0 or -EINVAL
+ **/
+static int rnpgbe_get_permanent_mac(struct mucse_hw *hw,
+ u8 *mac_addr)
+{
+ struct device *dev = &hw->pdev->dev;
+
+ if (mucse_fw_get_macaddr(hw, hw->pfvfnum, mac_addr, hw->port) ||
+ !is_valid_ether_addr(mac_addr)) {
+ dev_err(dev, "Failed to get valid MAC from FW\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * rnpgbe_reset_hw_ops - Do a hardware reset
+ * @hw: hw information structure
+ *
+ * rnpgbe_reset_hw_ops calls fw to do a hardware
+ * reset, and cleans some regs to default.
+ *
+ * @return: 0 on success, negative on failure
+ **/
+static int rnpgbe_reset_hw_ops(struct mucse_hw *hw)
+{
+ struct mucse_dma_info *dma = &hw->dma;
+ int err;
+
+ rnpgbe_dma_wr32(dma, RNPGBE_DMA_AXI_EN, 0);
+ err = mucse_mbx_fw_reset_phy(hw);
+ if (err)
+ return err;
+ return rnpgbe_get_permanent_mac(hw, hw->perm_addr);
+}
+
+/**
+ * rnpgbe_driver_status_hw_ops - Echo driver status to hw
+ * @hw: hw information structure
+ * @enable: true or false status
+ * @mode: status mode
+ **/
+static void rnpgbe_driver_status_hw_ops(struct mucse_hw *hw,
+ bool enable,
+ int mode)
+{
+ switch (mode) {
+ case mucse_driver_insmod:
+ mucse_mbx_ifinsmod(hw, enable);
+ break;
+ }
+}
+
+static const struct mucse_hw_operations rnpgbe_hw_ops = {
+ .reset_hw = &rnpgbe_reset_hw_ops,
+ .driver_status = &rnpgbe_driver_status_hw_ops,
+};
/**
* rnpgbe_init_common - Setup common attribute
@@ -27,6 +97,8 @@ static void rnpgbe_init_common(struct mucse_hw *hw)
mbx->pf2fw_mbox_ctrl = GBE_PF2FW_MBX_MASK_OFFSET;
mbx->fw_pf_mbox_mask = GBE_FWPF_MBX_MASK;
+
+ hw->ops = &rnpgbe_hw_ops;
}
/**
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
index cb3eb53b804d..42acc96e5b26 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_hw.h
@@ -20,6 +20,7 @@
#define N210_DEFAULT_USECSTOCOUNT 62
/**************** DMA Registers ****************************/
#define RNPGBE_DMA_DUMY 0x000c
+#define RNPGBE_DMA_AXI_EN 0x0010
/**************** CHIP Resource ****************************/
#define RNPGBE_MAX_QUEUES 8
#endif /* _RNPGBE_HW_H */
diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
index 89d8f78af146..4d75f73b012b 100644
--- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
+++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
@@ -8,6 +8,8 @@
#include <linux/etherdevice.h>
#include "rnpgbe.h"
+#include "rnpgbe_mbx.h"
+#include "rnpgbe_mbx_fw.h"
static const char rnpgbe_driver_name[] = "rnpgbe";
static const struct rnpgbe_info *rnpgbe_info_tbl[] = {
@@ -34,6 +36,55 @@ static struct pci_device_id rnpgbe_pci_tbl[] = {
{0, },
};
+/**
+ * rnpgbe_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP).
+ *
+ * @return: 0 on success, negative value on failure
+ **/
+static int rnpgbe_open(struct net_device *netdev)
+{
+ return 0;
+}
+
+/**
+ * rnpgbe_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS.
+ *
+ * @return: 0, this is not allowed to fail
+ **/
+static int rnpgbe_close(struct net_device *netdev)
+{
+ return 0;
+}
+
+/**
+ * rnpgbe_xmit_frame - Send a skb to driver
+ * @skb: skb structure to be sent
+ * @netdev: network interface device structure
+ *
+ * @return: NETDEV_TX_OK or NETDEV_TX_BUSY
+ **/
+static netdev_tx_t rnpgbe_xmit_frame(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ dev_kfree_skb_any(skb);
+ netdev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops rnpgbe_netdev_ops = {
+ .ndo_open = rnpgbe_open,
+ .ndo_stop = rnpgbe_close,
+ .ndo_start_xmit = rnpgbe_xmit_frame,
+};
+
/**
* rnpgbe_add_adapter - Add netdev for this pci_dev
* @pdev: PCI device information structure
@@ -82,6 +133,27 @@ static int rnpgbe_add_adapter(struct pci_dev *pdev,
hw->hw_addr = hw_addr;
hw->dma.dma_version = dma_version;
info->init(hw);
+ mucse_init_mbx_params_pf(hw);
+ /* echo fw driver insmod to control hw */
+ hw->ops->driver_status(hw, true, mucse_driver_insmod);
+ err = mucse_mbx_get_capability(hw);
+ if (err) {
+ dev_err(&pdev->dev,
+ "mucse_mbx_get_capability failed! %d\n",
+ err);
+ goto err_free_net;
+ }
+ netdev->netdev_ops = &rnpgbe_netdev_ops;
+ netdev->watchdog_timeo = 5 * HZ;
+ err = hw->ops->reset_hw(hw);
+ if (err) {
+ dev_err(&pdev->dev, "Hw reset failed %d\n", err);
+ goto err_free_net;
+ }
+ eth_hw_addr_set(netdev, hw->perm_addr);
+ err = register_netdev(netdev);
+ if (err)
+ goto err_free_net;
return 0;
err_free_net:
@@ -145,12 +217,15 @@ static int rnpgbe_probe(struct pci_dev *pdev, const struct pci_device_id *id)
static void rnpgbe_rm_adapter(struct pci_dev *pdev)
{
struct mucse *mucse = pci_get_drvdata(pdev);
+ struct mucse_hw *hw = &mucse->hw;
struct net_device *netdev;
if (!mucse)
return;
netdev = mucse->netdev;
+ unregister_netdev(netdev);
mucse->netdev = NULL;
+ hw->ops->driver_status(hw, false, mucse_driver_insmod);
free_netdev(netdev);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support
2025-08-18 11:28 ` [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support Dong Yibo
@ 2025-08-19 13:59 ` Vadim Fedorenko
2025-08-20 1:43 ` Yibo Dong
2025-08-20 20:16 ` Andrew Lunn
1 sibling, 1 reply; 29+ messages in thread
From: Vadim Fedorenko @ 2025-08-19 13:59 UTC (permalink / raw)
To: Dong Yibo, andrew+netdev, davem, edumazet, kuba, pabeni, horms,
corbet, gur.stavi, maddy, mpe, danishanwar, lee, gongfan1,
lorenzo, geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran
Cc: netdev, linux-kernel, linux-doc
On 18/08/2025 12:28, Dong Yibo wrote:
> Initialize n500/n210 chip bar resource map and
> dma, eth, mbx ... info for future use.
>
[...]
> +struct mucse_hw {
> + void __iomem *hw_addr;
> + void __iomem *ring_msix_base;
> + struct pci_dev *pdev;
> + enum rnpgbe_hw_type hw_type;
> + struct mucse_dma_info dma;
> + struct mucse_eth_info eth;
> + struct mucse_mac_info mac;
> + struct mucse_mbx_info mbx;
> + u32 usecstocount;
What is this field for? You don't use it anywhere in the patchset apart
from initialization. Maybe it's better to introduce it once it's used?
Together with the defines of values for this field...
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support
2025-08-19 13:59 ` Vadim Fedorenko
@ 2025-08-20 1:43 ` Yibo Dong
2025-08-20 20:10 ` Andrew Lunn
0 siblings, 1 reply; 29+ messages in thread
From: Yibo Dong @ 2025-08-20 1:43 UTC (permalink / raw)
To: Vadim Fedorenko
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-kernel, linux-doc
On Tue, Aug 19, 2025 at 02:59:09PM +0100, Vadim Fedorenko wrote:
> On 18/08/2025 12:28, Dong Yibo wrote:
> > Initialize n500/n210 chip bar resource map and
> > dma, eth, mbx ... info for future use.
> >
> [...]
>
> > +struct mucse_hw {
> > + void __iomem *hw_addr;
> > + void __iomem *ring_msix_base;
> > + struct pci_dev *pdev;
> > + enum rnpgbe_hw_type hw_type;
> > + struct mucse_dma_info dma;
> > + struct mucse_eth_info eth;
> > + struct mucse_mac_info mac;
> > + struct mucse_mbx_info mbx;
> > + u32 usecstocount;
>
> What is this field for? You don't use it anywhere in the patchset apart
> from initialization. Maybe it's better to introduce it once it's used?
> Together with the defines of values for this field...
>
It is used to store chip frequency which is used to calculate values
related to 'delay register' in the future. I will improve this.
Thanks for your feedback.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 1/5] net: rnpgbe: Add build support for rnpgbe
2025-08-18 11:28 ` [PATCH v5 1/5] net: rnpgbe: Add build support for rnpgbe Dong Yibo
@ 2025-08-20 20:06 ` Andrew Lunn
2025-08-21 1:29 ` Yibo Dong
0 siblings, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-20 20:06 UTC (permalink / raw)
To: Dong Yibo
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
> +/**
> + * rnpgbe_init_module - Driver init routine
> + *
> + * rnpgbe_init_module is called when driver insmod
> + *
> + * @return: 0 on success, negative on failure
> + **/
> +static int __init rnpgbe_init_module(void)
> +{
> + return pci_register_driver(&rnpgbe_driver);
> +}
> +
> +module_init(rnpgbe_init_module);
> +
> +/**
> + * rnpgbe_exit_module - Driver remove routine
> + *
> + * rnpgbe_exit_module is called when driver is removed
> + **/
> +static void __exit rnpgbe_exit_module(void)
> +{
> + pci_unregister_driver(&rnpgbe_driver);
> +}
> +
> +module_exit(rnpgbe_exit_module);
This can be replaced by module_pci_driver()
Andrew
---
pw-bot: cr
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support
2025-08-20 1:43 ` Yibo Dong
@ 2025-08-20 20:10 ` Andrew Lunn
2025-08-21 1:53 ` Yibo Dong
0 siblings, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-20 20:10 UTC (permalink / raw)
To: Yibo Dong
Cc: Vadim Fedorenko, andrew+netdev, davem, edumazet, kuba, pabeni,
horms, corbet, gur.stavi, maddy, mpe, danishanwar, lee, gongfan1,
lorenzo, geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-kernel, linux-doc
On Wed, Aug 20, 2025 at 09:43:41AM +0800, Yibo Dong wrote:
> On Tue, Aug 19, 2025 at 02:59:09PM +0100, Vadim Fedorenko wrote:
> > On 18/08/2025 12:28, Dong Yibo wrote:
> > > Initialize n500/n210 chip bar resource map and
> > > dma, eth, mbx ... info for future use.
> > >
> > [...]
> >
> > > +struct mucse_hw {
> > > + void __iomem *hw_addr;
> > > + void __iomem *ring_msix_base;
> > > + struct pci_dev *pdev;
> > > + enum rnpgbe_hw_type hw_type;
> > > + struct mucse_dma_info dma;
> > > + struct mucse_eth_info eth;
> > > + struct mucse_mac_info mac;
> > > + struct mucse_mbx_info mbx;
> > > + u32 usecstocount;
> >
> > What is this field for? You don't use it anywhere in the patchset apart
> > from initialization. Maybe it's better to introduce it once it's used?
> > Together with the defines of values for this field...
> >
>
> It is used to store chip frequency which is used to calculate values
> related to 'delay register' in the future. I will improve this.
Maybe also see if you can find a better name. count is rather
vague. Count of what?
Andrew
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support
2025-08-18 11:28 ` [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support Dong Yibo
2025-08-19 13:59 ` Vadim Fedorenko
@ 2025-08-20 20:16 ` Andrew Lunn
2025-08-21 1:54 ` Yibo Dong
1 sibling, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-20 20:16 UTC (permalink / raw)
To: Dong Yibo
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
> +const struct rnpgbe_info rnpgbe_n500_info = {
> + .total_queue_pair_cnts = RNPGBE_MAX_QUEUES,
> + .hw_type = rnpgbe_hw_n500,
> + .init = &rnpgbe_init_n500,
> +};
> +
> +const struct rnpgbe_info rnpgbe_n210_info = {
> + .total_queue_pair_cnts = RNPGBE_MAX_QUEUES,
> + .hw_type = rnpgbe_hw_n210,
> + .init = &rnpgbe_init_n210,
> +};
> +
> +const struct rnpgbe_info rnpgbe_n210L_info = {
> + .total_queue_pair_cnts = RNPGBE_MAX_QUEUES,
> + .hw_type = rnpgbe_hw_n210L,
> + .init = &rnpgbe_init_n210,
> +};
total_queue_pair_cnts is the same for all three. So it probably does
not need to be in the structure. You can just use RNPGBE_MAX_QUEUES.
Andrew
---
pw-bot: cr
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 3/5] net: rnpgbe: Add basic mbx ops support
2025-08-18 11:28 ` [PATCH v5 3/5] net: rnpgbe: Add basic mbx ops support Dong Yibo
@ 2025-08-20 20:23 ` Andrew Lunn
2025-08-21 1:44 ` Yibo Dong
0 siblings, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-20 20:23 UTC (permalink / raw)
To: Dong Yibo
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
> +/**
> + * mucse_mbx_get_ack - Read ack from reg
> + * @mbx: pointer to the MBX structure
> + * @reg: register to read
> + *
> + * @return: the ack value
> + **/
> +static u16 mucse_mbx_get_ack(struct mucse_mbx_info *mbx, int reg)
> +{
> + return (mbx_data_rd32(mbx, reg) >> 16);
> +}
> +static int mucse_check_for_ack_pf(struct mucse_hw *hw)
> +{
> + struct mucse_mbx_info *mbx = &hw->mbx;
> + u16 hw_fw_ack;
> +
> + hw_fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
> +int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
> +{
> + struct mucse_mbx_info *mbx = &hw->mbx;
> + int size_inwords = size / 4;
> + u32 ctrl_reg;
> + int ret;
> + int i;
> +
> + ctrl_reg = PF2FW_MBOX_CTRL(mbx);
> + ret = mucse_obtain_mbx_lock_pf(hw);
> + if (ret)
> + return ret;
> +
> + for (i = 0; i < size_inwords; i++)
> + mbx_data_wr32(mbx, MBX_FW_PF_SHM_DATA + i * 4, msg[i]);
> +
> + /* flush msg and acks as we are overwriting the message buffer */
> + hw->mbx.fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
It seems like the ACK is always at MBX_FW2PF_COUNTER. So why pass it
to mucse_mbx_get_ack()? Please look at your other getters and setters.
> +/**
> + * mucse_write_mbx - Write a message to the mailbox
> + * @hw: pointer to the HW structure
> + * @msg: the message buffer
> + * @size: length of buffer
> + *
> + * @return: 0 on success, negative on failure
> + **/
> +int mucse_write_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
> +{
> + return mucse_write_mbx_pf(hw, msg, size);
> +}
This function does not do anything useful. Why not call
mucse_write_mbx_pf() directly?
> +/**
> + * mucse_check_for_msg - Check to see if fw sent us mail
> + * @hw: pointer to the HW structure
> + *
> + * @return: 0 on success, negative on failure
> + **/
> +int mucse_check_for_msg(struct mucse_hw *hw)
> +{
> + return mucse_check_for_msg_pf(hw);
> +}
> +
> +/**
> + * mucse_check_for_ack - Check to see if fw sent us ACK
> + * @hw: pointer to the HW structure
> + *
> + * @return: 0 on success, negative on failure
> + **/
> +int mucse_check_for_ack(struct mucse_hw *hw)
> +{
> + return mucse_check_for_ack_pf(hw);
> +}
These as well.
Andrew
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support
2025-08-18 11:28 ` [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support Dong Yibo
@ 2025-08-20 20:30 ` Andrew Lunn
2025-08-21 2:04 ` Yibo Dong
2025-08-20 20:37 ` Andrew Lunn
1 sibling, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-20 20:30 UTC (permalink / raw)
To: Dong Yibo
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
> +int mucse_mbx_get_capability(struct mucse_hw *hw)
> +{
> + struct hw_abilities ability = {};
> + int try_cnt = 3;
> + int err = -EIO;
> +
> + while (try_cnt--) {
> + err = mucse_fw_get_capability(hw, &ability);
> + if (err)
> + continue;
> + hw->pfvfnum = le16_to_cpu(ability.pfnum);
> + hw->fw_version = le32_to_cpu(ability.fw_version);
> + hw->usecstocount = le32_to_cpu(ability.axi_mhz);
If you can get it from the hardware, why do you need to initialise it
in the earlier patch?
I guess you have a bootstrap problem, you need it to get it. But
cannot you just initialise it to a single pessimistic value which will
work well enough for all hardware variants until you can actually ask
the hardware?
Andrew
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support
2025-08-18 11:28 ` [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support Dong Yibo
2025-08-20 20:30 ` Andrew Lunn
@ 2025-08-20 20:37 ` Andrew Lunn
2025-08-21 2:49 ` Yibo Dong
1 sibling, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-20 20:37 UTC (permalink / raw)
To: Dong Yibo
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
> +static int mucse_mbx_fw_post_req(struct mucse_hw *hw,
> + struct mbx_fw_cmd_req *req,
> + struct mbx_req_cookie *cookie)
> +{
> + int len = le16_to_cpu(req->datalen);
> + int err;
> +
> + cookie->errcode = 0;
> + cookie->done = 0;
> + init_waitqueue_head(&cookie->wait);
> + err = mutex_lock_interruptible(&hw->mbx.lock);
> + if (err)
> + return err;
> + err = mucse_write_mbx(hw, (u32 *)req, len);
> + if (err)
> + goto out;
> + err = wait_event_timeout(cookie->wait,
> + cookie->done == 1,
> + cookie->timeout_jiffies);
> +
> + if (!err)
> + err = -ETIMEDOUT;
> + else
> + err = 0;
> + if (!err && cookie->errcode)
> + err = cookie->errcode;
> +out:
> + mutex_unlock(&hw->mbx.lock);
> + return err;
What is your design with respect to mutex_lock_interruptible() and
then calling wait_event_timeout() which will ignore signals?
Is your intention that you can always ^C the driver, and it will clean
up whatever it was doing and return -EINTR? Such unwinding can be
tricky and needs careful review. Before i do that, i just want to make
sure this is your intention, and you yourself have carefully reviewed
the code.
Andrew
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 5/5] net: rnpgbe: Add register_netdev
2025-08-18 11:28 ` [PATCH v5 5/5] net: rnpgbe: Add register_netdev Dong Yibo
@ 2025-08-20 20:42 ` Andrew Lunn
2025-08-21 3:43 ` Yibo Dong
0 siblings, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-20 20:42 UTC (permalink / raw)
To: Dong Yibo
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
> +static int rnpgbe_get_permanent_mac(struct mucse_hw *hw,
> + u8 *mac_addr)
> +{
> + struct device *dev = &hw->pdev->dev;
> +
> + if (mucse_fw_get_macaddr(hw, hw->pfvfnum, mac_addr, hw->port) ||
> + !is_valid_ether_addr(mac_addr)) {
> + dev_err(dev, "Failed to get valid MAC from FW\n");
> + return -EINVAL;
I _think_ mucse_fw_get_macaddr() can return -EINTR, because deep down,
it has a call to mutex_lock_interruptible(). If that happens, you
should not return iEINVAL, it is not an invalid value, its just an
interrupted system call.
This is what i'm talking about needing careful review...
Andrew
---
pw-bot: cr
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 1/5] net: rnpgbe: Add build support for rnpgbe
2025-08-20 20:06 ` Andrew Lunn
@ 2025-08-21 1:29 ` Yibo Dong
2025-08-21 3:00 ` Andrew Lunn
0 siblings, 1 reply; 29+ messages in thread
From: Yibo Dong @ 2025-08-21 1:29 UTC (permalink / raw)
To: Andrew Lunn
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Wed, Aug 20, 2025 at 10:06:00PM +0200, Andrew Lunn wrote:
> > +/**
> > + * rnpgbe_init_module - Driver init routine
> > + *
> > + * rnpgbe_init_module is called when driver insmod
> > + *
> > + * @return: 0 on success, negative on failure
> > + **/
> > +static int __init rnpgbe_init_module(void)
> > +{
> > + return pci_register_driver(&rnpgbe_driver);
> > +}
> > +
> > +module_init(rnpgbe_init_module);
> > +
> > +/**
> > + * rnpgbe_exit_module - Driver remove routine
> > + *
> > + * rnpgbe_exit_module is called when driver is removed
> > + **/
> > +static void __exit rnpgbe_exit_module(void)
> > +{
> > + pci_unregister_driver(&rnpgbe_driver);
> > +}
> > +
> > +module_exit(rnpgbe_exit_module);
>
> This can be replaced by module_pci_driver()
>
Ok, I will improve it.
By the way, if I want to add some functions(maybe workqueue to handle
link status, or debugfs for the driver) in the future. The function is
only one for driver, not each for every pci device, should I turn back to
'module_exit' and 'module_init'?
Maybe workqueue can use 'system_power_efficient_wq' just like libwx
does?
>
> Andrew
>
> ---
> pw-bot: cr
>
Thanks for your feedback.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 3/5] net: rnpgbe: Add basic mbx ops support
2025-08-20 20:23 ` Andrew Lunn
@ 2025-08-21 1:44 ` Yibo Dong
2025-08-21 3:06 ` Andrew Lunn
0 siblings, 1 reply; 29+ messages in thread
From: Yibo Dong @ 2025-08-21 1:44 UTC (permalink / raw)
To: Andrew Lunn
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Wed, Aug 20, 2025 at 10:23:44PM +0200, Andrew Lunn wrote:
> > +/**
> > + * mucse_mbx_get_ack - Read ack from reg
> > + * @mbx: pointer to the MBX structure
> > + * @reg: register to read
> > + *
> > + * @return: the ack value
> > + **/
> > +static u16 mucse_mbx_get_ack(struct mucse_mbx_info *mbx, int reg)
> > +{
> > + return (mbx_data_rd32(mbx, reg) >> 16);
> > +}
>
> > +static int mucse_check_for_ack_pf(struct mucse_hw *hw)
> > +{
> > + struct mucse_mbx_info *mbx = &hw->mbx;
> > + u16 hw_fw_ack;
> > +
> > + hw_fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
>
> > +int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
> > +{
> > + struct mucse_mbx_info *mbx = &hw->mbx;
> > + int size_inwords = size / 4;
> > + u32 ctrl_reg;
> > + int ret;
> > + int i;
> > +
> > + ctrl_reg = PF2FW_MBOX_CTRL(mbx);
> > + ret = mucse_obtain_mbx_lock_pf(hw);
> > + if (ret)
> > + return ret;
> > +
> > + for (i = 0; i < size_inwords; i++)
> > + mbx_data_wr32(mbx, MBX_FW_PF_SHM_DATA + i * 4, msg[i]);
> > +
> > + /* flush msg and acks as we are overwriting the message buffer */
> > + hw->mbx.fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
>
> It seems like the ACK is always at MBX_FW2PF_COUNTER. So why pass it
> to mucse_mbx_get_ack()? Please look at your other getters and setters.
>
'mucse_mbx_get_ack' is always at MBX_FW2PF_COUNTER now, just for pf-fw mbx.
But, in the future, there will be pf-vf mbx with different input.
Should I move 'MBX_FW2PF_COUNTER' to function 'mucse_mbx_get_ack', and
update the function when I add vf relative code in the future?
> > +/**
> > + * mucse_write_mbx - Write a message to the mailbox
> > + * @hw: pointer to the HW structure
> > + * @msg: the message buffer
> > + * @size: length of buffer
> > + *
> > + * @return: 0 on success, negative on failure
> > + **/
> > +int mucse_write_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
> > +{
> > + return mucse_write_mbx_pf(hw, msg, size);
> > +}
>
> This function does not do anything useful. Why not call
> mucse_write_mbx_pf() directly?
>
Yes, I should call it directly.
> > +/**
> > + * mucse_check_for_msg - Check to see if fw sent us mail
> > + * @hw: pointer to the HW structure
> > + *
> > + * @return: 0 on success, negative on failure
> > + **/
> > +int mucse_check_for_msg(struct mucse_hw *hw)
> > +{
> > + return mucse_check_for_msg_pf(hw);
> > +}
> > +
> > +/**
> > + * mucse_check_for_ack - Check to see if fw sent us ACK
> > + * @hw: pointer to the HW structure
> > + *
> > + * @return: 0 on success, negative on failure
> > + **/
> > +int mucse_check_for_ack(struct mucse_hw *hw)
> > +{
> > + return mucse_check_for_ack_pf(hw);
> > +}
>
> These as well.
Got it, I will update it.
>
> Andrew
>
Thanks for your feedback.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support
2025-08-20 20:10 ` Andrew Lunn
@ 2025-08-21 1:53 ` Yibo Dong
0 siblings, 0 replies; 29+ messages in thread
From: Yibo Dong @ 2025-08-21 1:53 UTC (permalink / raw)
To: Andrew Lunn
Cc: Vadim Fedorenko, andrew+netdev, davem, edumazet, kuba, pabeni,
horms, corbet, gur.stavi, maddy, mpe, danishanwar, lee, gongfan1,
lorenzo, geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-kernel, linux-doc
On Wed, Aug 20, 2025 at 10:10:00PM +0200, Andrew Lunn wrote:
> On Wed, Aug 20, 2025 at 09:43:41AM +0800, Yibo Dong wrote:
> > On Tue, Aug 19, 2025 at 02:59:09PM +0100, Vadim Fedorenko wrote:
> > > On 18/08/2025 12:28, Dong Yibo wrote:
> > > > Initialize n500/n210 chip bar resource map and
> > > > dma, eth, mbx ... info for future use.
> > > >
> > > [...]
> > >
> > > > +struct mucse_hw {
> > > > + void __iomem *hw_addr;
> > > > + void __iomem *ring_msix_base;
> > > > + struct pci_dev *pdev;
> > > > + enum rnpgbe_hw_type hw_type;
> > > > + struct mucse_dma_info dma;
> > > > + struct mucse_eth_info eth;
> > > > + struct mucse_mac_info mac;
> > > > + struct mucse_mbx_info mbx;
> > > > + u32 usecstocount;
> > >
> > > What is this field for? You don't use it anywhere in the patchset apart
> > > from initialization. Maybe it's better to introduce it once it's used?
> > > Together with the defines of values for this field...
> > >
> >
> > It is used to store chip frequency which is used to calculate values
> > related to 'delay register' in the future. I will improve this.
>
> Maybe also see if you can find a better name. count is rather
> vague. Count of what?
>
> Andrew
>
Chip use clock cycle not us(microsecond) to achieve timing. If chip is 125MHz,
driver setups a register to 125 to get 1us timing(125 * 10^6 * 10^(-6)).
Maybe usecstocycle better?
Thanks for your feedback.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support
2025-08-20 20:16 ` Andrew Lunn
@ 2025-08-21 1:54 ` Yibo Dong
0 siblings, 0 replies; 29+ messages in thread
From: Yibo Dong @ 2025-08-21 1:54 UTC (permalink / raw)
To: Andrew Lunn
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Wed, Aug 20, 2025 at 10:16:00PM +0200, Andrew Lunn wrote:
> > +const struct rnpgbe_info rnpgbe_n500_info = {
> > + .total_queue_pair_cnts = RNPGBE_MAX_QUEUES,
> > + .hw_type = rnpgbe_hw_n500,
> > + .init = &rnpgbe_init_n500,
> > +};
> > +
> > +const struct rnpgbe_info rnpgbe_n210_info = {
> > + .total_queue_pair_cnts = RNPGBE_MAX_QUEUES,
> > + .hw_type = rnpgbe_hw_n210,
> > + .init = &rnpgbe_init_n210,
> > +};
> > +
> > +const struct rnpgbe_info rnpgbe_n210L_info = {
> > + .total_queue_pair_cnts = RNPGBE_MAX_QUEUES,
> > + .hw_type = rnpgbe_hw_n210L,
> > + .init = &rnpgbe_init_n210,
> > +};
>
> total_queue_pair_cnts is the same for all three. So it probably does
> not need to be in the structure. You can just use RNPGBE_MAX_QUEUES.
>
> Andrew
>
Got it, I will update it.
> ---
> pw-bot: cr
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support
2025-08-20 20:30 ` Andrew Lunn
@ 2025-08-21 2:04 ` Yibo Dong
0 siblings, 0 replies; 29+ messages in thread
From: Yibo Dong @ 2025-08-21 2:04 UTC (permalink / raw)
To: Andrew Lunn
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Wed, Aug 20, 2025 at 10:30:17PM +0200, Andrew Lunn wrote:
> > +int mucse_mbx_get_capability(struct mucse_hw *hw)
> > +{
> > + struct hw_abilities ability = {};
> > + int try_cnt = 3;
> > + int err = -EIO;
> > +
> > + while (try_cnt--) {
> > + err = mucse_fw_get_capability(hw, &ability);
> > + if (err)
> > + continue;
> > + hw->pfvfnum = le16_to_cpu(ability.pfnum);
> > + hw->fw_version = le32_to_cpu(ability.fw_version);
> > + hw->usecstocount = le32_to_cpu(ability.axi_mhz);
>
> If you can get it from the hardware, why do you need to initialise it
> in the earlier patch?
>
> I guess you have a bootstrap problem, you need it to get it. But
> cannot you just initialise it to a single pessimistic value which will
> work well enough for all hardware variants until you can actually ask
> the hardware?
>
> Andrew
>
It is a problem related with fw version. Older fw may return with axi_mhz
0, So I init a no-zero default value first. Also, I missed to check the axi_mhz
here. The 'usecstocount' is removed in v6, I will update here like this in
the patch which truely use 'usecstocount':
if (le32_to_cpu(ability.axi_mhz))
hw->usecstocount = le32_to_cpu(ability.axi_mhz);
/* else keep use the default value */
Thanks for your feedback.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support
2025-08-20 20:37 ` Andrew Lunn
@ 2025-08-21 2:49 ` Yibo Dong
2025-08-21 3:13 ` Andrew Lunn
0 siblings, 1 reply; 29+ messages in thread
From: Yibo Dong @ 2025-08-21 2:49 UTC (permalink / raw)
To: Andrew Lunn
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Wed, Aug 20, 2025 at 10:37:01PM +0200, Andrew Lunn wrote:
> > +static int mucse_mbx_fw_post_req(struct mucse_hw *hw,
> > + struct mbx_fw_cmd_req *req,
> > + struct mbx_req_cookie *cookie)
> > +{
> > + int len = le16_to_cpu(req->datalen);
> > + int err;
> > +
> > + cookie->errcode = 0;
> > + cookie->done = 0;
> > + init_waitqueue_head(&cookie->wait);
> > + err = mutex_lock_interruptible(&hw->mbx.lock);
> > + if (err)
> > + return err;
> > + err = mucse_write_mbx(hw, (u32 *)req, len);
> > + if (err)
> > + goto out;
> > + err = wait_event_timeout(cookie->wait,
> > + cookie->done == 1,
> > + cookie->timeout_jiffies);
> > +
> > + if (!err)
> > + err = -ETIMEDOUT;
> > + else
> > + err = 0;
> > + if (!err && cookie->errcode)
> > + err = cookie->errcode;
> > +out:
> > + mutex_unlock(&hw->mbx.lock);
> > + return err;
>
> What is your design with respect to mutex_lock_interruptible() and
> then calling wait_event_timeout() which will ignore signals?
>
> Is your intention that you can always ^C the driver, and it will clean
> up whatever it was doing and return -EINTR? Such unwinding can be
> tricky and needs careful review. Before i do that, i just want to make
> sure this is your intention, and you yourself have carefully reviewed
> the code.
>
> Andrew
>
>
'mucse_mbx_fw_post_req' is designed can be called by 'cat /sys/xxx', So I used
xx_interruptible() before.
The design sequence is:
write_mbx with cookie ------> fw ----> dirver_irq_handler(call wake_up)
| |
V V
wait_event_xxxx -------------------> free(cookie)
But if ^C just after 'wait_event_interruptible_timeout', cookie will
be free before fw really response, a crash will happen.
cookie pointer is in mbx.req, and fw response with no change.
write_mbx with cookie ------> fw ---------> dirver_irq_handler(call wake_up)
| |
V V
wait_event_xxxx ---> free(cookie) crash with freed cookie
|
v
^C
So I use goto retry if -ERESTARTSYS with wait_event_interruptible_timeout.
And it is the same with wait_event_timeout.
If ^C in mutex_lock_interruptible, it is safe return since no write to
fw and no response from fw.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 1/5] net: rnpgbe: Add build support for rnpgbe
2025-08-21 1:29 ` Yibo Dong
@ 2025-08-21 3:00 ` Andrew Lunn
0 siblings, 0 replies; 29+ messages in thread
From: Andrew Lunn @ 2025-08-21 3:00 UTC (permalink / raw)
To: Yibo Dong
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
> Ok, I will improve it.
> By the way, if I want to add some functions(maybe workqueue to handle
> link status, or debugfs for the driver) in the future. The function is
> only one for driver, not each for every pci device, should I turn back to
> 'module_exit' and 'module_init'?
> Maybe workqueue can use 'system_power_efficient_wq' just like libwx
> does?
Generally, you don't have per driver data, only per device data. It
makes the locking simpler, and handling bind/unbind etc.
Andrew
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 3/5] net: rnpgbe: Add basic mbx ops support
2025-08-21 1:44 ` Yibo Dong
@ 2025-08-21 3:06 ` Andrew Lunn
2025-08-21 3:51 ` Yibo Dong
0 siblings, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-21 3:06 UTC (permalink / raw)
To: Yibo Dong
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Thu, Aug 21, 2025 at 09:44:11AM +0800, Yibo Dong wrote:
> On Wed, Aug 20, 2025 at 10:23:44PM +0200, Andrew Lunn wrote:
> > > +/**
> > > + * mucse_mbx_get_ack - Read ack from reg
> > > + * @mbx: pointer to the MBX structure
> > > + * @reg: register to read
> > > + *
> > > + * @return: the ack value
> > > + **/
> > > +static u16 mucse_mbx_get_ack(struct mucse_mbx_info *mbx, int reg)
> > > +{
> > > + return (mbx_data_rd32(mbx, reg) >> 16);
> > > +}
> >
> > > +static int mucse_check_for_ack_pf(struct mucse_hw *hw)
> > > +{
> > > + struct mucse_mbx_info *mbx = &hw->mbx;
> > > + u16 hw_fw_ack;
> > > +
> > > + hw_fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
> >
> > > +int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
> > > +{
> > > + struct mucse_mbx_info *mbx = &hw->mbx;
> > > + int size_inwords = size / 4;
> > > + u32 ctrl_reg;
> > > + int ret;
> > > + int i;
> > > +
> > > + ctrl_reg = PF2FW_MBOX_CTRL(mbx);
> > > + ret = mucse_obtain_mbx_lock_pf(hw);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + for (i = 0; i < size_inwords; i++)
> > > + mbx_data_wr32(mbx, MBX_FW_PF_SHM_DATA + i * 4, msg[i]);
> > > +
> > > + /* flush msg and acks as we are overwriting the message buffer */
> > > + hw->mbx.fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
> >
> > It seems like the ACK is always at MBX_FW2PF_COUNTER. So why pass it
> > to mucse_mbx_get_ack()? Please look at your other getters and setters.
> >
>
> 'mucse_mbx_get_ack' is always at MBX_FW2PF_COUNTER now, just for pf-fw mbx.
> But, in the future, there will be pf-vf mbx with different input.
> Should I move 'MBX_FW2PF_COUNTER' to function 'mucse_mbx_get_ack', and
> update the function when I add vf relative code in the future?
Maybe add mucse_mbx_get_pf_ack() so you can later add
mucse_mbx_get_vf_ack()?
The problem is, our crystal ball about what will come next is not very
good. So we review the code we see now, and make comments about it
now. You can add comments explaining why something is the way it is
because in the future it needs to be more generic to handle additional
use cases, etc. Or explain in the commit message.
Andrew
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support
2025-08-21 2:49 ` Yibo Dong
@ 2025-08-21 3:13 ` Andrew Lunn
2025-08-21 3:32 ` Yibo Dong
0 siblings, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-21 3:13 UTC (permalink / raw)
To: Yibo Dong
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
> 'mucse_mbx_fw_post_req' is designed can be called by 'cat /sys/xxx',
It is pretty unusual for ethernet drivers to export data in /sys,
except via standard APIs, like statistics, carrier, address, opstate
etc. I don't know how well the core will handle EINTR. It is not
something most drivers do. -ETIMEDOUT is more likely when the firmware
has crashed and does not respond in time.
Do you have any operations which take a long time when things are
working correctly?
Andrew
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support
2025-08-21 3:13 ` Andrew Lunn
@ 2025-08-21 3:32 ` Yibo Dong
2025-08-22 19:52 ` Andrew Lunn
0 siblings, 1 reply; 29+ messages in thread
From: Yibo Dong @ 2025-08-21 3:32 UTC (permalink / raw)
To: Andrew Lunn
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Thu, Aug 21, 2025 at 05:13:27AM +0200, Andrew Lunn wrote:
> > 'mucse_mbx_fw_post_req' is designed can be called by 'cat /sys/xxx',
>
> It is pretty unusual for ethernet drivers to export data in /sys,
> except via standard APIs, like statistics, carrier, address, opstate
> etc. I don't know how well the core will handle EINTR. It is not
> something most drivers do. -ETIMEDOUT is more likely when the firmware
> has crashed and does not respond in time.
>
> Do you have any operations which take a long time when things are
> working correctly?
>
> Andrew
>
'Update firmware operation' will take long time, maybe more than
10s. If user use 'ethtool -f' to update firmware, and ^C before done?
If ^C before mucse_write_mbx, return as soon as possible. If after mucse_write_mbx,
wait until fw true response.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 5/5] net: rnpgbe: Add register_netdev
2025-08-20 20:42 ` Andrew Lunn
@ 2025-08-21 3:43 ` Yibo Dong
0 siblings, 0 replies; 29+ messages in thread
From: Yibo Dong @ 2025-08-21 3:43 UTC (permalink / raw)
To: Andrew Lunn
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Wed, Aug 20, 2025 at 10:42:47PM +0200, Andrew Lunn wrote:
> > +static int rnpgbe_get_permanent_mac(struct mucse_hw *hw,
> > + u8 *mac_addr)
> > +{
> > + struct device *dev = &hw->pdev->dev;
> > +
> > + if (mucse_fw_get_macaddr(hw, hw->pfvfnum, mac_addr, hw->port) ||
> > + !is_valid_ether_addr(mac_addr)) {
> > + dev_err(dev, "Failed to get valid MAC from FW\n");
> > + return -EINVAL;
>
> I _think_ mucse_fw_get_macaddr() can return -EINTR, because deep down,
> it has a call to mutex_lock_interruptible(). If that happens, you
> should not return iEINVAL, it is not an invalid value, its just an
> interrupted system call.
>
> This is what i'm talking about needing careful review...
>
> Andrew
>
> ---
> pw-bot: cr
>
>
Ok, Maybe like This?
Just return function return if mucse_fw_get_macaddr failed, and return
-EINVAL if not a valid mac.
static int rnpgbe_get_permanent_mac(struct mucse_hw *hw,
u8 *mac_addr)
{
struct device *dev = &hw->pdev->dev;
int ret;
ret = mucse_fw_get_macaddr(hw, hw->pfvfnum, mac_addr, hw->port);
if (ret) {
dev_err(dev, "Failed to get MAC from FW\n");
return ret;
}
if (!is_valid_ether_addr(mac_addr)) {
dev_err(dev, "MAC from FW is not valid\n");
return -EINVAL;
}
return 0;
}
Thanks for your feedback.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 3/5] net: rnpgbe: Add basic mbx ops support
2025-08-21 3:06 ` Andrew Lunn
@ 2025-08-21 3:51 ` Yibo Dong
0 siblings, 0 replies; 29+ messages in thread
From: Yibo Dong @ 2025-08-21 3:51 UTC (permalink / raw)
To: Andrew Lunn
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Thu, Aug 21, 2025 at 05:06:50AM +0200, Andrew Lunn wrote:
> On Thu, Aug 21, 2025 at 09:44:11AM +0800, Yibo Dong wrote:
> > On Wed, Aug 20, 2025 at 10:23:44PM +0200, Andrew Lunn wrote:
> > > > +/**
> > > > + * mucse_mbx_get_ack - Read ack from reg
> > > > + * @mbx: pointer to the MBX structure
> > > > + * @reg: register to read
> > > > + *
> > > > + * @return: the ack value
> > > > + **/
> > > > +static u16 mucse_mbx_get_ack(struct mucse_mbx_info *mbx, int reg)
> > > > +{
> > > > + return (mbx_data_rd32(mbx, reg) >> 16);
> > > > +}
> > >
> > > > +static int mucse_check_for_ack_pf(struct mucse_hw *hw)
> > > > +{
> > > > + struct mucse_mbx_info *mbx = &hw->mbx;
> > > > + u16 hw_fw_ack;
> > > > +
> > > > + hw_fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
> > >
> > > > +int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
> > > > +{
> > > > + struct mucse_mbx_info *mbx = &hw->mbx;
> > > > + int size_inwords = size / 4;
> > > > + u32 ctrl_reg;
> > > > + int ret;
> > > > + int i;
> > > > +
> > > > + ctrl_reg = PF2FW_MBOX_CTRL(mbx);
> > > > + ret = mucse_obtain_mbx_lock_pf(hw);
> > > > + if (ret)
> > > > + return ret;
> > > > +
> > > > + for (i = 0; i < size_inwords; i++)
> > > > + mbx_data_wr32(mbx, MBX_FW_PF_SHM_DATA + i * 4, msg[i]);
> > > > +
> > > > + /* flush msg and acks as we are overwriting the message buffer */
> > > > + hw->mbx.fw_ack = mucse_mbx_get_ack(mbx, MBX_FW2PF_COUNTER);
> > >
> > > It seems like the ACK is always at MBX_FW2PF_COUNTER. So why pass it
> > > to mucse_mbx_get_ack()? Please look at your other getters and setters.
> > >
> >
> > 'mucse_mbx_get_ack' is always at MBX_FW2PF_COUNTER now, just for pf-fw mbx.
> > But, in the future, there will be pf-vf mbx with different input.
> > Should I move 'MBX_FW2PF_COUNTER' to function 'mucse_mbx_get_ack', and
> > update the function when I add vf relative code in the future?
>
> Maybe add mucse_mbx_get_pf_ack() so you can later add
> mucse_mbx_get_vf_ack()?
>
> The problem is, our crystal ball about what will come next is not very
> good. So we review the code we see now, and make comments about it
> now. You can add comments explaining why something is the way it is
> because in the future it needs to be more generic to handle additional
> use cases, etc. Or explain in the commit message.
>
> Andrew
>
Got it, I will move MBX_FW2PF_COUNTER to mucse_mbx_get_ack and rename
the fucntion. And add new function later.
Thanks for your feedback.
Thanks for your feedback.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support
2025-08-21 3:32 ` Yibo Dong
@ 2025-08-22 19:52 ` Andrew Lunn
2025-08-23 1:12 ` Yibo Dong
0 siblings, 1 reply; 29+ messages in thread
From: Andrew Lunn @ 2025-08-22 19:52 UTC (permalink / raw)
To: Yibo Dong
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
> 'Update firmware operation' will take long time, maybe more than
> 10s. If user use 'ethtool -f' to update firmware, and ^C before done?
> If ^C before mucse_write_mbx, return as soon as possible. If after mucse_write_mbx,
> wait until fw true response.
And what happens if the firmware writing is interrupted? Could you end
up with a brick? This is actually one of the operations i would not
expect to be able to ^C.
You might also want consider devlink flash.
https://www.kernel.org/doc/html/latest/networking/devlink/devlink-flash.html
It replaces the older ethtool-flash mechanism, and doesn’t require
taking any networking locks in the kernel to perform the flash
update.
I assume this is meaning ethtool take RTNL, and while that is held, no
other network configuration can be performed on any interface. devlink
has its own lock so avoids this.
Andrew
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support
2025-08-22 19:52 ` Andrew Lunn
@ 2025-08-23 1:12 ` Yibo Dong
0 siblings, 0 replies; 29+ messages in thread
From: Yibo Dong @ 2025-08-23 1:12 UTC (permalink / raw)
To: Andrew Lunn
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms, corbet,
gur.stavi, maddy, mpe, danishanwar, lee, gongfan1, lorenzo,
geert+renesas, Parthiban.Veerasooran, lukas.bulwahn,
alexanderduyck, richardcochran, netdev, linux-doc, linux-kernel
On Fri, Aug 22, 2025 at 09:52:25PM +0200, Andrew Lunn wrote:
> > 'Update firmware operation' will take long time, maybe more than
> > 10s. If user use 'ethtool -f' to update firmware, and ^C before done?
> > If ^C before mucse_write_mbx, return as soon as possible. If after mucse_write_mbx,
> > wait until fw true response.
>
> And what happens if the firmware writing is interrupted? Could you end
> up with a brick? This is actually one of the operations i would not
> expect to be able to ^C.
>
> You might also want consider devlink flash.
>
> https://www.kernel.org/doc/html/latest/networking/devlink/devlink-flash.html
>
> It replaces the older ethtool-flash mechanism, and doesn’t require
> taking any networking locks in the kernel to perform the flash
> update.
>
> I assume this is meaning ethtool take RTNL, and while that is held, no
> other network configuration can be performed on any interface. devlink
> has its own lock so avoids this.
>
> Andrew
>
ethtool or devlink both call mbx(mucse_mbx_fw_post_req)
to do the true update to firmware. FW not end up with a brick, it has
fault tolerance itself.
But that's not the point. The original question is
about 'wait_event_timeout', I add some comment link this in v6:
Wait fw response without interruptible.
static int mucse_mbx_fw_post_req(struct mucse_hw *hw,
struct mbx_fw_cmd_req *req,
struct mbx_req_cookie *cookie)
{
int len = le16_to_cpu(req->datalen);
int err;
cookie->errcode = 0;
cookie->done = 0;
init_waitqueue_head(&cookie->wait);
err = mutex_lock_interruptible(&hw->mbx.lock);
if (err)
return err;
err = mucse_write_mbx_pf(hw, (u32 *)req, len);
if (err)
goto out;
/* if write succeeds, we must wait for firmware response or
* timeout to avoid using the already freed cookie->wait
*/
err = wait_event_timeout(cookie->wait,
cookie->done == 1,
cookie->timeout_jiffies);
if (!err)
err = -ETIMEDOUT;
else
err = 0;
if (!err && cookie->errcode)
err = cookie->errcode;
out:
mutex_unlock(&hw->mbx.lock);
return err;
}
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2025-08-23 1:12 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-18 11:28 [PATCH v5 0/5] Add driver for 1Gbe network chips from MUCSE Dong Yibo
2025-08-18 11:28 ` [PATCH v5 1/5] net: rnpgbe: Add build support for rnpgbe Dong Yibo
2025-08-20 20:06 ` Andrew Lunn
2025-08-21 1:29 ` Yibo Dong
2025-08-21 3:00 ` Andrew Lunn
2025-08-18 11:28 ` [PATCH v5 2/5] net: rnpgbe: Add n500/n210 chip support Dong Yibo
2025-08-19 13:59 ` Vadim Fedorenko
2025-08-20 1:43 ` Yibo Dong
2025-08-20 20:10 ` Andrew Lunn
2025-08-21 1:53 ` Yibo Dong
2025-08-20 20:16 ` Andrew Lunn
2025-08-21 1:54 ` Yibo Dong
2025-08-18 11:28 ` [PATCH v5 3/5] net: rnpgbe: Add basic mbx ops support Dong Yibo
2025-08-20 20:23 ` Andrew Lunn
2025-08-21 1:44 ` Yibo Dong
2025-08-21 3:06 ` Andrew Lunn
2025-08-21 3:51 ` Yibo Dong
2025-08-18 11:28 ` [PATCH v5 4/5] net: rnpgbe: Add basic mbx_fw support Dong Yibo
2025-08-20 20:30 ` Andrew Lunn
2025-08-21 2:04 ` Yibo Dong
2025-08-20 20:37 ` Andrew Lunn
2025-08-21 2:49 ` Yibo Dong
2025-08-21 3:13 ` Andrew Lunn
2025-08-21 3:32 ` Yibo Dong
2025-08-22 19:52 ` Andrew Lunn
2025-08-23 1:12 ` Yibo Dong
2025-08-18 11:28 ` [PATCH v5 5/5] net: rnpgbe: Add register_netdev Dong Yibo
2025-08-20 20:42 ` Andrew Lunn
2025-08-21 3:43 ` Yibo Dong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).