src/dpdk/drivers/net/mlx5/mlx5_trigger.c
static int
mlx5_hairpin_auto_bind(struct rte_eth_dev *dev)
{
	struct mlx5_priv *priv = dev->data->dev_private;
	struct mlx5_devx_modify_sq_attr sq_attr = { 0 };
	struct mlx5_devx_modify_rq_attr rq_attr = { 0 };
	struct mlx5_txq_ctrl *txq_ctrl;
	struct mlx5_rxq_ctrl *rxq_ctrl;
	struct mlx5_devx_obj *sq;
	struct mlx5_devx_obj *rq;
	unsigned int i;
	int ret = 0;
	bool need_auto = false;
	uint16_t self_port = dev->data->port_id;

	for (i = 0; i != priv->txqs_n; ++i) {
		txq_ctrl = mlx5_txq_get(dev, i);
		if (!txq_ctrl)
			continue;
		if (txq_ctrl->type != MLX5_TXQ_TYPE_HAIRPIN) {
			mlx5_txq_release(dev, i);
			continue;
		}
		if (txq_ctrl->hairpin_conf.peers[0].port != self_port)
			continue;
		if (txq_ctrl->hairpin_conf.manual_bind) {
			mlx5_txq_release(dev, i);
			return 0;
		}
		need_auto = true;
		mlx5_txq_release(dev, i);
	}
	if (!need_auto)
		return 0;
	for (i = 0; i != priv->txqs_n; ++i) {
		txq_ctrl = mlx5_txq_get(dev, i);
		if (!txq_ctrl)
			continue;
		if (txq_ctrl->type != MLX5_TXQ_TYPE_HAIRPIN) {
			mlx5_txq_release(dev, i);
			continue;
		}
		/* Skip hairpin queues with other peer ports. */
		if (txq_ctrl->hairpin_conf.peers[0].port != self_port)
			continue;
		if (!txq_ctrl->obj) {
			rte_errno = ENOMEM;
			DRV_LOG(ERR, "port %u no txq object found: %d",
				dev->data->port_id, i);
			mlx5_txq_release(dev, i);
			return -rte_errno;
		}
		sq = txq_ctrl->obj->sq;
		rxq_ctrl = mlx5_rxq_get(dev,
					txq_ctrl->hairpin_conf.peers[0].queue);
		if (!rxq_ctrl) {
			mlx5_txq_release(dev, i);
			rte_errno = EINVAL;
			DRV_LOG(ERR, "port %u no rxq object found: %d",
				dev->data->port_id,
				txq_ctrl->hairpin_conf.peers[0].queue);
			return -rte_errno;
		}
		if (rxq_ctrl->type != MLX5_RXQ_TYPE_HAIRPIN ||
		    rxq_ctrl->hairpin_conf.peers[0].queue != i) {
			rte_errno = ENOMEM;
			DRV_LOG(ERR, "port %u Tx queue %d can't be binded to "
				"Rx queue %d", dev->data->port_id,
				i, txq_ctrl->hairpin_conf.peers[0].queue);
			goto error;
		}
		rq = rxq_ctrl->obj->rq;
		if (!rq) {
			rte_errno = ENOMEM;
			DRV_LOG(ERR, "port %u hairpin no matching rxq: %d",
				dev->data->port_id,
				txq_ctrl->hairpin_conf.peers[0].queue);
			goto error;
		}
		sq_attr.state = MLX5_SQC_STATE_RDY;
		sq_attr.sq_state = MLX5_SQC_STATE_RST;
		sq_attr.hairpin_peer_rq = rq->id;
		sq_attr.hairpin_peer_vhca = priv->config.hca_attr.vhca_id;
		ret = mlx5_devx_cmd_modify_sq(sq, &sq_attr);
		if (ret)
			goto error;
		rq_attr.state = MLX5_SQC_STATE_RDY;
		rq_attr.rq_state = MLX5_SQC_STATE_RST;
		rq_attr.hairpin_peer_sq = sq->id;
		rq_attr.hairpin_peer_vhca = priv->config.hca_attr.vhca_id;
		ret = mlx5_devx_cmd_modify_rq(rq, &rq_attr);
		if (ret)
			goto error;
		/* Qs with auto-bind will be destroyed directly. */
		rxq_ctrl->hairpin_status = 1;
		txq_ctrl->hairpin_status = 1;
		mlx5_txq_release(dev, i);
		mlx5_rxq_release(dev, txq_ctrl->hairpin_conf.peers[0].queue);
	}
	return 0;
error:
	mlx5_txq_release(dev, i);
	mlx5_rxq_release(dev, txq_ctrl->hairpin_conf.peers[0].queue);
	return -rte_errno;
}
/**
 * Binds Tx queues to Rx queues for hairpin.
 *
 * Binds Tx queues to the target Rx queues.
 *
 * @param dev
 *   Pointer to Ethernet device structure.
 *
 * @return
 *   0 on success, a negative errno value otherwise and rte_errno is set.
 */
