net/mlx4_en: Add support for drop action through ethtool
authorHadar Hen Zion <hadarh@mellanox.co.il>
Thu, 5 Jul 2012 04:03:50 +0000 (04:03 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 7 Jul 2012 23:23:06 +0000 (16:23 -0700)
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>
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h

index 3e72a2076fb556a44914cf0ff191e6a30d010ed4..dd6a77b21149fd67f06ea885cf4362a0d63963e9 100644 (file)
@@ -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 {
index b7945a80ad15057603e7aa4409762e069553aea6..94375a8c6d42ac1b022ebeca37e13201b4f5d85a 100644 (file)
@@ -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 @@ tx_err:
                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]);
index d49a7ac3187d3c451d67638d48349a0e2d0d55d0..a04cbf767eb582dc16a4b7194ba68724469b72f5 100644 (file)
@@ -844,6 +844,36 @@ out:
        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)
 {
index 8882e70493fee564226bdb4fa1ae8987ff160beb..a12632150b34c28ce7b21511b33ec788058c4a3f 100644 (file)
@@ -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);