Commit cabdc8ee authored by Hadar Hen Zion's avatar Hadar Hen Zion Committed by David S. Miller

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: default avatarHadar Hen Zion <hadarh@mellanox.co.il>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 82067281
...@@ -821,7 +821,7 @@ static int mlx4_en_flow_replace(struct net_device *dev, ...@@ -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 */ /* Allow direct QP attaches if the EN_ETHTOOL_QP_ATTACH flag is set */
if (cmd->fs.ring_cookie == RX_CLS_FLOW_DISC) 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) { else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) {
qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1); qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1);
} else { } else {
......
...@@ -796,6 +796,10 @@ int mlx4_en_start_port(struct net_device *dev) ...@@ -796,6 +796,10 @@ int mlx4_en_start_port(struct net_device *dev)
goto mac_err; goto mac_err;
} }
err = mlx4_en_create_drop_qp(priv);
if (err)
goto rss_err;
/* Configure tx cq's and rings */ /* Configure tx cq's and rings */
for (i = 0; i < priv->tx_ring_num; i++) { for (i = 0; i < priv->tx_ring_num; i++) {
/* Configure cq */ /* Configure cq */
...@@ -895,7 +899,8 @@ int mlx4_en_start_port(struct net_device *dev) ...@@ -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_tx_ring(priv, &priv->tx_ring[tx_index]);
mlx4_en_deactivate_cq(priv, &priv->tx_cq[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); mlx4_en_release_rss_steer(priv);
mac_err: mac_err:
mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn); 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) ...@@ -950,6 +955,8 @@ void mlx4_en_stop_port(struct net_device *dev)
/* Flush multicast filter */ /* Flush multicast filter */
mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG); mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG);
mlx4_en_destroy_drop_qp(priv);
/* Free TX Rings */ /* Free TX Rings */
for (i = 0; i < priv->tx_ring_num; i++) { for (i = 0; i < priv->tx_ring_num; i++) {
mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[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, ...@@ -844,6 +844,36 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
return err; 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 */ /* Allocate rx qp's and configure them according to rss map */
int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
{ {
......
...@@ -500,6 +500,7 @@ struct mlx4_en_priv { ...@@ -500,6 +500,7 @@ struct mlx4_en_priv {
struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS]; struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS];
struct mlx4_en_cq *tx_cq; struct mlx4_en_cq *tx_cq;
struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
struct mlx4_qp drop_qp;
struct work_struct mcast_task; struct work_struct mcast_task;
struct work_struct mac_task; struct work_struct mac_task;
struct work_struct watchdog_task; struct work_struct watchdog_task;
...@@ -586,6 +587,8 @@ void mlx4_en_unmap_buffer(struct mlx4_buf *buf); ...@@ -586,6 +587,8 @@ void mlx4_en_unmap_buffer(struct mlx4_buf *buf);
void mlx4_en_calc_rx_buf(struct net_device *dev); void mlx4_en_calc_rx_buf(struct net_device *dev);
int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv); int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv);
void mlx4_en_release_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); 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); void mlx4_en_rx_irq(struct mlx4_cq *mcq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment