From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (unknown [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C60D5460AB; Fri, 17 Jan 2025 12:46:49 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C92BE42E64; Fri, 17 Jan 2025 12:45:25 +0100 (CET) Received: from smtpbguseast3.qq.com (smtpbguseast3.qq.com [54.243.244.52]) by mails.dpdk.org (Postfix) with ESMTP id C545F42E54 for ; Fri, 17 Jan 2025 12:45:23 +0100 (CET) X-QQ-mid: bizesmtp85t1737114318t6fdcgga X-QQ-Originating-IP: ddDLSEDBnNhbwun668seix7uVA+zFaUxyOxnUT4sxqE= Received: from DSK-zaiyuwang.trustnetic.com ( [36.24.187.167]) by bizesmtp.qq.com (ESMTP) with id ; Fri, 17 Jan 2025 19:45:17 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 9317770008958626555 From: Zaiyu Wang To: dev@dpdk.org Cc: Zaiyu Wang , Jiawen Wu Subject: [PATCH v3 06/15] net/ngbe: add add/remove/set mac addr ops for VF device Date: Fri, 17 Jan 2025 19:44:44 +0800 Message-Id: <20250117114455.15864-7-zaiyuwang@trustnetic.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20250117114455.15864-1-zaiyuwang@trustnetic.com> References: <20250109040227.1016-1-zaiyuwang@trustnetic.com> <20250117114455.15864-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: NBxOuQH3x7tH8Hlqwp5n3yay1S50m/2r0f6eZLqhVghFPUFMeuaQC8rx nuM1pdRkHzw3krrnbWZlrhODPQbamG6OnwBDzoUuOigm/ju0sevXWWrbc+QPxUuuC8Br3uN IcGX6lGpVdIir9BMLjIdgrfTgwWqOxUoUGCWe5rwEAJ3nTYXblTcz+FrRFCHKhHKJyDJoOX 9YEbCYzkUcfQtLVZx5E0WaUHRKm+nd0CSaOAvO3aLSjTFUanxcT5p2Ky4VfMeaRmXT80zwr r/sEr/HmegTlNd1RrmVviN7O0Zv4aS/9Z4Ex3bRqK518OqWrgERq7dUfaimxBChW//0fzWI 5Jj+2Kj4BXNEmueZlr8y2+YNlwsOlYSnRUjs9w0afNCPplrY7Siue112UNKjsJIIYJkXVnA DditMlYXP1jrQiruzRJDRTjr8xX6PJvLiArZPSAkPoCbHc0G3F6y8V0CWQp9UkXu3PIh97X VRcSi3+hVAGdCgi+88WdT+vnrFkrArJPfqDn2UoSXwyLPDDT/YxoKjIVYA3i39Az7Lyg3c+ Z885F28EbKC3ilvTeVRElmB99wPmgpQCKJA/r7y/u4xKRiwOdsx5e6T/i3crGbLlsxCLE0D MkdO3f4Sm+WS/8SowO8n+9TwRu5jBasAdbGj7fkeHaYN3jHBTTzvEcAwijI2boDKKpMK81w YV8JCmmEqWZPK/+kYKXsdS1NIHI4DrpyRaG5jtmmtBWZR84to8xwSJMs/8cwSiJ/e38oJ+T sCyC6SCLXsM/M0KzrD37AjHV0CVNOH8lesyP/HmxN7e2eLV3r+Wh4qkULWONDrix8E7JH6q NmqqDKtUFdgQ5WdVPhynaIqRfPDgn2ZBfpryBSnnSgA8hIFzjWQjDqwv1caqmKZ/xmtnise gs9I9INkIQHTEo8vOuLqrP/47GeaTGXmy/rORiufK8dXshVsgaLISI3J7CSazOIVfcoLz9Q tYC4nTgTfIq3zlm2FcOtaeH+Osji+JRO/C9mbEvIdFJrICeJmZ3QJubFPten9Pd5q3jO2Gi cn+iN1O8piMWIx1M1Q7cB8wYbfbikTl4K9rnhIgBGRXHOyrhNsnGFwCrzjdMiInF59kglbA g== X-QQ-XMRINFO: NS+P29fieYNw95Bth2bWPxk= 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 Generate a random MAC address if none was assigned by PF during the initialization of VF device. And support to add and remove MAC address. Signed-off-by: Zaiyu Wang --- doc/guides/nics/features/ngbe_vf.ini | 1 + drivers/net/ngbe/base/ngbe_type.h | 1 + drivers/net/ngbe/base/ngbe_vf.c | 83 +++++++++++++++ drivers/net/ngbe/base/ngbe_vf.h | 4 + drivers/net/ngbe/ngbe_ethdev_vf.c | 146 +++++++++++++++++++++++++++ 5 files changed, 235 insertions(+) diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini index 570b5ac25b..6f16f2b079 100644 --- a/doc/guides/nics/features/ngbe_vf.ini +++ b/doc/guides/nics/features/ngbe_vf.ini @@ -4,6 +4,7 @@ ; Refer to default.ini for the full list of available PMD features. ; [Features] +Unicast MAC filter = Y MTU update = Y Promiscuous mode = Y Allmulticast mode = Y diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index f780b92efa..7a3b52ffd4 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -335,6 +335,7 @@ struct ngbe_mac_info { /* RAR */ s32 (*set_rar)(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); + s32 (*set_uc_addr)(struct ngbe_hw *hw, u32 index, u8 *addr); s32 (*clear_rar)(struct ngbe_hw *hw, u32 index); s32 (*set_vmdq)(struct ngbe_hw *hw, u32 rar, u32 vmdq); s32 (*clear_vmdq)(struct ngbe_hw *hw, u32 rar, u32 vmdq); diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c index c0436c7b8a..47fee7e14d 100644 --- a/drivers/net/ngbe/base/ngbe_vf.c +++ b/drivers/net/ngbe/base/ngbe_vf.c @@ -191,6 +191,40 @@ STATIC s32 ngbevf_write_msg_read_ack(struct ngbe_hw *hw, u32 *msg, return mbx->read_posted(hw, retmsg, size, 0); } +/** + * ngbe_set_rar_vf - set device MAC address + * @hw: pointer to hardware structure + * @index: Receive address register to write + * @addr: Address to put into receive address register + * @vmdq: VMDq "set" or "pool" index + * @enable_addr: set flag that address is active + **/ +s32 ngbe_set_rar_vf(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr) +{ + u32 msgbuf[3]; + u8 *msg_addr = (u8 *)(&msgbuf[1]); + s32 ret_val; + + UNREFERENCED_PARAMETER(vmdq, enable_addr, index); + + memset(msgbuf, 0, 12); + msgbuf[0] = NGBE_VF_SET_MAC_ADDR; + memcpy(msg_addr, addr, 6); + ret_val = ngbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3); + + msgbuf[0] &= ~NGBE_VT_MSGTYPE_CTS; + + /* if nacked the address was rejected, use "perm_addr" */ + if (!ret_val && + (msgbuf[0] == (NGBE_VF_SET_MAC_ADDR | NGBE_VT_MSGTYPE_NACK))) { + ngbe_get_mac_addr_vf(hw, hw->mac.addr); + return NGBE_ERR_MBX; + } + + return ret_val; +} + /** * ngbevf_update_xcast_mode - Update Multicast mode * @hw: pointer to the HW structure @@ -228,6 +262,51 @@ s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode) return 0; } +/** + * ngbe_get_mac_addr_vf - Read device MAC address + * @hw: pointer to the HW structure + * @mac_addr: the MAC address + **/ +s32 ngbe_get_mac_addr_vf(struct ngbe_hw *hw, u8 *mac_addr) +{ + int i; + + for (i = 0; i < ETH_ADDR_LEN; i++) + mac_addr[i] = hw->mac.perm_addr[i]; + + return 0; +} + +s32 ngbevf_set_uc_addr_vf(struct ngbe_hw *hw, u32 index, u8 *addr) +{ + u32 msgbuf[3], msgbuf_chk; + u8 *msg_addr = (u8 *)(&msgbuf[1]); + s32 ret_val; + + memset(msgbuf, 0, sizeof(msgbuf)); + /* + * If index is one then this is the start of a new list and needs + * indication to the PF so it can do it's own list management. + * If it is zero then that tells the PF to just clear all of + * this VF's macvlans and there is no new list. + */ + msgbuf[0] |= index << NGBE_VT_MSGINFO_SHIFT; + msgbuf[0] |= NGBE_VF_SET_MACVLAN; + msgbuf_chk = msgbuf[0]; + if (addr) + memcpy(msg_addr, addr, 6); + + ret_val = ngbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3); + if (!ret_val) { + msgbuf[0] &= ~NGBE_VT_MSGTYPE_CTS; + + if (msgbuf[0] == (msgbuf_chk | NGBE_VT_MSGTYPE_NACK)) + return NGBE_ERR_OUT_OF_MEM; + } + + return ret_val; +} + /** * ngbevf_rlpml_set_vf - Set the maximum receive packet length * @hw: pointer to the HW structure @@ -359,8 +438,12 @@ s32 ngbe_init_ops_vf(struct ngbe_hw *hw) mac->reset_hw = ngbe_reset_hw_vf; mac->start_hw = ngbe_start_hw_vf; mac->stop_hw = ngbe_stop_hw_vf; + mac->get_mac_addr = ngbe_get_mac_addr_vf; mac->negotiate_api_version = ngbevf_negotiate_api_version; + /* RAR, Multicast */ + mac->set_rar = ngbe_set_rar_vf; + mac->set_uc_addr = ngbevf_set_uc_addr_vf; mac->update_xcast_mode = ngbevf_update_xcast_mode; mac->set_rlpml = ngbevf_rlpml_set_vf; diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h index a64de9d332..3f328a0221 100644 --- a/drivers/net/ngbe/base/ngbe_vf.h +++ b/drivers/net/ngbe/base/ngbe_vf.h @@ -16,6 +16,10 @@ s32 ngbe_init_hw_vf(struct ngbe_hw *hw); s32 ngbe_start_hw_vf(struct ngbe_hw *hw); s32 ngbe_reset_hw_vf(struct ngbe_hw *hw); s32 ngbe_stop_hw_vf(struct ngbe_hw *hw); +s32 ngbe_get_mac_addr_vf(struct ngbe_hw *hw, u8 *mac_addr); +s32 ngbe_set_rar_vf(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr); +s32 ngbevf_set_uc_addr_vf(struct ngbe_hw *hw, u32 index, u8 *addr); s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode); s32 ngbevf_rlpml_set_vf(struct ngbe_hw *hw, u16 max_size); int ngbevf_negotiate_api_version(struct ngbe_hw *hw, int api); diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c index f53c17cc82..e4a62a7df9 100644 --- a/drivers/net/ngbe/ngbe_ethdev_vf.c +++ b/drivers/net/ngbe/ngbe_ethdev_vf.c @@ -20,6 +20,7 @@ static int ngbevf_dev_close(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); /* * The set of PCI devices this driver supports (for VF) @@ -82,6 +83,22 @@ ngbevf_negotiate_api(struct ngbe_hw *hw) } } +static void +generate_random_mac_addr(struct rte_ether_addr *mac_addr) +{ + uint64_t random; + + /* Set Organizationally Unique Identifier (OUI) prefix. */ + mac_addr->addr_bytes[0] = 0x00; + mac_addr->addr_bytes[1] = 0x09; + mac_addr->addr_bytes[2] = 0xC0; + /* Force indication of locally assigned MAC address. */ + mac_addr->addr_bytes[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR; + /* Generate the last 3 bytes of the MAC address with a random number. */ + random = rte_rand(); + memcpy(&mac_addr->addr_bytes[3], &random, 3); +} + /* * Virtual Function device init */ @@ -92,6 +109,8 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev) uint32_t tc, tcs; struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); + struct rte_ether_addr *perm_addr = + (struct rte_ether_addr *)hw->mac.perm_addr; PMD_INIT_FUNC_TRACE(); @@ -150,6 +169,29 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev) return -ENOMEM; } + /* Generate a random MAC address, if none was assigned by PF. */ + if (rte_is_zero_ether_addr(perm_addr)) { + generate_random_mac_addr(perm_addr); + err = ngbe_set_rar_vf(hw, 1, perm_addr->addr_bytes, 0, 1); + if (err) { + rte_free(eth_dev->data->mac_addrs); + eth_dev->data->mac_addrs = NULL; + return err; + } + PMD_INIT_LOG(INFO, "\tVF MAC address not assigned by Host PF"); + PMD_INIT_LOG(INFO, "\tAssign randomly generated MAC address " + "%02x:%02x:%02x:%02x:%02x:%02x", + perm_addr->addr_bytes[0], + perm_addr->addr_bytes[1], + perm_addr->addr_bytes[2], + perm_addr->addr_bytes[3], + perm_addr->addr_bytes[4], + perm_addr->addr_bytes[5]); + } + + /* Copy the permanent MAC address */ + rte_ether_addr_copy(perm_addr, ð_dev->data->mac_addrs[0]); + /* reset the hardware with the new settings */ err = hw->mac.start_hw(hw); if (err) { @@ -263,12 +305,113 @@ ngbevf_dev_close(struct rte_eth_dev *dev) hw->mac.reset_hw(hw); + /** + * Remove the VF MAC address ro ensure + * that the VF traffic goes to the PF + * after stop, close and detach of the VF + **/ + ngbevf_remove_mac_addr(dev, 0); + + dev->rx_pkt_burst = NULL; + dev->tx_pkt_burst = NULL; + rte_free(dev->data->mac_addrs); dev->data->mac_addrs = NULL; return 0; } +static int +ngbevf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, + __rte_unused uint32_t index, + __rte_unused uint32_t pool) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + int err; + + /* + * On a VF, adding again the same MAC addr is not an idempotent + * operation. Trap this case to avoid exhausting the [very limited] + * set of PF resources used to store VF MAC addresses. + */ + if (memcmp(hw->mac.perm_addr, mac_addr, + sizeof(struct rte_ether_addr)) == 0) + return -1; + err = ngbevf_set_uc_addr_vf(hw, 2, mac_addr->addr_bytes); + if (err != 0) + PMD_DRV_LOG(ERR, "Unable to add MAC address " + "%02x:%02x:%02x:%02x:%02x:%02x - err=%d", + mac_addr->addr_bytes[0], + mac_addr->addr_bytes[1], + mac_addr->addr_bytes[2], + mac_addr->addr_bytes[3], + mac_addr->addr_bytes[4], + mac_addr->addr_bytes[5], + err); + return err; +} + +static void +ngbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct rte_ether_addr *perm_addr = + (struct rte_ether_addr *)hw->mac.perm_addr; + struct rte_ether_addr *mac_addr; + uint32_t i; + int err; + + /* + * The NGBE_VF_SET_MACVLAN command of the ngbe-pf driver does + * not support the deletion of a given MAC address. + * Instead, it imposes to delete all MAC addresses, then to add again + * all MAC addresses with the exception of the one to be deleted. + */ + (void)ngbevf_set_uc_addr_vf(hw, 0, NULL); + + /* + * Add again all MAC addresses, with the exception of the deleted one + * and of the permanent MAC address. + */ + for (i = 0, mac_addr = dev->data->mac_addrs; + i < hw->mac.num_rar_entries; i++, mac_addr++) { + /* Skip the deleted MAC address */ + if (i == index) + continue; + /* Skip NULL MAC addresses */ + if (rte_is_zero_ether_addr(mac_addr)) + continue; + /* Skip the permanent MAC address */ + if (memcmp(perm_addr, mac_addr, + sizeof(struct rte_ether_addr)) == 0) + continue; + err = ngbevf_set_uc_addr_vf(hw, 2, mac_addr->addr_bytes); + if (err != 0) + PMD_DRV_LOG(ERR, + "Adding again MAC address " + "%02x:%02x:%02x:%02x:%02x:%02x failed " + "err=%d", + mac_addr->addr_bytes[0], + mac_addr->addr_bytes[1], + mac_addr->addr_bytes[2], + mac_addr->addr_bytes[3], + mac_addr->addr_bytes[4], + mac_addr->addr_bytes[5], + err); + } +} + +static int +ngbevf_set_default_mac_addr(struct rte_eth_dev *dev, + struct rte_ether_addr *addr) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + + hw->mac.set_rar(hw, 0, (void *)addr, 0, 0); + + return 0; +} + static int ngbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) { @@ -402,6 +545,9 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = { .allmulticast_disable = ngbevf_dev_allmulticast_disable, .dev_infos_get = ngbevf_dev_info_get, .mtu_set = ngbevf_dev_set_mtu, + .mac_addr_add = ngbevf_add_mac_addr, + .mac_addr_remove = ngbevf_remove_mac_addr, + .mac_addr_set = ngbevf_set_default_mac_addr, }; RTE_PMD_REGISTER_PCI(net_ngbe_vf, rte_ngbevf_pmd); -- 2.21.0.windows.1