aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox
diff options
context:
space:
mode:
authorYan Burman <yanb@mellanox.com>2013-02-06 21:25:19 -0500
committerDavid S. Miller <davem@davemloft.net>2013-02-07 23:26:12 -0500
commit79aeaccd915c527a75f2cb01682eab160bed4f48 (patch)
treed9fb2253288a2970220f770d17d27aebd2479eca /drivers/net/ethernet/mellanox
parent4d9e01da87caa9bc63c3284ab38e0dd53eeab6ae (diff)
net/mlx4_en: Optimize loopback related checks in data path
Currently there are relatively complex conditional checks in the fast path, for TX loopback enabling and resulting RX filter logic. Move elaborate if's out of data path, replace them with a single flag for each state and update that state from appropriate places. Also, in native (non SRIOV) mode and not in loopback or in selftest, there is no need to try and filter out packets that HW loopback-ed, as in native mode we do not loopback packets anymore. Signed-off-by: Yan Burman <yanb@mellanox.com> Signed-off-by: Amir Vadai <amirv@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_main.c22
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c39
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_selftest.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h16
6 files changed, 65 insertions, 21 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index f3c7961a271f..e3c3d122979e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -95,6 +95,28 @@ int en_print(const char *level, const struct mlx4_en_priv *priv,
95 return i; 95 return i;
96} 96}
97 97
98void mlx4_en_update_loopback_state(struct net_device *dev,
99 netdev_features_t features)
100{
101 struct mlx4_en_priv *priv = netdev_priv(dev);
102
103 priv->flags &= ~(MLX4_EN_FLAG_RX_FILTER_NEEDED|
104 MLX4_EN_FLAG_ENABLE_HW_LOOPBACK);
105
106 /* Drop the packet if SRIOV is not enabled
107 * and not performing the selftest or flb disabled
108 */
109 if (mlx4_is_mfunc(priv->mdev->dev) &&
110 !(features & NETIF_F_LOOPBACK) && !priv->validate_loopback)
111 priv->flags |= MLX4_EN_FLAG_RX_FILTER_NEEDED;
112
113 /* Set dmac in Tx WQE if we are in SRIOV mode or if loopback selftest
114 * is requested
115 */
116 if (mlx4_is_mfunc(priv->mdev->dev) || priv->validate_loopback)
117 priv->flags |= MLX4_EN_FLAG_ENABLE_HW_LOOPBACK;
118}
119
98static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) 120static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
99{ 121{
100 struct mlx4_en_profile *params = &mdev->profile; 122 struct mlx4_en_profile *params = &mdev->profile;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index ac1c14f7424a..551ef688a8df 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1563,6 +1563,8 @@ static int mlx4_en_set_features(struct net_device *netdev,
1563 priv->ctrl_flags &= 1563 priv->ctrl_flags &=
1564 cpu_to_be32(~MLX4_WQE_CTRL_FORCE_LOOPBACK); 1564 cpu_to_be32(~MLX4_WQE_CTRL_FORCE_LOOPBACK);
1565 1565
1566 mlx4_en_update_loopback_state(netdev, features);
1567
1566 return 0; 1568 return 0;
1567 1569
1568} 1570}
@@ -1731,6 +1733,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
1731 en_warn(priv, "Using %d TX rings\n", prof->tx_ring_num); 1733 en_warn(priv, "Using %d TX rings\n", prof->tx_ring_num);
1732 en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num); 1734 en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num);
1733 1735
1736 mlx4_en_update_loopback_state(priv->dev, priv->dev->features);
1737
1734 /* Configure port */ 1738 /* Configure port */
1735 mlx4_en_calc_rx_buf(dev); 1739 mlx4_en_calc_rx_buf(dev);
1736 err = mlx4_SET_PORT_general(mdev->dev, priv->port, 1740 err = mlx4_SET_PORT_general(mdev->dev, priv->port,
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index fed26d867f4e..ed214d05dd71 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -563,9 +563,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
563 unsigned int length; 563 unsigned int length;
564 int polled = 0; 564 int polled = 0;
565 int ip_summed; 565 int ip_summed;
566 struct ethhdr *ethh;
567 dma_addr_t dma;
568 u64 s_mac;
569 int factor = priv->cqe_factor; 566 int factor = priv->cqe_factor;
570 567
571 if (!priv->port_up) 568 if (!priv->port_up)
@@ -603,21 +600,27 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
603 goto next; 600 goto next;
604 } 601 }
605 602
606 /* Get pointer to first fragment since we haven't skb yet and 603 /* Check if we need to drop the packet if SRIOV is not enabled
607 * cast it to ethhdr struct */ 604 * and not performing the selftest or flb disabled
608 dma = be64_to_cpu(rx_desc->data[0].addr); 605 */
609 dma_sync_single_for_cpu(priv->ddev, dma, sizeof(*ethh), 606 if (priv->flags & MLX4_EN_FLAG_RX_FILTER_NEEDED) {
610 DMA_FROM_DEVICE); 607 struct ethhdr *ethh;
611 ethh = (struct ethhdr *)(page_address(frags[0].page) + 608 dma_addr_t dma;
612 frags[0].offset); 609 u64 s_mac;
613 s_mac = mlx4_en_mac_to_u64(ethh->h_source); 610 /* Get pointer to first fragment since we haven't
614 611 * skb yet and cast it to ethhdr struct
615 /* If source MAC is equal to our own MAC and not performing 612 */
616 * the selftest or flb disabled - drop the packet */ 613 dma = be64_to_cpu(rx_desc->data[0].addr);
617 if (s_mac == priv->mac && 614 dma_sync_single_for_cpu(priv->ddev, dma, sizeof(*ethh),
618 !((dev->features & NETIF_F_LOOPBACK) || 615 DMA_FROM_DEVICE);
619 priv->validate_loopback)) 616 ethh = (struct ethhdr *)(page_address(frags[0].page) +
620 goto next; 617 frags[0].offset);
618
619 /* Drop the packet, since HW loopback-ed it */
620 s_mac = mlx4_en_mac_to_u64(ethh->h_source);
621 if (s_mac == priv->mac)
622 goto next;
623 }
621 624
622 /* 625 /*
623 * Packet is OK - process it. 626 * Packet is OK - process it.
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
index bf2e5d3f177c..3488c6d9e6b5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
@@ -87,6 +87,8 @@ static int mlx4_en_test_loopback(struct mlx4_en_priv *priv)
87 priv->loopback_ok = 0; 87 priv->loopback_ok = 0;
88 priv->validate_loopback = 1; 88 priv->validate_loopback = 1;
89 89
90 mlx4_en_update_loopback_state(priv->dev, priv->dev->features);
91
90 /* xmit */ 92 /* xmit */
91 if (mlx4_en_test_loopback_xmit(priv)) { 93 if (mlx4_en_test_loopback_xmit(priv)) {
92 en_err(priv, "Transmitting loopback packet failed\n"); 94 en_err(priv, "Transmitting loopback packet failed\n");
@@ -107,6 +109,7 @@ static int mlx4_en_test_loopback(struct mlx4_en_priv *priv)
107mlx4_en_test_loopback_exit: 109mlx4_en_test_loopback_exit:
108 110
109 priv->validate_loopback = 0; 111 priv->validate_loopback = 0;
112 mlx4_en_update_loopback_state(priv->dev, priv->dev->features);
110 return !loopback_ok; 113 return !loopback_ok;
111} 114}
112 115
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 30724d811115..3b28e167b05b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -640,7 +640,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
640 ring->tx_csum++; 640 ring->tx_csum++;
641 } 641 }
642 642
643 if (mlx4_is_mfunc(mdev->dev) || priv->validate_loopback) { 643 if (priv->flags & MLX4_EN_FLAG_ENABLE_HW_LOOPBACK) {
644 /* Copy dst mac address to wqe. This allows loopback in eSwitch, 644 /* Copy dst mac address to wqe. This allows loopback in eSwitch,
645 * so that VFs and PF can communicate with each other 645 * so that VFs and PF can communicate with each other
646 */ 646 */
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 43f01650e585..696dcf33619f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -432,6 +432,17 @@ struct ethtool_flow_id {
432 u64 id; 432 u64 id;
433}; 433};
434 434
435enum {
436 MLX4_EN_FLAG_PROMISC = (1 << 0),
437 MLX4_EN_FLAG_MC_PROMISC = (1 << 1),
438 /* whether we need to enable hardware loopback by putting dmac
439 * in Tx WQE
440 */
441 MLX4_EN_FLAG_ENABLE_HW_LOOPBACK = (1 << 2),
442 /* whether we need to drop packets that hardware loopback-ed */
443 MLX4_EN_FLAG_RX_FILTER_NEEDED = (1 << 3)
444};
445
435struct mlx4_en_priv { 446struct mlx4_en_priv {
436 struct mlx4_en_dev *mdev; 447 struct mlx4_en_dev *mdev;
437 struct mlx4_en_port_profile *prof; 448 struct mlx4_en_port_profile *prof;
@@ -481,8 +492,6 @@ struct mlx4_en_priv {
481 struct mlx4_en_rss_map rss_map; 492 struct mlx4_en_rss_map rss_map;
482 __be32 ctrl_flags; 493 __be32 ctrl_flags;
483 u32 flags; 494 u32 flags;
484#define MLX4_EN_FLAG_PROMISC 0x1
485#define MLX4_EN_FLAG_MC_PROMISC 0x2
486 u8 num_tx_rings_p_up; 495 u8 num_tx_rings_p_up;
487 u32 tx_ring_num; 496 u32 tx_ring_num;
488 u32 rx_ring_num; 497 u32 rx_ring_num;
@@ -534,6 +543,9 @@ enum mlx4_en_wol {
534 543
535#define MLX4_EN_WOL_DO_MODIFY (1ULL << 63) 544#define MLX4_EN_WOL_DO_MODIFY (1ULL << 63)
536 545
546void mlx4_en_update_loopback_state(struct net_device *dev,
547 netdev_features_t features);
548
537void mlx4_en_destroy_netdev(struct net_device *dev); 549void mlx4_en_destroy_netdev(struct net_device *dev);
538int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, 550int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
539 struct mlx4_en_port_profile *prof); 551 struct mlx4_en_port_profile *prof);