On Sun, Aug 16, 2015 at 07:05:30PM +0300, Eran Ben Elisha wrote: > From: Maor Gottlieb <maorg@xxxxxxxxxxxx> > > Set the mcast loopback prevention bit in the QPC for ETH MLX QPs (not > RSS QPs), when the firmware supports this feature. In addition, all rx > ring QPs need to be updated in order not to enforce loopback checks. > This prevents getting packets we sent both from the network stack and > the HCA. Loopback prevention is done by comparing the counter indices of > the sent and receiving QPs. If they're equal, packets aren't > loopback-ed. > > Signed-off-by: Maor Gottlieb <maorg@xxxxxxxxxxxx> > Signed-off-by: Eran Ben Elisha <eranbe@xxxxxxxxxxxx> > --- > drivers/net/ethernet/mellanox/mlx4/en_main.c | 22 ++++++++++++++++++++ > drivers/net/ethernet/mellanox/mlx4/en_resources.c | 25 +++++++++++++++++++++++ > drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 ++- > 3 files changed, 49 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c > index a946e4b..70e381a 100644 > --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c > +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c > @@ -123,6 +123,28 @@ void mlx4_en_update_loopback_state(struct net_device *dev, > */ > if (mlx4_is_mfunc(priv->mdev->dev) || priv->validate_loopback) > priv->flags |= MLX4_EN_FLAG_ENABLE_HW_LOOPBACK; > + > + mutex_lock(&priv->mdev->state_lock); > + if (priv->mdev->dev->caps.flags2 & > + MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB && > + priv->rss_map.indir_qp.qpn) { > + int i; > + int err = 0; > + > + for (i = 0; i < priv->rx_ring_num; i++) { > + int ret; > + > + ret = mlx4_en_change_mcast_lb(priv, > + &priv->rss_map.qps[i], > + !!(features & > + NETIF_F_LOOPBACK)); If "feature" is not changing inside the loop can we take it out just for the code to look more readable? > + if (!err) > + err = ret; > + } > + if (err) > + mlx4_warn(priv->mdev, "failed to change mcast loopback\n"); > + } > + mutex_unlock(&priv->mdev->state_lock); > } > > static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) > diff --git a/drivers/net/ethernet/mellanox/mlx4/en_resources.c b/drivers/net/ethernet/mellanox/mlx4/en_resources.c > index e482fa1b..12aab5a 100644 > --- a/drivers/net/ethernet/mellanox/mlx4/en_resources.c > +++ b/drivers/net/ethernet/mellanox/mlx4/en_resources.c > @@ -69,6 +69,15 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, > context->pri_path.counter_index = priv->counter_index; > context->cqn_send = cpu_to_be32(cqn); > context->cqn_recv = cpu_to_be32(cqn); > + if (!rss && > + (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_LB_SRC_CHK) && > + context->pri_path.counter_index != > + MLX4_SINK_COUNTER_INDEX(mdev->dev)) { > + /* disable multicast loopback to qp with same counter */ > + if (!(dev->features & NETIF_F_LOOPBACK)) > + context->pri_path.fl |= MLX4_FL_ETH_SRC_CHECK_MC_LB; > + context->pri_path.control |= MLX4_CTRL_ETH_SRC_CHECK_IF_COUNTER; > + } > context->db_rec_addr = cpu_to_be64(priv->res.db.dma << 2); > if (!(dev->features & NETIF_F_HW_VLAN_CTAG_RX)) > context->param3 |= cpu_to_be32(1 << 30); > @@ -80,6 +89,22 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, > } > } > > +int mlx4_en_change_mcast_lb(struct mlx4_en_priv *priv, struct mlx4_qp *qp, > + int loopback) > +{ > + int ret; > + struct mlx4_update_qp_params qp_params; > + > + memset(&qp_params, 0, sizeof(qp_params)); > + if (!loopback) > + qp_params.flags = MLX4_UPDATE_QP_PARAMS_FLAGS_ETH_CHECK_MC_LB; > + > + ret = mlx4_update_qp(priv->mdev->dev, qp->qpn, > + MLX4_UPDATE_QP_ETH_SRC_CHECK_MC_LB, > + &qp_params); > + > + return ret; > +} > > int mlx4_en_map_buffer(struct mlx4_buf *buf) > { > diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h > index 666d166..7db86d4 100644 > --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h > +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h > @@ -797,7 +797,8 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, > void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event); > int mlx4_en_map_buffer(struct mlx4_buf *buf); > void mlx4_en_unmap_buffer(struct mlx4_buf *buf); > - > +int mlx4_en_change_mcast_lb(struct mlx4_en_priv *priv, struct mlx4_qp *qp, > + int loopback); > void mlx4_en_calc_rx_buf(struct net_device *dev); > int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv); > void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv); > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html