diff options
author | Hadar Hen Zion <hadarh@mellanox.co.il> | 2012-07-05 00:03:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-07 19:23:06 -0400 |
commit | cabdc8ee3768ceb6367e88c6fe84a66dd667bdf9 (patch) | |
tree | 9ff702eb373d3e2cb75c4f53a218b643ed43f248 /drivers/net/ethernet/mellanox | |
parent | 820672812f8284143f933da8ccc60e296230d25d (diff) |
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>
Diffstat (limited to 'drivers/net/ethernet/mellanox')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_rx.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 |
4 files changed, 42 insertions, 2 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 3e72a2076fb5..dd6a77b21149 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |||
@@ -821,7 +821,7 @@ static int mlx4_en_flow_replace(struct net_device *dev, | |||
821 | 821 | ||
822 | /* Allow direct QP attaches if the EN_ETHTOOL_QP_ATTACH flag is set */ | 822 | /* Allow direct QP attaches if the EN_ETHTOOL_QP_ATTACH flag is set */ |
823 | if (cmd->fs.ring_cookie == RX_CLS_FLOW_DISC) | 823 | if (cmd->fs.ring_cookie == RX_CLS_FLOW_DISC) |
824 | return -EINVAL; | 824 | qpn = priv->drop_qp.qpn; |
825 | else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) { | 825 | else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) { |
826 | qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1); | 826 | qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1); |
827 | } else { | 827 | } else { |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index b7945a80ad15..94375a8c6d42 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -796,6 +796,10 @@ int mlx4_en_start_port(struct net_device *dev) | |||
796 | goto mac_err; | 796 | goto mac_err; |
797 | } | 797 | } |
798 | 798 | ||
799 | err = mlx4_en_create_drop_qp(priv); | ||
800 | if (err) | ||
801 | goto rss_err; | ||
802 | |||
799 | /* Configure tx cq's and rings */ | 803 | /* Configure tx cq's and rings */ |
800 | for (i = 0; i < priv->tx_ring_num; i++) { | 804 | for (i = 0; i < priv->tx_ring_num; i++) { |
801 | /* Configure cq */ | 805 | /* Configure cq */ |
@@ -895,7 +899,8 @@ tx_err: | |||
895 | mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[tx_index]); | 899 | mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[tx_index]); |
896 | mlx4_en_deactivate_cq(priv, &priv->tx_cq[tx_index]); | 900 | mlx4_en_deactivate_cq(priv, &priv->tx_cq[tx_index]); |
897 | } | 901 | } |
898 | 902 | mlx4_en_destroy_drop_qp(priv); | |
903 | rss_err: | ||
899 | mlx4_en_release_rss_steer(priv); | 904 | mlx4_en_release_rss_steer(priv); |
900 | mac_err: | 905 | mac_err: |
901 | mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn); | 906 | 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 | /* Flush multicast filter */ | 955 | /* Flush multicast filter */ |
951 | mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG); | 956 | mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG); |
952 | 957 | ||
958 | mlx4_en_destroy_drop_qp(priv); | ||
959 | |||
953 | /* Free TX Rings */ | 960 | /* Free TX Rings */ |
954 | for (i = 0; i < priv->tx_ring_num; i++) { | 961 | for (i = 0; i < priv->tx_ring_num; i++) { |
955 | mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[i]); | 962 | mlx4_en_deactivate_tx_ring(priv, &priv->tx_ring[i]); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index d49a7ac3187d..a04cbf767eb5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c | |||
@@ -844,6 +844,36 @@ out: | |||
844 | return err; | 844 | return err; |
845 | } | 845 | } |
846 | 846 | ||
847 | int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv) | ||
848 | { | ||
849 | int err; | ||
850 | u32 qpn; | ||
851 | |||
852 | err = mlx4_qp_reserve_range(priv->mdev->dev, 1, 1, &qpn); | ||
853 | if (err) { | ||
854 | en_err(priv, "Failed reserving drop qpn\n"); | ||
855 | return err; | ||
856 | } | ||
857 | err = mlx4_qp_alloc(priv->mdev->dev, qpn, &priv->drop_qp); | ||
858 | if (err) { | ||
859 | en_err(priv, "Failed allocating drop qp\n"); | ||
860 | mlx4_qp_release_range(priv->mdev->dev, qpn, 1); | ||
861 | return err; | ||
862 | } | ||
863 | |||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | void mlx4_en_destroy_drop_qp(struct mlx4_en_priv *priv) | ||
868 | { | ||
869 | u32 qpn; | ||
870 | |||
871 | qpn = priv->drop_qp.qpn; | ||
872 | mlx4_qp_remove(priv->mdev->dev, &priv->drop_qp); | ||
873 | mlx4_qp_free(priv->mdev->dev, &priv->drop_qp); | ||
874 | mlx4_qp_release_range(priv->mdev->dev, qpn, 1); | ||
875 | } | ||
876 | |||
847 | /* Allocate rx qp's and configure them according to rss map */ | 877 | /* Allocate rx qp's and configure them according to rss map */ |
848 | int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) | 878 | int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) |
849 | { | 879 | { |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 8882e70493fe..a12632150b34 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -500,6 +500,7 @@ struct mlx4_en_priv { | |||
500 | struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS]; | 500 | struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS]; |
501 | struct mlx4_en_cq *tx_cq; | 501 | struct mlx4_en_cq *tx_cq; |
502 | struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; | 502 | struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; |
503 | struct mlx4_qp drop_qp; | ||
503 | struct work_struct mcast_task; | 504 | struct work_struct mcast_task; |
504 | struct work_struct mac_task; | 505 | struct work_struct mac_task; |
505 | struct work_struct watchdog_task; | 506 | struct work_struct watchdog_task; |
@@ -586,6 +587,8 @@ void mlx4_en_unmap_buffer(struct mlx4_buf *buf); | |||
586 | void mlx4_en_calc_rx_buf(struct net_device *dev); | 587 | void mlx4_en_calc_rx_buf(struct net_device *dev); |
587 | int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv); | 588 | int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv); |
588 | void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv); | 589 | void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv); |
590 | int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv); | ||
591 | void mlx4_en_destroy_drop_qp(struct mlx4_en_priv *priv); | ||
589 | int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring); | 592 | int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring); |
590 | void mlx4_en_rx_irq(struct mlx4_cq *mcq); | 593 | void mlx4_en_rx_irq(struct mlx4_cq *mcq); |
591 | 594 | ||