diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index d72137c00e..8ffc2ca1c7 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -5645,6 +5645,61 @@ handle_port_link_status(const char *cmd __rte_unused, return 0; } +int +rte_eth_hairpin_queue_peer_update(uint16_t peer_port, uint16_t peer_queue, + struct rte_hairpin_peer_info *cur_info, + struct rte_hairpin_peer_info *peer_info, + uint32_t direction) +{ + struct rte_eth_dev *dev; + + /* Current queue information is not mandatory. */ + if (peer_info == NULL) + return -EINVAL; + + /* No need to check the validity again. */ + dev = &rte_eth_devices[peer_port]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_update, + -ENOTSUP); + + return (*dev->dev_ops->hairpin_queue_peer_update)(dev, peer_queue, + cur_info, peer_info, direction); +} + +int +rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue, + struct rte_hairpin_peer_info *peer_info, + uint32_t direction) +{ + struct rte_eth_dev *dev; + + if (peer_info == NULL) + return -EINVAL; + + /* No need to check the validity again. */ + dev = &rte_eth_devices[cur_port]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_bind, + -ENOTSUP); + + return (*dev->dev_ops->hairpin_queue_peer_bind)(dev, cur_queue, + peer_info, direction); +} + +int +rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue, + uint32_t direction) +{ + struct rte_eth_dev *dev; + + /* No need to check the validity again. */ + dev = &rte_eth_devices[cur_port]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->hairpin_queue_peer_unbind, + -ENOTSUP); + + return (*dev->dev_ops->hairpin_queue_peer_unbind)(dev, cur_queue, + direction); +} + RTE_LOG_REGISTER(rte_eth_dev_logtype, lib.ethdev, INFO); RTE_INIT(ethdev_init_telemetry) diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h index 03e00d52fe..23a14540d2 100644 --- a/lib/librte_ethdev/rte_ethdev_driver.h +++ b/lib/librte_ethdev/rte_ethdev_driver.h @@ -21,6 +21,9 @@ extern "C" { #endif +/**< @internal Declaration of the hairpin peer queue information structure. */ +struct rte_hairpin_peer_info; + /* * Definitions of all functions exported by an Ethernet driver through the * generic structure of type *eth_dev_ops* supplied in the *rte_eth_dev* @@ -734,6 +737,21 @@ typedef int (*eth_hairpin_bind_t)(struct rte_eth_dev *dev, typedef int (*eth_hairpin_unbind_t)(struct rte_eth_dev *dev, uint16_t rx_port); +typedef int (*eth_hairpin_queue_peer_update_t) + (struct rte_eth_dev *dev, uint16_t peer_queue, + struct rte_hairpin_peer_info *current_info, + struct rte_hairpin_peer_info *peer_info, uint32_t direction); +/**< @internal Update and fetch peer queue information. */ + +typedef int (*eth_hairpin_queue_peer_bind_t) + (struct rte_eth_dev *dev, uint16_t cur_queue, + struct rte_hairpin_peer_info *peer_info, uint32_t direction); +/**< @internal Bind peer queue to the current queue with fetched information. */ + +typedef int (*eth_hairpin_queue_peer_unbind_t) + (struct rte_eth_dev *dev, uint16_t cur_queue, uint32_t direction); +/**< @internal Unbind peer queue from the current queue. */ + /** * @internal A structure containing the functions exported by an Ethernet driver. */ @@ -886,6 +904,12 @@ struct eth_dev_ops { /**< Bind all hairpin Tx queues of device to the peer port Rx queues. */ eth_hairpin_unbind_t hairpin_unbind; /**< Unbind all hairpin Tx queues from the peer port Rx queues. */ + eth_hairpin_queue_peer_update_t hairpin_queue_peer_update; + /**< Pass the current queue info and get the peer queue info. */ + eth_hairpin_queue_peer_bind_t hairpin_queue_peer_bind; + /**< Set up the connection between the pair of hairpin queues. */ + eth_hairpin_queue_peer_unbind_t hairpin_queue_peer_unbind; + /**< Disconnect the hairpin queues of a pair from each other. */ }; /** @@ -1241,6 +1265,83 @@ __rte_internal int rte_eth_dev_destroy(struct rte_eth_dev *ethdev, ethdev_uninit_t ethdev_uninit); +/** + * @internal + * Pass the current hairpin queue HW and/or SW information to the peer queue + * and fetch back the information of the peer queue. + * + * @param peer_port + * Peer port identifier of the Ethernet device. + * @param peer_queue + * Peer queue index of the port. + * @param cur_info + * Pointer to the current information structure. + * @param peer_info + * Pointer to the peer information, output. + * @param direction + * Direction to pass the information. + * positive - pass Tx queue information and get peer Rx queue information + * zero - pass Rx queue information and get peer Tx queue information + * + * @return + * Negative errno value on error, 0 on success. + */ +__rte_internal +int +rte_eth_hairpin_queue_peer_update(uint16_t peer_port, uint16_t peer_queue, + struct rte_hairpin_peer_info *cur_info, + struct rte_hairpin_peer_info *peer_info, + uint32_t direction); + +/** + * @internal + * Configure current hairpin queue with the peer information fetched to create + * the connection (bind) with peer queue in the specified direction. + * This function might need to be called twice to fully create the connections. + * + * @param cur_port + * Current port identifier of the Ethernet device. + * @param cur_queue + * Current queue index of the port. + * @param peer_info + * Pointer to the peer information, input. + * @param direction + * Direction to create the connection. + * positive - bind current Tx queue to peer Rx queue + * zero - bind current Rx queue to peer Tx queue + * + * @return + * Negative errno value on error, 0 on success. + */ +__rte_internal +int +rte_eth_hairpin_queue_peer_bind(uint16_t cur_port, uint16_t cur_queue, + struct rte_hairpin_peer_info *peer_info, + uint32_t direction); + +/** + * @internal + * Reset the current queue state and configuration to disconnect (unbind) it + * from the peer queue. + * This function might need to be called twice to disconnect each other. + * + * @param cur_port + * Current port identifier of the Ethernet device. + * @param cur_queue + * Current queue index of the port. + * @param direction + * Direction to destroy the connection. + * positive - unbind current Tx queue from peer Rx queue + * zero - unbind current Rx queue from peer Tx queue + * + * @return + * Negative errno value on error, 0 on success. + */ +__rte_internal +int +rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue, + uint32_t direction); + #ifdef __cplusplus } #endif diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map index a1e6897c92..f64c379ac2 100644 --- a/lib/librte_ethdev/rte_ethdev_version.map +++ b/lib/librte_ethdev/rte_ethdev_version.map @@ -258,6 +258,9 @@ INTERNAL { rte_eth_devargs_parse; rte_eth_dma_zone_free; rte_eth_dma_zone_reserve; + rte_eth_hairpin_queue_peer_bind; + rte_eth_hairpin_queue_peer_unbind; + rte_eth_hairpin_queue_peer_update; rte_eth_switch_domain_alloc; rte_eth_switch_domain_free; };