From: illusion wang Add base dispatch layer infrastructure for control-level routing: 1. Dispatch management & ops table structures allocation 2. X-macro op table template for uniform dispatch entry registration 3. Control PF / regular PF routing logic via ctrl_lvl bitmask 4. Local chip init/deinit dispatch wrappers (no channel dependency) Document constraint: init_chip_module/deinit_chip_module only valid on Control PF, caller must guard with has_ctrl to avoid NULL deref. This patch only provides core routing skeleton, no channel message handling or resource locking logic. Signed-off-by: illusion wang --- .../net/ethernet/nebula-matrix/nbl/Makefile | 1 + .../nbl/nbl_channel/nbl_channel.c | 4 + .../net/ethernet/nebula-matrix/nbl/nbl_core.h | 4 + .../nebula-matrix/nbl/nbl_core/nbl_dispatch.c | 137 ++++++++++++++++++ .../nebula-matrix/nbl/nbl_core/nbl_dispatch.h | 24 +++ .../nbl/nbl_include/nbl_def_channel.h | 26 ++++ .../nbl/nbl_include/nbl_def_dispatch.h | 42 ++++++ .../nbl/nbl_include/nbl_include.h | 16 ++ .../net/ethernet/nebula-matrix/nbl/nbl_main.c | 8 + 9 files changed, 262 insertions(+) create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.c create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.h create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dispatch.h diff --git a/drivers/net/ethernet/nebula-matrix/nbl/Makefile b/drivers/net/ethernet/nebula-matrix/nbl/Makefile index 523aa26d727c..9b6ec0fc0428 100644 --- a/drivers/net/ethernet/nebula-matrix/nbl/Makefile +++ b/drivers/net/ethernet/nebula-matrix/nbl/Makefile @@ -10,4 +10,5 @@ nbl-objs += nbl_common/nbl_common.o \ nbl_hw/nbl_resource.o \ nbl_hw/nbl_interrupt.o \ nbl_hw/nbl_vsi.o \ + nbl_core/nbl_dispatch.o \ nbl_main.o diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.c index 220c740f68b9..655ada86978a 100644 --- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.c +++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.c @@ -1051,6 +1051,10 @@ int nbl_chan_init_common(struct nbl_adapter *adap) struct nbl_channel_mgt *chan_mgt; int ret; + BUILD_BUG_ON(sizeof(struct nbl_chan_param_cfg_msix_map) != 8); + BUILD_BUG_ON(sizeof(struct nbl_chan_param_set_mailbox_irq) != 4); + BUILD_BUG_ON(sizeof(struct nbl_chan_param_get_vsi_id) != 4); + BUILD_BUG_ON(sizeof(struct nbl_chan_param_get_eth_id) != 8); chan_mgt = nbl_chan_setup_chan_mgt(adap); if (IS_ERR(chan_mgt)) { ret = PTR_ERR(chan_mgt); diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h index 319d105436a1..a1f874bb03c6 100644 --- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h +++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h @@ -14,6 +14,8 @@ struct nbl_hw_mgt; struct nbl_hw_ops_tbl; struct nbl_resource_mgt; struct nbl_resource_ops_tbl; +struct nbl_dispatch_mgt; +struct nbl_dispatch_ops_tbl; struct nbl_channel_ops_tbl; struct nbl_channel_mgt; @@ -25,12 +27,14 @@ enum { struct nbl_interface { struct nbl_hw_ops_tbl *hw_ops_tbl; struct nbl_resource_ops_tbl *resource_ops_tbl; + struct nbl_dispatch_ops_tbl *dispatch_ops_tbl; struct nbl_channel_ops_tbl *channel_ops_tbl; }; struct nbl_core { struct nbl_hw_mgt *hw_mgt; struct nbl_resource_mgt *res_mgt; + struct nbl_dispatch_mgt *disp_mgt; struct nbl_channel_mgt *chan_mgt; }; diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.c new file mode 100644 index 000000000000..8116643859c7 --- /dev/null +++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Nebula Matrix Limited. + */ +#include +#include +#include "nbl_dispatch.h" + +static void nbl_disp_deinit_module(struct nbl_dispatch_mgt *disp_mgt) +{ + struct nbl_resource_ops *res_ops = disp_mgt->res_ops_tbl->ops; + struct nbl_resource_mgt *p = disp_mgt->res_ops_tbl->priv; + + NBL_OPS_CALL(res_ops->deinit_module, (p)); +} + +static int nbl_disp_init_module(struct nbl_dispatch_mgt *disp_mgt) +{ + struct nbl_resource_ops *res_ops = disp_mgt->res_ops_tbl->ops; + struct nbl_resource_mgt *p = disp_mgt->res_ops_tbl->priv; + + return NBL_OPS_CALL_RET(res_ops->init_module, (p)); +} + +/* NBL_DISP_SET_OPS(disp_op_name, func, ctrl_lvl, msg_type, msg_req, msg_resp) + * ctrl_lvl is to define when this disp_op should go directly to res_op, + * not sending a channel msg. + * Use X Macros to reduce codes in channel_op and disp_op setup/remove + * + * Note: init_module / deinit_module only valid on Control PF + * (has_ctrl=1). On regular PF without MGT ctrl bit, these ops become NULL, + * caller must guard with has_ctrl to avoid NULL dereference. + */ +#define NBL_DISP_OPS_TBL \ +do { \ + NBL_DISP_SET_OPS(init_module, nbl_disp_init_module, \ + NBL_DISP_CTRL_LVL_MGT, -1, NULL, NULL); \ + NBL_DISP_SET_OPS(deinit_module, \ + nbl_disp_deinit_module, \ + NBL_DISP_CTRL_LVL_MGT, -1, NULL, NULL); \ +} while (0) + +/* Ctrl lvl means that if a certain level is set, then all disp_ops that + * declared this lvl will go directly to res_ops, rather than send a + * channel msg, and vice versa. + */ +static void nbl_disp_setup_ctrl_lvl(struct nbl_dispatch_mgt *disp_mgt, u32 lvl) +{ + struct nbl_dispatch_ops *disp_ops = disp_mgt->disp_ops_tbl->ops; + + set_bit(lvl, disp_mgt->ctrl_lvl); + +#define NBL_DISP_SET_OPS(disp_op, func, ctrl, msg_type, msg_req, msg_resp) \ +do { \ + typeof(msg_type) _msg_type = (msg_type); \ + (void)(_msg_type); \ + (void)(msg_resp); \ + disp_ops->NBL_NAME(disp_op) = \ + test_bit(ctrl, disp_mgt->ctrl_lvl) ? func : msg_req; \ +} while (0) + NBL_DISP_OPS_TBL; +#undef NBL_DISP_SET_OPS +} + +static struct nbl_dispatch_mgt * +nbl_disp_setup_disp_mgt(struct nbl_common_info *common) +{ + struct nbl_dispatch_mgt *disp_mgt; + struct device *dev = common->dev; + + disp_mgt = devm_kzalloc(dev, sizeof(*disp_mgt), GFP_KERNEL); + if (!disp_mgt) + return ERR_PTR(-ENOMEM); + + disp_mgt->common = common; + return disp_mgt; +} + +static struct nbl_dispatch_ops_tbl * +nbl_disp_setup_ops(struct device *dev, struct nbl_dispatch_mgt *disp_mgt) +{ + struct nbl_dispatch_ops_tbl *disp_ops_tbl; + struct nbl_dispatch_ops *disp_ops; + + disp_ops_tbl = devm_kzalloc(dev, sizeof(*disp_ops_tbl), GFP_KERNEL); + if (!disp_ops_tbl) + return ERR_PTR(-ENOMEM); + + disp_ops = devm_kzalloc(dev, sizeof(*disp_ops), GFP_KERNEL); + if (!disp_ops) + return ERR_PTR(-ENOMEM); + + disp_ops_tbl->ops = disp_ops; + disp_ops_tbl->priv = disp_mgt; + + return disp_ops_tbl; +} + +int nbl_disp_init(struct nbl_adapter *adapter) +{ + struct nbl_common_info *common = &adapter->common; + struct nbl_dispatch_ops_tbl *disp_ops_tbl; + struct nbl_resource_ops_tbl *res_ops_tbl = + adapter->intf.resource_ops_tbl; + struct nbl_channel_ops_tbl *chan_ops_tbl = + adapter->intf.channel_ops_tbl; + struct device *dev = &adapter->pdev->dev; + struct nbl_dispatch_mgt *disp_mgt; + int ret; + + disp_mgt = nbl_disp_setup_disp_mgt(common); + if (IS_ERR(disp_mgt)) { + ret = PTR_ERR(disp_mgt); + return ret; + } + + disp_ops_tbl = nbl_disp_setup_ops(dev, disp_mgt); + if (IS_ERR(disp_ops_tbl)) { + ret = PTR_ERR(disp_ops_tbl); + return ret; + } + + disp_mgt->res_ops_tbl = res_ops_tbl; + disp_mgt->chan_ops_tbl = chan_ops_tbl; + disp_mgt->disp_ops_tbl = disp_ops_tbl; + adapter->core.disp_mgt = disp_mgt; + adapter->intf.dispatch_ops_tbl = disp_ops_tbl; + + if (common->has_ctrl) + nbl_disp_setup_ctrl_lvl(disp_mgt, NBL_DISP_CTRL_LVL_MGT); + + return 0; +} + +void nbl_disp_remove(struct nbl_adapter *adapter) +{ +} diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.h new file mode 100644 index 000000000000..f06b90075af4 --- /dev/null +++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Nebula Matrix Limited. + */ + +#ifndef _NBL_DISPATCH_H_ +#define _NBL_DISPATCH_H_ +#include "../nbl_include/nbl_include.h" +#include "../nbl_include/nbl_def_channel.h" +#include "../nbl_include/nbl_def_hw.h" +#include "../nbl_include/nbl_def_resource.h" +#include "../nbl_include/nbl_def_dispatch.h" +#include "../nbl_include/nbl_def_common.h" +#include "../nbl_core.h" + +struct nbl_dispatch_mgt { + struct nbl_common_info *common; + struct nbl_resource_ops_tbl *res_ops_tbl; + struct nbl_channel_ops_tbl *chan_ops_tbl; + struct nbl_dispatch_ops_tbl *disp_ops_tbl; + DECLARE_BITMAP(ctrl_lvl, NBL_DISP_CTRL_LVL_MAX); +}; + +#endif diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_channel.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_channel.h index abeaceea2423..381696b05237 100644 --- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_channel.h +++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_channel.h @@ -281,6 +281,32 @@ enum nbl_chan_state { NBL_CHAN_STATE_NBITS }; +struct nbl_chan_param_cfg_msix_map { + __le16 num_net_msix; + __le16 num_others_msix; + __le16 msix_mask_en; + __le16 rsvd; +}; + +struct nbl_chan_param_set_mailbox_irq { + __le16 vector_id; + u8 enable_msix; + u8 rsvd; +}; + +struct nbl_chan_param_get_vsi_id { + __le16 vsi_id; + __le16 type; +}; + +struct nbl_chan_param_get_eth_id { + __le16 vsi_id; + u8 eth_num; + u8 eth_id; + u8 logic_eth_id; + u8 rsvd[3]; +}; + struct nbl_board_port_info { u8 eth_num; u8 eth_speed; diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dispatch.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dispatch.h new file mode 100644 index 000000000000..4386cfd6faa7 --- /dev/null +++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dispatch.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Nebula Matrix Limited. + */ + +#ifndef _NBL_DEF_DISPATCH_H_ +#define _NBL_DEF_DISPATCH_H_ + +#include + +struct nbl_dispatch_mgt; +struct nbl_adapter; +enum { + NBL_DISP_CTRL_LVL_NEVER = 0, + NBL_DISP_CTRL_LVL_MGT, + NBL_DISP_CTRL_LVL_NET, + NBL_DISP_CTRL_LVL_MAX, +}; + +struct nbl_dispatch_ops { + int (*init_module)(struct nbl_dispatch_mgt *disp_mgt); + void (*deinit_module)(struct nbl_dispatch_mgt *disp_mgt); + int (*configure_msix_map)(struct nbl_dispatch_mgt *disp_mgt, + u16 num_net_msix, u16 num_others_msix, + bool net_msix_mask_en); + int (*destroy_msix_map)(struct nbl_dispatch_mgt *disp_mgt); + int (*set_mailbox_irq)(struct nbl_dispatch_mgt *disp_mgt, + u16 vector_id, bool enable_msix); + int (*get_vsi_id)(struct nbl_dispatch_mgt *disp_mgt, u16 type, + u16 *vsi_id); + int (*get_eth_id)(struct nbl_dispatch_mgt *disp_mgt, u16 vsi_id, + u8 *eth_num, u8 *eth_id, u8 *logic_eth_id); +}; + +struct nbl_dispatch_ops_tbl { + struct nbl_dispatch_ops *ops; + struct nbl_dispatch_mgt *priv; +}; + +int nbl_disp_init(struct nbl_adapter *adapter); +void nbl_disp_remove(struct nbl_adapter *adapter); +#endif diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h index 5cd0dac5a776..6336f952dd04 100644 --- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h +++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h @@ -19,6 +19,8 @@ #define NBL_MAX_FUNC 520 #define NBL_MAX_ETHERNET 4 +/* Used for macros to pass checkpatch */ +#define NBL_NAME(x) x enum { NBL_VSI_DATA = 0, @@ -42,6 +44,20 @@ enum nbl_fw_port_speed { NBL_FW_PORT_SPEED_100G, }; +#define NBL_OPS_CALL(func, para) \ +do { \ + typeof(func) _func = (func); \ + if (_func) \ + _func para; \ +} while (0) + +/* Optional ops: NULL means not implemented, return 0 = no-op (not an error) */ +#define NBL_OPS_CALL_RET(func, para) \ +({ \ + typeof(func) _func = (func); \ + _func ? _func para : 0; \ +}) + enum nbl_performance_mode { NBL_QUIRKS_NO_TOE, NBL_QUIRKS_UVN_PREFETCH_ALIGN, diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c index a292ec8620db..1cf661eb88a8 100644 --- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c +++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c @@ -11,6 +11,7 @@ #include "nbl_include/nbl_def_channel.h" #include "nbl_include/nbl_def_hw.h" #include "nbl_include/nbl_def_resource.h" +#include "nbl_include/nbl_def_dispatch.h" #include "nbl_include/nbl_def_common.h" #include "nbl_core.h" @@ -47,7 +48,13 @@ struct nbl_adapter *nbl_core_init(struct pci_dev *pdev, ret = nbl_res_init_leonis(adapter); if (ret) goto res_init_fail; + + ret = nbl_disp_init(adapter); + if (ret) + goto disp_init_fail; return adapter; +disp_init_fail: + nbl_res_remove_leonis(adapter); res_init_fail: nbl_chan_remove_common(adapter); chan_init_fail: @@ -58,6 +65,7 @@ struct nbl_adapter *nbl_core_init(struct pci_dev *pdev, void nbl_core_remove(struct nbl_adapter *adapter) { + nbl_disp_remove(adapter); nbl_res_remove_leonis(adapter); nbl_chan_remove_common(adapter); nbl_hw_remove_leonis(adapter); -- 2.47.3