net/mlx4_en: Add support for drop action through ethtool
The drop action is implemented by allocating a QP and keeping it in a reset state such that the HW drops any packets which are steered to that QP. When a drop action is requested, we attach the relevant flow to that QP. Sign-off-by: Hadar Hen Zion <hadarh@mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
820672812f
commit
cabdc8ee37
4 changed files with 42 additions and 2 deletions
|
@ -821,7 +821,7 @@ static int mlx4_en_flow_replace(struct net_device *dev,
|
|||
|
||||
/* Allow direct QP attaches if the EN_ETHTOOL_QP_ATTACH flag is set */
|
||||
if (cmd->fs.ring_cookie == RX_CLS_FLOW_DISC)
|
||||
return -EINVAL;
|
||||
qpn = priv->drop_qp.qpn;
|
||||
else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) {
|
||||
qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1);
|
||||
} else {
|
||||
|
|
|
@ -796,6 +796,10 @@ int mlx4_en_start_port(struct net_device *dev)
|
|||
goto mac_err;
|
||||
}
|
||||
|
||||
err = mlx4_en_create_drop_qp(priv);
|
||||
if (err)
|
||||
goto rss_err;
|
||||
|
||||
/* Configure tx cq's and rings */
|
||||
for (i = 0; i < priv->tx_ring_num; i++) {
|
||||
/* Configure cq */
|
||||
|
@ -895,7 +899,8 @@ int mlx4_en_start_port(struct net_device *dev)
|
|||
mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[tx_index]);
|
||||
mlx4_en_deactivate_cq(priv, &priv->tx_cq[tx_index]);
|
||||
}
|
||||
|
||||
mlx4_en_destroy_drop_qp(priv);
|
||||
rss_err:
|
||||
mlx4_en_release_rss_steer(priv);
|
||||
mac_err:
|
||||
mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn);
|
||||
|
@ -950,6 +955,8 @@ void mlx4_en_stop_port(struct net_device *dev)
|
|||
/* Flush multicast filter */
|
||||
mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG);
|
||||
|
||||
mlx4_en_destroy_drop_qp(priv);
|
||||
|
||||
/* Free TX Rings */
|
||||
for (i = 0; i < priv->tx_ring_num; i++) {
|
||||
mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[i]);
|
||||
|
|
|
@ -844,6 +844,36 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
|
|||
return err;
|
||||
}
|
||||
|
||||
int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv)
|
||||
{
|
||||
int err;
|
||||
u32 qpn;
|
||||
|
||||
err = mlx4_qp_reserve_range(priv->mdev->dev, 1, 1, &qpn);
|
||||
if (err) {
|
||||
en_err(priv, "Failed reserving drop qpn\n");
|
||||
return err;
|
||||
}
|
||||
err = mlx4_qp_alloc(priv->mdev->dev, qpn, &priv->drop_qp);
|
||||
if (err) {
|
||||
en_err(priv, "Failed allocating drop qp\n");
|
||||
mlx4_qp_release_range(priv->mdev->dev, qpn, 1);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mlx4_en_destroy_drop_qp(struct mlx4_en_priv *priv)
|
||||
{
|
||||
u32 qpn;
|
||||
|
||||
qpn = priv->drop_qp.qpn;
|
||||
mlx4_qp_remove(priv->mdev->dev, &priv->drop_qp);
|
||||
mlx4_qp_free(priv->mdev->dev, &priv->drop_qp);
|
||||
mlx4_qp_release_range(priv->mdev->dev, qpn, 1);
|
||||
}
|
||||
|
||||
/* Allocate rx qp's and configure them according to rss map */
|
||||
int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
|
||||
{
|
||||
|
|
|
@ -500,6 +500,7 @@ struct mlx4_en_priv {
|
|||
struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS];
|
||||
struct mlx4_en_cq *tx_cq;
|
||||
struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
|
||||
struct mlx4_qp drop_qp;
|
||||
struct work_struct mcast_task;
|
||||
struct work_struct mac_task;
|
||||
struct work_struct watchdog_task;
|
||||
|
@ -586,6 +587,8 @@ void mlx4_en_unmap_buffer(struct mlx4_buf *buf);
|
|||
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);
|
||||
int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv);
|
||||
void mlx4_en_destroy_drop_qp(struct mlx4_en_priv *priv);
|
||||
int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring);
|
||||
void mlx4_en_rx_irq(struct mlx4_cq *mcq);
|
||||
|
||||
|
|
Loading…
Reference in a new issue