From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id AFA93460C1; Mon, 20 Jan 2025 10:44:34 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1A01440A87; Mon, 20 Jan 2025 10:44:02 +0100 (CET) Received: from smtpbgsg1.qq.com (smtpbgsg1.qq.com [54.254.200.92]) by mails.dpdk.org (Postfix) with ESMTP id 9BEB7409FA for ; Mon, 20 Jan 2025 10:43:58 +0100 (CET) X-QQ-mid: bizesmtp86t1737366233tqjf8kv9 X-QQ-Originating-IP: fdp7WEA4hCO33YI/RXJZLuTR5Cppx2Chqfw1uiRvVj8= Received: from DSK-zaiyuwang.trustnetic.com ( [115.197.136.137]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 20 Jan 2025 17:43:52 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 11551911197035160284 From: Zaiyu Wang To: dev@dpdk.org Cc: Zaiyu Wang , Jiawen Wu Subject: [PATCH v4 09/15] net/ngbe: add interrupt support for VF device Date: Mon, 20 Jan 2025 17:42:35 +0800 Message-Id: <20250120094242.1844-10-zaiyuwang@trustnetic.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20250120094242.1844-1-zaiyuwang@trustnetic.com> References: <20250109040227.1016-1-zaiyuwang@trustnetic.com> <20250120094242.1844-1-zaiyuwang@trustnetic.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybglogicsvrgz:qybglogicsvrgz5a-1 X-QQ-XMAILINFO: M58CI+QHpTskEGgg4eD+AL4+mTIIeAkHG7MS9TV8OjCTCt5z2iiDpcVD am0/O0/vbueM8Rox4JU7HDaR9B4816QtuGBHOm0aToyhCy5xPbGIFFj7Og+Qp7D9JuK5xTQ UlGGg7BVOldmkWsUcUYytvzQ0Fn8y2qGiGGNawZ5/mUFnXp1ShDbNfHOFqhq6N2NNN752yY rEReHndv/Ry+vpLR5ByxmrZFAWm2mKNYywF75gI3I7Tcvz+8wE8G7sWf+0+ZPL5w1XIW3Hh ALs+e9Uow6oPbVqctHonNyaijZrrHk3uQ2O/NPTwNT7Lk4o/VQEgBsMb1JJpc2f+1kDUjwx PYSojNsZyvQxm+f3UjnZYCcM5IwOF+QDaTVuScPLOeSpOh0StbKZ3UgDdwWXgjpzHmXTti6 MPPudRyhzZ1riolRQSqRpJOIFx4OLdGtaDHpIISEwCCy6GGXWRHT98tPCNOfkD4JybyA+9P GHEPhE7r/LWz4oQNA/H52moDA3jWyjEa5AzgG+4uEf9sRltqliRRjAwwdvyr7RbQhU3fixT SXlMIe8Z6j8bdWzsyFZVMkYiwd5ESntj8KnejqsHY15GyHmk2goU2soOTjUTJ454x71knWM ivTRlWxQ++jeIpi9TvgDMvyH+INQVPGffB8jv5uCsT9kM1J2NXuopPkzz3JRDbD7QNKYRR5 YxVZbJ4nut7HVhWavapfosqZaM9Igl8EKpJj7Q/wg6CIi+tzeaQOhDPGAdJFHKDN/s6Yr0r 9IDn+0X0idTlf5ebNORY0Kfdu/5infUmk+gvUzFFJ+RTS83ghlcNKpuEpp26N8ki8Ta2Zj0 btXJM9glc+LXqKsSvwW47w2aMjDaiC91wfrpp2BYBZP9z3prdvrQJZ/7M94lpB+tIBM+T63 ualB4Bu/dUbg0pVAbf22ZWYlR10TZfl9ilsLdX2oBj1d2tMWa9Rq3FsYnao5WMB0sX7TYf9 F/bafxlYs0WFmt9RRcCgFHJo/Ha0G39TFHvJvRYNWJc3tgUw66051nK8/n2WBRypnRXoKCt 8atk9Na8BbwbfBjlfG X-QQ-XMRINFO: OD9hHCdaPRBwq3WW+NvGbIU= X-QQ-RECHKSPAM: 0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add VF device interrupt handler, support to enable and disable RX queue interrupt, and configure misx interrupt. Signed-off-by: Zaiyu Wang --- doc/guides/nics/features/ngbe_vf.ini | 1 + drivers/net/ngbe/ngbe_ethdev_vf.c | 230 +++++++++++++++++++++++++++ 2 files changed, 231 insertions(+) diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini index 441bf3bded..d6f2a1d726 100644 --- a/doc/guides/nics/features/ngbe_vf.ini +++ b/doc/guides/nics/features/ngbe_vf.ini @@ -5,6 +5,7 @@ ; [Features] Unicast MAC filter = Y +Rx interrupt = Y MTU update = Y Scattered Rx = Y LRO = Y diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c index a6048807cc..e1ba8b02d2 100644 --- a/drivers/net/ngbe/ngbe_ethdev_vf.c +++ b/drivers/net/ngbe/ngbe_ethdev_vf.c @@ -18,11 +18,15 @@ #define NGBEVF_PMD_NAME "rte_ngbevf_pmd" /* PMD name */ static int ngbevf_dev_close(struct rte_eth_dev *dev); +static void ngbevf_intr_disable(struct rte_eth_dev *dev); +static void ngbevf_intr_enable(struct rte_eth_dev *dev); static int ngbevf_vlan_offload_config(struct rte_eth_dev *dev, int mask); static void ngbevf_set_vfta_all(struct rte_eth_dev *dev, bool on); +static void ngbevf_configure_msix(struct rte_eth_dev *dev); static int ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev); static int ngbevf_dev_promiscuous_disable(struct rte_eth_dev *dev); static void ngbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index); +static void ngbevf_dev_interrupt_handler(void *param); /* * The set of PCI devices this driver supports (for VF) @@ -110,6 +114,7 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev) int err; uint32_t tc, tcs; struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + struct rte_intr_handle *intr_handle = pci_dev->intr_handle; struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); struct ngbe_vfta *shadow_vfta = NGBE_DEV_VFTA(eth_dev); struct ngbe_hwstrip *hwstrip = NGBE_DEV_HWSTRIP(eth_dev); @@ -173,6 +178,9 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev) /* init_mailbox_params */ hw->mbx.init_params(hw); + /* Disable the interrupts for VF */ + ngbevf_intr_disable(eth_dev); + hw->mac.num_rar_entries = 32; /* The MAX of the underlying PF */ err = hw->mac.reset_hw(hw); @@ -240,6 +248,11 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev) /* enter promiscuous mode */ ngbevf_dev_promiscuous_enable(eth_dev); + rte_intr_callback_register(intr_handle, + ngbevf_dev_interrupt_handler, eth_dev); + rte_intr_enable(intr_handle); + ngbevf_intr_enable(eth_dev); + PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x mac.type=%s", eth_dev->data->port_id, pci_dev->id.vendor_id, pci_dev->id.device_id, "ngbe_mac_sp_vf"); @@ -332,6 +345,39 @@ ngbevf_dev_info_get(struct rte_eth_dev *dev, return 0; } +static void +ngbevf_intr_disable(struct rte_eth_dev *dev) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + struct ngbe_hw *hw = ngbe_dev_hw(dev); + + PMD_INIT_FUNC_TRACE(); + + /* Clear interrupt mask to stop from interrupts being generated */ + wr32(hw, NGBE_VFIMS, NGBE_VFIMS_MASK); + + ngbe_flush(hw); + + /* Clear mask value. */ + intr->mask_misc = NGBE_VFIMS_MASK; +} + +static void +ngbevf_intr_enable(struct rte_eth_dev *dev) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + struct ngbe_hw *hw = ngbe_dev_hw(dev); + + PMD_INIT_FUNC_TRACE(); + + /* VF enable interrupt autoclean */ + wr32(hw, NGBE_VFIMC, NGBE_VFIMC_MASK); + + ngbe_flush(hw); + + intr->mask_misc = 0; +} + static int ngbevf_dev_configure(struct rte_eth_dev *dev) { @@ -370,6 +416,8 @@ static int ngbevf_dev_close(struct rte_eth_dev *dev) { struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = pci_dev->intr_handle; PMD_INIT_FUNC_TRACE(); if (rte_eal_process_type() != RTE_PROC_PRIMARY) @@ -387,9 +435,16 @@ ngbevf_dev_close(struct rte_eth_dev *dev) dev->rx_pkt_burst = NULL; dev->tx_pkt_burst = NULL; + /* Disable the interrupts for VF */ + ngbevf_intr_disable(dev); + rte_free(dev->data->mac_addrs); dev->data->mac_addrs = NULL; + rte_intr_disable(intr_handle); + rte_intr_callback_unregister(intr_handle, + ngbevf_dev_interrupt_handler, dev); + return 0; } @@ -492,6 +547,113 @@ ngbevf_vlan_offload_set(struct rte_eth_dev *dev, int mask) return 0; } +static int +ngbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id) +{ + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = pci_dev->intr_handle; + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + struct ngbe_hw *hw = ngbe_dev_hw(dev); + uint32_t vec = NGBE_MISC_VEC_ID; + + if (rte_intr_allow_others(intr_handle)) + vec = NGBE_RX_VEC_START; + intr->mask_misc &= ~(1 << vec); + RTE_SET_USED(queue_id); + wr32(hw, NGBE_VFIMC, ~intr->mask_misc); + + rte_intr_enable(intr_handle); + + return 0; +} + +static int +ngbevf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = pci_dev->intr_handle; + uint32_t vec = NGBE_MISC_VEC_ID; + + if (rte_intr_allow_others(intr_handle)) + vec = NGBE_RX_VEC_START; + intr->mask_misc |= (1 << vec); + RTE_SET_USED(queue_id); + wr32(hw, NGBE_VFIMS, intr->mask_misc); + + return 0; +} + +static void +ngbevf_set_ivar_map(struct ngbe_hw *hw, int8_t direction, + uint8_t queue, uint8_t msix_vector) +{ + uint32_t tmp, idx; + + if (direction == -1) { + /* other causes */ + msix_vector |= NGBE_VFIVAR_VLD; + tmp = rd32(hw, NGBE_VFIVARMISC); + tmp &= ~0xFF; + tmp |= msix_vector; + wr32(hw, NGBE_VFIVARMISC, tmp); + } else { + /* rx or tx cause */ + /* Workaround for ICR lost */ + idx = ((16 * (queue & 1)) + (8 * direction)); + tmp = rd32(hw, NGBE_VFIVAR(queue >> 1)); + tmp &= ~(0xFF << idx); + tmp |= (msix_vector << idx); + wr32(hw, NGBE_VFIVAR(queue >> 1), tmp); + } +} + +static void +ngbevf_configure_msix(struct rte_eth_dev *dev) +{ + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = pci_dev->intr_handle; + struct ngbe_hw *hw = ngbe_dev_hw(dev); + uint32_t q_idx; + uint32_t vector_idx = NGBE_MISC_VEC_ID; + uint32_t base = NGBE_MISC_VEC_ID; + + /* Configure VF other cause ivar */ + ngbevf_set_ivar_map(hw, -1, 1, vector_idx); + + /* won't configure msix register if no mapping is done + * between intr vector and event fd. + */ + if (!rte_intr_dp_is_en(intr_handle)) + return; + + if (rte_intr_allow_others(intr_handle)) { + base = NGBE_RX_VEC_START; + vector_idx = NGBE_RX_VEC_START; + } + + /* Configure all RX queues of VF */ + for (q_idx = 0; q_idx < dev->data->nb_rx_queues; q_idx++) { + /* Force all queue use vector 0, + * as NGBE_VF_MAXMSIVECOTR = 1 + */ + ngbevf_set_ivar_map(hw, 0, q_idx, vector_idx); + rte_intr_vec_list_index_set(intr_handle, q_idx, + vector_idx); + if (vector_idx < base + rte_intr_nb_efd_get(intr_handle) + - 1) + vector_idx++; + } + + /* As RX queue setting above show, all queues use the vector 0. + * Set only the ITR value of NGBE_MISC_VEC_ID. + */ + wr32(hw, NGBE_ITR(NGBE_MISC_VEC_ID), + NGBE_ITR_IVAL(NGBE_QUEUE_ITR_INTERVAL_DEFAULT) + | NGBE_ITR_WRDSA); +} + static int ngbevf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, __rte_unused uint32_t index, @@ -705,6 +867,72 @@ ngbevf_dev_allmulticast_disable(struct rte_eth_dev *dev) return ret; } +static void ngbevf_mbx_process(struct rte_eth_dev *dev) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + u32 in_msg = 0; + + /* peek the message first */ + in_msg = rd32(hw, NGBE_VFMBX); + + /* PF reset VF event */ + if (in_msg == NGBE_PF_CONTROL_MSG) { + /* dummy mbx read to ack pf */ + if (ngbe_read_mbx(hw, &in_msg, 1, 0)) + return; + rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, + NULL); + } +} + +static int +ngbevf_dev_interrupt_get_status(struct rte_eth_dev *dev) +{ + uint32_t eicr; + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + + ngbevf_intr_disable(dev); + + /* read-on-clear nic registers here */ + eicr = rd32(hw, NGBE_VFICR); + intr->flags = 0; + + /* only one misc vector supported - mailbox */ + eicr &= NGBE_VFICR_MASK; + /* Workaround for ICR lost */ + intr->flags |= NGBE_FLAG_MAILBOX; + + /* To avoid compiler warnings set eicr to used. */ + RTE_SET_USED(eicr); + + return 0; +} + +static int +ngbevf_dev_interrupt_action(struct rte_eth_dev *dev) +{ + struct ngbe_interrupt *intr = ngbe_dev_intr(dev); + + if (intr->flags & NGBE_FLAG_MAILBOX) { + ngbevf_mbx_process(dev); + intr->flags &= ~NGBE_FLAG_MAILBOX; + } + + ngbevf_intr_enable(dev); + + return 0; +} + +static void +ngbevf_dev_interrupt_handler(void *param) +{ + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; + + ngbevf_dev_interrupt_get_status(dev); + ngbevf_dev_interrupt_action(dev); +} + /* * dev_ops for virtual function, bare necessities for basic vf * operation have been implemented @@ -720,6 +948,8 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = { .vlan_filter_set = ngbevf_vlan_filter_set, .vlan_strip_queue_set = ngbevf_vlan_strip_queue_set, .vlan_offload_set = ngbevf_vlan_offload_set, + .rx_queue_intr_enable = ngbevf_dev_rx_queue_intr_enable, + .rx_queue_intr_disable = ngbevf_dev_rx_queue_intr_disable, .mac_addr_add = ngbevf_add_mac_addr, .mac_addr_remove = ngbevf_remove_mac_addr, .mac_addr_set = ngbevf_set_default_mac_addr, -- 2.21.0.windows.1