Due to a chip design limitation, only the VF supports the igb_uio driver. The PF does not.
The igb_uio driver requires allocating interrupts and configuring the PCIe MSI-X table before the driver's probe function is called. This pre-probe configuration is only possible on the VF due to the hardware limitation; the PF can only configure the MSI-X table during its probe process. Therefore, using igb_uio on the PF will fail. This commit clarifies this restriction. Signed-off-by: Dimon Zhao <[email protected]> --- doc/guides/nics/nbl.rst | 12 +++++ doc/guides/rel_notes/release_26_03.rst | 4 ++ drivers/net/nbl/nbl_core.c | 5 ++ drivers/net/nbl/nbl_dev/nbl_dev.c | 28 +++++++++-- drivers/net/nbl/nbl_dev/nbl_dev.h | 3 ++ drivers/net/nbl/nbl_dispatch.c | 49 +++++++++++++++++++ drivers/net/nbl/nbl_ethdev.c | 13 +++++ .../nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.c | 14 ++++++ .../nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.h | 9 ++++ .../nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c | 10 ++++ drivers/net/nbl/nbl_include/nbl_def_channel.h | 5 ++ .../net/nbl/nbl_include/nbl_def_dispatch.h | 3 ++ drivers/net/nbl/nbl_include/nbl_def_hw.h | 3 ++ .../net/nbl/nbl_include/nbl_def_resource.h | 3 ++ 14 files changed, 157 insertions(+), 4 deletions(-) diff --git a/doc/guides/nics/nbl.rst b/doc/guides/nics/nbl.rst index ba0a119dfd..646d0e3e16 100644 --- a/doc/guides/nics/nbl.rst +++ b/doc/guides/nics/nbl.rst @@ -101,3 +101,15 @@ Limitations or Known Issues 32-bit architectures are not supported. Windows and BSD are not supported yet. + +**igb_uio Driver Support** + +Due to chip design limitations, only the VF supports the ``igb_uio`` driver, +PF does not support this driver. + +**uio_pci_generic Driver Support** + +The ``uio_pci_generic`` driver is not supported on both PF and VF devices. +This is because the NBL PMD requires MSI-X interrupts to receive mailbox +messages, but the ``uio_pci_generic`` driver does not support MSI-X interrupts. + diff --git a/doc/guides/rel_notes/release_26_03.rst b/doc/guides/rel_notes/release_26_03.rst index 5e8437a758..adee6bf947 100644 --- a/doc/guides/rel_notes/release_26_03.rst +++ b/doc/guides/rel_notes/release_26_03.rst @@ -98,6 +98,10 @@ New Features * Added new APIs to convert between RSS type names and values. * Added new API call to obtain the global RSS string table. +* **Updated NBL driver.** + + * Added support for igb_uio driver on VF devices. + Removed Items ------------- diff --git a/drivers/net/nbl/nbl_core.c b/drivers/net/nbl/nbl_core.c index 313f8c5bd6..8ca3d184cf 100644 --- a/drivers/net/nbl/nbl_core.c +++ b/drivers/net/nbl/nbl_core.c @@ -41,6 +41,11 @@ int nbl_core_init(struct nbl_adapter *adapter, struct rte_eth_dev *eth_dev) common->eth_dev = eth_dev; nbl_init_func_caps(pci_dev, &adapter->caps); + if (pci_dev->id.device_id == NBL_DEVICE_ID_M18100_VF) + common->is_vf = true; + else + common->is_vf = false; + product_base_ops = nbl_core_get_product_ops(adapter->caps.product_type); /* every product's hw/chan/res layer has a great difference, so call their own init ops */ diff --git a/drivers/net/nbl/nbl_dev/nbl_dev.c b/drivers/net/nbl/nbl_dev/nbl_dev.c index 2b0413fb7c..ad06eee3d8 100644 --- a/drivers/net/nbl/nbl_dev/nbl_dev.c +++ b/drivers/net/nbl/nbl_dev/nbl_dev.c @@ -857,8 +857,12 @@ static void nbl_dev_mailbox_interrupt_handler(void *cn_arg) { struct nbl_dev_mgt *dev_mgt = (struct nbl_dev_mgt *)cn_arg; const struct nbl_channel_ops *chan_ops = NBL_DEV_MGT_TO_CHAN_OPS(dev_mgt); + struct nbl_dev_net_mgt *net_dev = NBL_DEV_MGT_TO_NET_DEV(dev_mgt); chan_ops->notify_interrupt(NBL_DEV_MGT_TO_CHAN_PRIV(dev_mgt)); + + if (net_dev->net_msix_mask_en) + rte_write32(net_dev->irq_data, net_dev->irq_enable_base); } static int nbl_dev_common_start(struct nbl_dev_mgt *dev_mgt) @@ -873,6 +877,7 @@ static int nbl_dev_common_start(struct nbl_dev_mgt *dev_mgt) u8 *mac; int ret; u16 priv_cnt = 0; + u16 global_vector_id = 0; board_info = &common->board_info; disp_ops->get_board_info(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), board_info); @@ -881,9 +886,22 @@ static int nbl_dev_common_start(struct nbl_dev_mgt *dev_mgt) disp_ops->clear_flow(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), net_dev->vsi_id); if (NBL_IS_NOT_COEXISTENCE(common)) { - ret = disp_ops->configure_msix_map(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), 0, 1, 0); - if (ret) - goto configure_msix_map_failed; + if (pci_dev->kdrv == RTE_PCI_KDRV_VFIO) { + ret = disp_ops->configure_msix_map(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), + 0, 1, 0); + if (ret) + goto configure_msix_map_failed; + } else { + ret = disp_ops->get_global_vector(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), + net_dev->vsi_id, 0, &global_vector_id); + if (ret) + goto get_global_vector_failed; + net_dev->irq_enable_base = + disp_ops->get_msix_irq_enable_info(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), + global_vector_id, &net_dev->irq_data); + net_dev->net_msix_mask_en = true; + rte_write32(net_dev->irq_data, net_dev->irq_enable_base); + } ret = disp_ops->enable_mailbox_irq(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt), 0, true); if (ret) @@ -960,7 +978,9 @@ static int nbl_dev_common_start(struct nbl_dev_mgt *dev_mgt) } enable_mailbox_irq_failed: if (NBL_IS_NOT_COEXISTENCE(common)) - disp_ops->destroy_msix_map(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt)); + if (pci_dev->kdrv == RTE_PCI_KDRV_VFIO) + disp_ops->destroy_msix_map(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt)); +get_global_vector_failed: configure_msix_map_failed: return ret; } diff --git a/drivers/net/nbl/nbl_dev/nbl_dev.h b/drivers/net/nbl/nbl_dev/nbl_dev.h index bfe2b06deb..230a983cf4 100644 --- a/drivers/net/nbl/nbl_dev/nbl_dev.h +++ b/drivers/net/nbl/nbl_dev/nbl_dev.h @@ -62,6 +62,9 @@ struct nbl_dev_net_mgt { bool hw_stats_inited; rte_thread_t tid; int fd[2]; + bool net_msix_mask_en; + u8 *irq_enable_base; + u32 irq_data; }; struct nbl_dev_mgt { diff --git a/drivers/net/nbl/nbl_dispatch.c b/drivers/net/nbl/nbl_dispatch.c index 52d37ba7fe..d2b55c0c25 100644 --- a/drivers/net/nbl/nbl_dispatch.c +++ b/drivers/net/nbl/nbl_dispatch.c @@ -80,6 +80,49 @@ static int nbl_disp_chan_enable_mailbox_irq_req(void *priv, u16 vector_id, bool return chan_ops->send_msg(NBL_DISP_MGT_TO_CHAN_PRIV(disp_mgt), &chan_send); } +static int nbl_disp_get_global_vector(void *priv, u16 vsi_id, + u16 local_vector_id, u16 *global_vector_id) +{ + struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv; + struct nbl_resource_ops *res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt); + u16 ret = 0; + + ret = NBL_OPS_CALL(res_ops->get_global_vector, + (NBL_DISP_MGT_TO_RES_PRIV(disp_mgt), + vsi_id, local_vector_id, global_vector_id)); + return ret; +} + +static int nbl_disp_chan_get_global_vector_req(void *priv, u16 vsi_id, + u16 local_vector_id, u16 *global_vector_id) +{ + struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv; + const struct nbl_channel_ops *chan_ops = NBL_DISP_MGT_TO_CHAN_OPS(disp_mgt); + struct nbl_chan_param_get_global_vector param = {0}; + struct nbl_chan_param_get_global_vector result = {0}; + struct nbl_chan_send_info chan_send; + int ret; + + param.vsi_id = vsi_id; + param.vector_id = local_vector_id; + + NBL_CHAN_SEND(chan_send, 0, NBL_CHAN_MSG_GET_GLOBAL_VECTOR, + ¶m, sizeof(param), &result, sizeof(result), 1); + ret = chan_ops->send_msg(NBL_DISP_MGT_TO_CHAN_PRIV(disp_mgt), &chan_send); + *global_vector_id = result.vector_id; + + return ret; +} + +static u8 *nbl_disp_get_msix_irq_enable_info(void *priv, u16 global_vector_id, u32 *irq_data) +{ + struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv; + struct nbl_resource_ops *res_ops = NBL_DISP_MGT_TO_RES_OPS(disp_mgt); + + return NBL_OPS_CALL(res_ops->get_msix_irq_enable_info, + (NBL_DISP_MGT_TO_RES_PRIV(disp_mgt), global_vector_id, irq_data)); +} + static int nbl_disp_alloc_txrx_queues(void *priv, u16 vsi_id, u16 queue_num) { struct nbl_dispatch_mgt *disp_mgt = (struct nbl_dispatch_mgt *)priv; @@ -1035,6 +1078,12 @@ do { \ NBL_DISP_CTRL_LVL_MGT, NBL_CHAN_MSG_MAILBOX_ENABLE_IRQ, \ nbl_disp_chan_enable_mailbox_irq_req, \ NULL); \ + NBL_DISP_SET_OPS(get_global_vector, nbl_disp_get_global_vector, \ + NBL_DISP_CTRL_LVL_MGT, NBL_CHAN_MSG_GET_GLOBAL_VECTOR, \ + nbl_disp_chan_get_global_vector_req, NULL); \ + NBL_DISP_SET_OPS(get_msix_irq_enable_info, nbl_disp_get_msix_irq_enable_info, \ + NBL_DISP_CTRL_LVL_NET, -1, \ + NULL, NULL); \ NBL_DISP_SET_OPS(alloc_txrx_queues, nbl_disp_alloc_txrx_queues, \ NBL_DISP_CTRL_LVL_MGT, \ NBL_CHAN_MSG_ALLOC_TXRX_QUEUES, \ diff --git a/drivers/net/nbl/nbl_ethdev.c b/drivers/net/nbl/nbl_ethdev.c index d269ea8058..f73808d877 100644 --- a/drivers/net/nbl/nbl_ethdev.c +++ b/drivers/net/nbl/nbl_ethdev.c @@ -88,6 +88,19 @@ static int nbl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, NBL_LOG(ERR, "Secondary process is not supported."); return -ENOTSUP; } + + if (pci_dev->kdrv == RTE_PCI_KDRV_UIO_GENERIC) { + NBL_LOG(ERR, "uio_pci_generic is not supported."); + return -ENOTSUP; + } + + if (pci_dev->kdrv == RTE_PCI_KDRV_IGB_UIO) { + if (pci_dev->id.device_id != NBL_DEVICE_ID_M18100_VF) { + NBL_LOG(ERR, "Only VF support igb_uio."); + return -ENOTSUP; + } + } + return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct nbl_adapter), nbl_eth_dev_init); } diff --git a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.c b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.c index 9e89a3be5f..a6fd60dfd7 100644 --- a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.c +++ b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.c @@ -138,6 +138,17 @@ static void nbl_hw_update_mailbox_queue_tail_ptr(void *priv, u16 tail_ptr, u8 tx rte_delay_us(NBL_NOTIFY_DELAY_MIN_TIME_FOR_REGS); } +static u8 *nbl_phy_get_msix_irq_enable_info(void *priv, u16 global_vector_id, u32 *irq_data) +{ + struct nbl_hw_mgt *hw_mgt = (struct nbl_hw_mgt *)priv; + struct nbl_msix_notify msix_notify = { 0 }; + + msix_notify.glb_msix_idx = global_vector_id; + memcpy(irq_data, &msix_notify, sizeof(msix_notify)); + + return (hw_mgt->hw_addr + NBL_PCOMPLETER_MSIX_NOTIRY_OFFSET); +} + const struct nbl_hw_ops nbl_hw_ops = { .update_tail_ptr = nbl_hw_update_tail_ptr, .get_tail_ptr = nbl_hw_get_tail_ptr, @@ -149,6 +160,9 @@ const struct nbl_hw_ops nbl_hw_ops = { .stop_mailbox_txq = nbl_hw_stop_mailbox_txq, .get_mailbox_rx_tail_ptr = nbl_hw_get_mailbox_rx_tail_ptr, .update_mailbox_queue_tail_ptr = nbl_hw_update_mailbox_queue_tail_ptr, + + /* irq */ + .get_msix_irq_enable_info = nbl_phy_get_msix_irq_enable_info, }; static int nbl_hw_setup_ops(struct nbl_hw_ops_tbl **hw_ops_tbl, diff --git a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.h b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.h index fc276e83d6..ae9800a285 100644 --- a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.h +++ b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis_snic.h @@ -50,4 +50,13 @@ struct nbl_mailbox_qinfo_cfg_dbg_tbl { u16 tx_tail_ptr; }; +#define NBL_PCOMPLETER_MSIX_NOTIRY_OFFSET (0x1020) + +struct nbl_msix_notify { + u32 glb_msix_idx:13; + u32 rsv1:3; + u32 mask:1; + u32 rsv2:15; +}; + #endif diff --git a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c index 5d40d4f5f8..189f8feb56 100644 --- a/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c +++ b/drivers/net/nbl/nbl_hw/nbl_hw_leonis/nbl_res_leonis.c @@ -115,9 +115,19 @@ static int nbl_get_xstats_names(__rte_unused void *priv, return 0; } +static u8 *nbl_res_get_msix_irq_enable_info(void *priv, u16 global_vector_id, u32 *irq_data) +{ + struct nbl_resource_mgt *res_mgt = (struct nbl_resource_mgt *)priv; + const struct nbl_hw_ops *hw_ops = NBL_RES_MGT_TO_HW_OPS(res_mgt); + + return hw_ops->get_msix_irq_enable_info(NBL_RES_MGT_TO_HW_PRIV(res_mgt), + global_vector_id, irq_data); +} + static struct nbl_resource_ops nbl_res_ops = { .get_hw_xstats_cnt = nbl_get_xstats_cnt, .get_hw_xstats_names = nbl_get_xstats_names, + .get_msix_irq_enable_info = nbl_res_get_msix_irq_enable_info, }; static bool is_ops_inited; diff --git a/drivers/net/nbl/nbl_include/nbl_def_channel.h b/drivers/net/nbl/nbl_include/nbl_def_channel.h index 55880737f1..d31e3bc772 100644 --- a/drivers/net/nbl/nbl_include/nbl_def_channel.h +++ b/drivers/net/nbl/nbl_include/nbl_def_channel.h @@ -314,6 +314,11 @@ struct nbl_chan_param_enable_mailbox_irq { bool enable_msix; }; +struct nbl_chan_param_get_global_vector { + u16 vsi_id; + u16 vector_id; +}; + struct nbl_chan_param_register_net_info { u16 pf_bdf; u64 vf_bar_start; diff --git a/drivers/net/nbl/nbl_include/nbl_def_dispatch.h b/drivers/net/nbl/nbl_include/nbl_def_dispatch.h index 45e7504a07..01d0967727 100644 --- a/drivers/net/nbl/nbl_include/nbl_def_dispatch.h +++ b/drivers/net/nbl/nbl_include/nbl_def_dispatch.h @@ -23,6 +23,9 @@ struct nbl_dispatch_ops { bool net_msix_mask_en); int (*destroy_msix_map)(void *priv); int (*enable_mailbox_irq)(void *p, u16 vector_id, bool enable_msix); + int (*get_global_vector)(void *priv, u16 vsi_id, + u16 local_vector_id, u16 *global_vector_id); + u8* (*get_msix_irq_enable_info)(void *priv, u16 global_vector_id, u32 *irq_data); void (*get_resource_pt_ops)(void *priv, struct nbl_resource_pt_ops *pt_ops, bool offload); int (*register_net)(void *priv, struct nbl_register_net_param *register_param, diff --git a/drivers/net/nbl/nbl_include/nbl_def_hw.h b/drivers/net/nbl/nbl_include/nbl_def_hw.h index 285ca98570..e9836e0120 100644 --- a/drivers/net/nbl/nbl_include/nbl_def_hw.h +++ b/drivers/net/nbl/nbl_include/nbl_def_hw.h @@ -22,6 +22,9 @@ struct nbl_hw_ops { void (*stop_mailbox_txq)(void *priv); uint16_t (*get_mailbox_rx_tail_ptr)(void *priv); void (*update_mailbox_queue_tail_ptr)(void *priv, uint16_t tail_ptr, uint8_t txrx); + + /* irq */ + u8* (*get_msix_irq_enable_info)(void *priv, u16 global_vector_id, u32 *irq_data); }; struct nbl_hw_ops_tbl { diff --git a/drivers/net/nbl/nbl_include/nbl_def_resource.h b/drivers/net/nbl/nbl_include/nbl_def_resource.h index 6935598789..3e6bb58f26 100644 --- a/drivers/net/nbl/nbl_include/nbl_def_resource.h +++ b/drivers/net/nbl/nbl_include/nbl_def_resource.h @@ -21,6 +21,9 @@ struct nbl_resource_ops { bool net_msix_mask_en); int (*destroy_msix_map)(void *priv, u16 func_id); int (*enable_mailbox_irq)(void *priv, u16 func_id, u16 vector_id, bool enable_msix); + int (*get_global_vector)(void *priv, u16 vsi_id, + u16 local_vector_id, u16 *global_vector_id); + u8* (*get_msix_irq_enable_info)(void *priv, u16 global_vector_id, u32 *irq_data); void (*get_resource_pt_ops)(void *priv, struct nbl_resource_pt_ops *pt_ops, bool offload); int (*register_net)(void *priv, struct nbl_register_net_param *register_param, -- 2.34.1

