src/dpdk/drivers/net/mlx5/mlx5_trigger.c
static int
mlx5_hairpin_unbind_single_port(struct rte_eth_dev *dev, uint16_t rx_port)
{
	struct mlx5_priv *priv = dev->data->dev_private;
	struct mlx5_txq_ctrl *txq_ctrl;
	uint32_t i;
	int ret;
	uint16_t cur_port = priv->dev_data->port_id;

	if (mlx5_eth_find_next(rx_port, priv->pci_dev) != rx_port) {
		rte_errno = ENODEV;
		DRV_LOG(ERR, "Rx port %u does not belong to mlx5", rx_port);
		return -rte_errno;
	}
	for (i = 0; i != priv->txqs_n; i++) {
		uint16_t rx_queue;

		txq_ctrl = mlx5_txq_get(dev, i);
		if (txq_ctrl == NULL)
			continue;
		if (txq_ctrl->type != MLX5_TXQ_TYPE_HAIRPIN) {
			mlx5_txq_release(dev, i);
			continue;
		}
		if (txq_ctrl->hairpin_conf.peers[0].port != rx_port) {
			mlx5_txq_release(dev, i);
			continue;
		}
		/* Indeed, only the first used queue needs to be checked. */
		if (txq_ctrl->hairpin_conf.manual_bind == 0) {
			if (cur_port != rx_port) {
				rte_errno = EINVAL;
				DRV_LOG(ERR, "port %u and port %u are in"
					" auto-bind mode", cur_port, rx_port);
				mlx5_txq_release(dev, i);
				return -rte_errno;
			} else {
				return 0;
			}
		}
		rx_queue = txq_ctrl->hairpin_conf.peers[0].queue;
		mlx5_txq_release(dev, i);
		ret = rte_eth_hairpin_queue_peer_unbind(rx_port, rx_queue, 0);
		if (ret) {
			DRV_LOG(ERR, "port %u Rx queue %d unbind - failure",
				rx_port, rx_queue);
			return ret;
		}
		ret = mlx5_hairpin_queue_peer_unbind(dev, i, 1);
		if (ret) {
			DRV_LOG(ERR, "port %u Tx queue %d unbind - failure",
				cur_port, i);
			return ret;
		}
	}
	return 0;
}
/*
 * Unbind the hairpin port pair, HW configuration of both devices will be clear
 * and status will be reset for all the queues used between the them.
 * This function only supports to unbind the Tx from one Rx.
 *
 * @param dev
 *   Pointer to Ethernet device structure.
 * @param rx_port
 *   Port identifier of the Rx port.
 *
 * @return
 *   0 on success, a negative errno value otherwise and rte_errno is set.
 */
Unbind the hairpin port pair, HW configuration of both devices will be clear
and status will be reset for all the queues used between the them.
This function only supports to unbind the Tx from one Rx.

@param dev
Pointer to Ethernet device structure.
@param rx_port
Port identifier of the Rx port.

@return
0 on success, a negative errno value otherwise and rte_errno is set.
Unbind the hairpin port pair HW configuration of both devices will be clear and status will be reset for all the queues used between the them . This function only supports to unbind the Tx from one Rx . @param dev Pointer to Ethernet device structure . @param rx_port Port identifier of the Rx port . @return 0 on success a negative errno value otherwise and rte_errno is set .
static int
mlx5_hairpin_unbind_single_port(struct rte_eth_dev *dev, uint16_t rx_port)
{
	struct mlx5_priv *priv = dev->data->dev_private;
	struct mlx5_txq_ctrl *txq_ctrl;
	uint32_t i;
	int ret;
	uint16_t cur_port = priv->dev_data->port_id;
	if (mlx5_eth_find_next(rx_port, priv->pci_dev) != rx_port) {
		rte_errno = ENODEV;
		DRV_LOG(ERR, "Rx port %u does not belong to mlx5", rx_port);
		return -rte_errno;
	}
	for (i = 0; i != priv->txqs_n; i++) {
		uint16_t rx_queue;
		txq_ctrl = mlx5_txq_get(dev, i);
		if (txq_ctrl == NULL)
			continue;
		if (txq_ctrl->type != MLX5_TXQ_TYPE_HAIRPIN) {
			mlx5_txq_release(dev, i);
			continue;
		}
		if (txq_ctrl->hairpin_conf.peers[0].port != rx_port) {
			mlx5_txq_release(dev, i);
			continue;
		}
		if (txq_ctrl->hairpin_conf.manual_bind == 0) {
			if (cur_port != rx_port) {
				rte_errno = EINVAL;
				DRV_LOG(ERR, "port %u and port %u are in"
					" auto-bind mode", cur_port, rx_port);
				mlx5_txq_release(dev, i);
				return -rte_errno;
			} else {
				return 0;
			}
		}
		rx_queue = txq_ctrl->hairpin_conf.peers[0].queue;
		mlx5_txq_release(dev, i);
		ret = rte_eth_hairpin_queue_peer_unbind(rx_port, rx_queue, 0);
		if (ret) {
			DRV_LOG(ERR, "port %u Rx queue %d unbind - failure",
				rx_port, rx_queue);
			return ret;
		}
		ret = mlx5_hairpin_queue_peer_unbind(dev, i, 1);
		if (ret) {
			DRV_LOG(ERR, "port %u Tx queue %d unbind - failure",
				cur_port, i);
			return ret;
		}
	}
	return 0;
}
static int mlx5_hairpin_unbind_single_port ( struct rte_eth_dev * dev , uint16_t rx_port ) { struct mlx5_priv * priv = dev -> data -> dev_private ; struct mlx5_txq_ctrl * txq_ctrl ; uint32_t i ; int ret ; uint16_t cur_port = priv -> dev_data -> port_id ; if ( mlx5_eth_find_next ( rx_port , priv -> pci_dev ) != rx_port ) { rte_errno = ENODEV ; DRV_LOG ( ERR , " " , rx_port ) ; return - rte_errno ; } for ( i = 0 ; i != priv -> txqs_n ; i ++ ) { uint16_t rx_queue ; txq_ctrl = mlx5_txq_get ( dev , i ) ; if ( txq_ctrl == NULL ) continue ; if ( txq_ctrl -> type != MLX5_TXQ_TYPE_HAIRPIN ) { mlx5_txq_release ( dev , i ) ; continue ; } if ( txq_ctrl -> hairpin_conf . peers [ 0 ] . port != rx_port ) { mlx5_txq_release ( dev , i ) ; continue ; } if ( txq_ctrl -> hairpin_conf . manual_bind == 0 ) { if ( cur_port != rx_port ) { rte_errno = EINVAL ; DRV_LOG ( ERR , " " " " , cur_port , rx_port ) ; mlx5_txq_release ( dev , i ) ; return - rte_errno ; } else { return 0 ; } } rx_queue = txq_ctrl -> hairpin_conf . peers [ 0 ] . queue ; mlx5_txq_release ( dev , i ) ; ret = rte_eth_hairpin_queue_peer_unbind ( rx_port , rx_queue , 0 ) ; if ( ret ) { DRV_LOG ( ERR , " " , rx_port , rx_queue ) ; return ret ; } ret = mlx5_hairpin_queue_peer_unbind ( dev , i , 1 ) ; if ( ret ) { DRV_LOG ( ERR , " " , cur_port , i ) ; return ret ; } } return 0 ; }
Unbind the hairpin port pair, HW configuration of both devices will be clear
 and status will be reset for all the queues used between the them.
Unbind the hairpin port pair HW configuration of both devices will be clear and status will be reset for all the queues used between the them .
/* Indeed, only the first used queue needs to be checked. */