Binds Tx queues to Rx queues for hairpin.
Binds Tx queues to the target Rx queues.

@param dev
Pointer to Ethernet device structure.

@return
0 on success, a negative errno value otherwise and rte_errno is set.
Binds Tx queues to Rx queues for hairpin . Binds Tx queues to the target Rx queues . @param dev Pointer to Ethernet device structure . @return 0 on success a negative errno value otherwise and rte_errno is set .
static int
mlx5_hairpin_auto_bind(struct rte_eth_dev *dev)
{
	struct mlx5_priv *priv = dev->data->dev_private;
	struct mlx5_devx_modify_sq_attr sq_attr = { 0 };
	struct mlx5_devx_modify_rq_attr rq_attr = { 0 };
	struct mlx5_txq_ctrl *txq_ctrl;
	struct mlx5_rxq_ctrl *rxq_ctrl;
	struct mlx5_devx_obj *sq;
	struct mlx5_devx_obj *rq;
	unsigned int i;
	int ret = 0;
	bool need_auto = false;
	uint16_t self_port = dev->data->port_id;
	for (i = 0; i != priv->txqs_n; ++i) {
		txq_ctrl = mlx5_txq_get(dev, i);
		if (!txq_ctrl)
			continue;
		if (txq_ctrl->type != MLX5_TXQ_TYPE_HAIRPIN) {
			mlx5_txq_release(dev, i);
			continue;
		}
		if (txq_ctrl->hairpin_conf.peers[0].port != self_port)
			continue;
		if (txq_ctrl->hairpin_conf.manual_bind) {
			mlx5_txq_release(dev, i);
			return 0;
		}
		need_auto = true;
		mlx5_txq_release(dev, i);
	}
	if (!need_auto)
		return 0;
	for (i = 0; i != priv->txqs_n; ++i) {
		txq_ctrl = mlx5_txq_get(dev, i);
		if (!txq_ctrl)
			continue;
		if (txq_ctrl->type != MLX5_TXQ_TYPE_HAIRPIN) {
			mlx5_txq_release(dev, i);
			continue;
		}
		if (txq_ctrl->hairpin_conf.peers[0].port != self_port)
			continue;
		if (!txq_ctrl->obj) {
			rte_errno = ENOMEM;
			DRV_LOG(ERR, "port %u no txq object found: %d",
				dev->data->port_id, i);
			mlx5_txq_release(dev, i);
			return -rte_errno;
		}
		sq = txq_ctrl->obj->sq;
		rxq_ctrl = mlx5_rxq_get(dev,
					txq_ctrl->hairpin_conf.peers[0].queue);
		if (!rxq_ctrl) {
			mlx5_txq_release(dev, i);
			rte_errno = EINVAL;
			DRV_LOG(ERR, "port %u no rxq object found: %d",
				dev->data->port_id,
				txq_ctrl->hairpin_conf.peers[0].queue);
			return -rte_errno;
		}
		if (rxq_ctrl->type != MLX5_RXQ_TYPE_HAIRPIN ||
		    rxq_ctrl->hairpin_conf.peers[0].queue != i) {
			rte_errno = ENOMEM;
			DRV_LOG(ERR, "port %u Tx queue %d can't be binded to "
				"Rx queue %d", dev->data->port_id,
				i, txq_ctrl->hairpin_conf.peers[0].queue);
			goto error;
		}
		rq = rxq_ctrl->obj->rq;
		if (!rq) {
			rte_errno = ENOMEM;
			DRV_LOG(ERR, "port %u hairpin no matching rxq: %d",
				dev->data->port_id,
				txq_ctrl->hairpin_conf.peers[0].queue);
			goto error;
		}
		sq_attr.state = MLX5_SQC_STATE_RDY;
		sq_attr.sq_state = MLX5_SQC_STATE_RST;
		sq_attr.hairpin_peer_rq = rq->id;
		sq_attr.hairpin_peer_vhca = priv->config.hca_attr.vhca_id;
		ret = mlx5_devx_cmd_modify_sq(sq, &sq_attr);
		if (ret)
			goto error;
		rq_attr.state = MLX5_SQC_STATE_RDY;
		rq_attr.rq_state = MLX5_SQC_STATE_RST;
		rq_attr.hairpin_peer_sq = sq->id;
		rq_attr.hairpin_peer_vhca = priv->config.hca_attr.vhca_id;
		ret = mlx5_devx_cmd_modify_rq(rq, &rq_attr);
		if (ret)
			goto error;
		rxq_ctrl->hairpin_status = 1;
		txq_ctrl->hairpin_status = 1;
		mlx5_txq_release(dev, i);
		mlx5_rxq_release(dev, txq_ctrl->hairpin_conf.peers[0].queue);
	}
	return 0;
error:
	mlx5_txq_release(dev, i);
	mlx5_rxq_release(dev, txq_ctrl->hairpin_conf.peers[0].queue);
	return -rte_errno;
}
static int mlx5_hairpin_auto_bind ( struct rte_eth_dev * dev ) { struct mlx5_priv * priv = dev -> data -> dev_private ; struct mlx5_devx_modify_sq_attr sq_attr = { 0 } ; struct mlx5_devx_modify_rq_attr rq_attr = { 0 } ; struct mlx5_txq_ctrl * txq_ctrl ; struct mlx5_rxq_ctrl * rxq_ctrl ; struct mlx5_devx_obj * sq ; struct mlx5_devx_obj * rq ; unsigned int i ; int ret = 0 ; bool need_auto = false ; uint16_t self_port = dev -> data -> port_id ; for ( i = 0 ; i != priv -> txqs_n ; ++ i ) { txq_ctrl = mlx5_txq_get ( dev , i ) ; if ( ! txq_ctrl ) continue ; if ( txq_ctrl -> type != MLX5_TXQ_TYPE_HAIRPIN ) { mlx5_txq_release ( dev , i ) ; continue ; } if ( txq_ctrl -> hairpin_conf . peers [ 0 ] . port != self_port ) continue ; if ( txq_ctrl -> hairpin_conf . manual_bind ) { mlx5_txq_release ( dev , i ) ; return 0 ; } need_auto = true ; mlx5_txq_release ( dev , i ) ; } if ( ! need_auto ) return 0 ; for ( i = 0 ; i != priv -> txqs_n ; ++ i ) { txq_ctrl = mlx5_txq_get ( dev , i ) ; if ( ! txq_ctrl ) continue ; if ( txq_ctrl -> type != MLX5_TXQ_TYPE_HAIRPIN ) { mlx5_txq_release ( dev , i ) ; continue ; } if ( txq_ctrl -> hairpin_conf . peers [ 0 ] . port != self_port ) continue ; if ( ! txq_ctrl -> obj ) { rte_errno = ENOMEM ; DRV_LOG ( ERR , " " , dev -> data -> port_id , i ) ; mlx5_txq_release ( dev , i ) ; return - rte_errno ; } sq = txq_ctrl -> obj -> sq ; rxq_ctrl = mlx5_rxq_get ( dev , txq_ctrl -> hairpin_conf . peers [ 0 ] . queue ) ; if ( ! rxq_ctrl ) { mlx5_txq_release ( dev , i ) ; rte_errno = EINVAL ; DRV_LOG ( ERR , " " , dev -> data -> port_id , txq_ctrl -> hairpin_conf . peers [ 0 ] . queue ) ; return - rte_errno ; } if ( rxq_ctrl -> type != MLX5_RXQ_TYPE_HAIRPIN || rxq_ctrl -> hairpin_conf . peers [ 0 ] . queue != i ) { rte_errno = ENOMEM ; DRV_LOG ( ERR , " " " " , dev -> data -> port_id , i , txq_ctrl -> hairpin_conf . peers [ 0 ] . queue ) ; goto error ; } rq = rxq_ctrl -> obj -> rq ; if ( ! rq ) { rte_errno = ENOMEM ; DRV_LOG ( ERR , " " , dev -> data -> port_id , txq_ctrl -> hairpin_conf . peers [ 0 ] . queue ) ; goto error ; } sq_attr . state = MLX5_SQC_STATE_RDY ; sq_attr . sq_state = MLX5_SQC_STATE_RST ; sq_attr . hairpin_peer_rq = rq -> id ; sq_attr . hairpin_peer_vhca = priv -> config . hca_attr . vhca_id ; ret = mlx5_devx_cmd_modify_sq ( sq , & sq_attr ) ; if ( ret ) goto error ; rq_attr . state = MLX5_SQC_STATE_RDY ; rq_attr . rq_state = MLX5_SQC_STATE_RST ; rq_attr . hairpin_peer_sq = sq -> id ; rq_attr . hairpin_peer_vhca = priv -> config . hca_attr . vhca_id ; ret = mlx5_devx_cmd_modify_rq ( rq , & rq_attr ) ; if ( ret ) goto error ; rxq_ctrl -> hairpin_status = 1 ; txq_ctrl -> hairpin_status = 1 ; mlx5_txq_release ( dev , i ) ; mlx5_rxq_release ( dev , txq_ctrl -> hairpin_conf . peers [ 0 ] . queue ) ; } return 0 ; error : mlx5_txq_release ( dev , i ) ; mlx5_rxq_release ( dev , txq_ctrl -> hairpin_conf . peers [ 0 ] . queue ) ; return - rte_errno ; }
Binds Tx queues to Rx queues for hairpin.
Binds Tx queues to Rx queues for hairpin .
/* Skip hairpin queues with other peer ports. */ /* Qs with auto-bind will be destroyed directly. */