> -----Original Message----- > From: Ori Kam <or...@mellanox.com> > Sent: Thursday, September 26, 2019 9:29 > To: Matan Azrad <ma...@mellanox.com>; Shahaf Shuler > <shah...@mellanox.com>; Slava Ovsiienko <viachesl...@mellanox.com> > Cc: dev@dpdk.org; Ori Kam <or...@mellanox.com>; jingjing...@intel.com; > step...@networkplumber.org > Subject: [PATCH 07/13] net/mlx5: add hairpin binding function > > When starting the port, in addition to creating the queues we need to bind > the hairpin queues. > > Signed-off-by: Ori Kam <or...@mellanox.com> Acked-by: Viacheslav Ovsiienko <viachesl...@mellanox.com>
> --- > drivers/net/mlx5/mlx5.h | 1 + > drivers/net/mlx5/mlx5_devx_cmds.c | 1 + > drivers/net/mlx5/mlx5_prm.h | 6 +++ > drivers/net/mlx5/mlx5_trigger.c | 97 > +++++++++++++++++++++++++++++++++++++++ > 4 files changed, 105 insertions(+) > > diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index > 506920e..41eb35a 100644 > --- a/drivers/net/mlx5/mlx5.h > +++ b/drivers/net/mlx5/mlx5.h > @@ -188,6 +188,7 @@ struct mlx5_hca_attr { > uint32_t log_max_hairpin_queues:5; > uint32_t log_max_hairpin_wq_data_sz:5; > uint32_t log_max_hairpin_num_packets:5; > + uint32_t vhca_id:16; > }; > > /* Flow list . */ > diff --git a/drivers/net/mlx5/mlx5_devx_cmds.c > b/drivers/net/mlx5/mlx5_devx_cmds.c > index 917bbf9..0243733 100644 > --- a/drivers/net/mlx5/mlx5_devx_cmds.c > +++ b/drivers/net/mlx5/mlx5_devx_cmds.c > @@ -334,6 +334,7 @@ struct mlx5_devx_obj * > > log_max_hairpin_wq_data_sz); > attr->log_max_hairpin_num_packets = MLX5_GET > (cmd_hca_cap, hcattr, log_min_hairpin_wq_data_sz); > + attr->vhca_id = MLX5_GET(cmd_hca_cap, hcattr, vhca_id); > attr->eth_net_offloads = MLX5_GET(cmd_hca_cap, hcattr, > eth_net_offloads); > attr->eth_virt = MLX5_GET(cmd_hca_cap, hcattr, eth_virt); diff --git > a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h index > faa7996..d4084db 100644 > --- a/drivers/net/mlx5/mlx5_prm.h > +++ b/drivers/net/mlx5/mlx5_prm.h > @@ -1611,6 +1611,12 @@ struct mlx5_ifc_create_rqt_in_bits { #pragma > GCC diagnostic error "-Wpedantic" > #endif > > +enum { > + MLX5_SQC_STATE_RST = 0x0, > + MLX5_SQC_STATE_RDY = 0x1, > + MLX5_SQC_STATE_ERR = 0x3, > +}; > + > struct mlx5_ifc_sqc_bits { > u8 rlky[0x1]; > u8 cd_master[0x1]; > diff --git a/drivers/net/mlx5/mlx5_trigger.c > b/drivers/net/mlx5/mlx5_trigger.c index 3ec86c4..a4fcdb3 100644 > --- a/drivers/net/mlx5/mlx5_trigger.c > +++ b/drivers/net/mlx5/mlx5_trigger.c > @@ -162,6 +162,96 @@ > } > > /** > + * 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_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; > + > + 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->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; > + 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; > +} > + > +/** > * DPDK callback to start the device. > * > * Simulate device start by attaching all configured flows. > @@ -192,6 +282,13 @@ > mlx5_txq_stop(dev); > return -rte_errno; > } > + ret = mlx5_hairpin_bind(dev); > + if (ret) { > + DRV_LOG(ERR, "port %u hairpin binding failed: %s", > + dev->data->port_id, strerror(rte_errno)); > + mlx5_txq_stop(dev); > + return -rte_errno; > + } > dev->data->dev_started = 1; > ret = mlx5_rx_intr_vec_enable(dev); > if (ret) { > -- > 1.8.3.1