]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mlx4_en: adding loopback support
authorJoe Jin <joe.jin@oracle.com>
Thu, 15 Dec 2011 02:39:33 +0000 (10:39 +0800)
committerJoe Jin <joe.jin@oracle.com>
Thu, 15 Dec 2011 02:39:33 +0000 (10:39 +0800)
commit 60d6fe99e4a507f77b63c090eb8aacb67e21687a
Author: Amir Vadai <amirv@mellanox.co.il>
Date:   Sat Nov 26 19:55:19 2011 +0000

    net/mlx4_en: adding loopback support

    Device must be in promiscuous mode or DMAC must be same as the host MAC, or
    else packet will be dropped by the HW rx filtering.

Signed-off-by: Amir Vadai <amirv@mellanox.co.il>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/net/mlx4/en_netdev.c
drivers/net/mlx4/en_tx.c
drivers/net/mlx4/mlx4_en.h
include/linux/mlx4/qp.h
include/linux/netdevice.h

index d9be9df9f29b8452e2def78d0fffd28309b06be7..aae1fb00fd218ee3791bbfcb1abee88e695d3559 100644 (file)
@@ -974,6 +974,21 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
+static int mlx4_en_set_features(struct net_device *netdev,
+               netdev_features_t features)
+{
+       struct mlx4_en_priv *priv = netdev_priv(netdev);
+
+       if (features & NETIF_F_LOOPBACK)
+               priv->ctrl_flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK);
+       else
+               priv->ctrl_flags &=
+                       cpu_to_be32(~MLX4_WQE_CTRL_FORCE_LOOPBACK);
+
+       return 0;
+
+}
+
 static const struct net_device_ops mlx4_netdev_ops = {
        .ndo_open               = mlx4_en_open,
        .ndo_stop               = mlx4_en_close,
@@ -990,6 +1005,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = mlx4_en_netpoll,
 #endif
+       .ndo_set_features       = mlx4_en_set_features,
 };
 
 int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
@@ -1022,6 +1038,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        priv->port = port;
        priv->port_up = false;
        priv->flags = prof->flags;
+       priv->ctrl_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE |
+                       MLX4_WQE_CTRL_SOLICITED);
        priv->tx_ring_num = prof->tx_ring_num;
        priv->rx_ring_num = prof->rx_ring_num;
        priv->mac_index = -1;
@@ -1088,6 +1106,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        dev->features = dev->hw_features | NETIF_F_HIGHDMA |
                        NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
                        NETIF_F_HW_VLAN_FILTER;
+       dev->hw_features |= NETIF_F_LOOPBACK;
 
        mdev->pndev[port] = dev;
 
index 2da48d2101aa51933cbbeb97a8406c5b3af4d676..5215d9415f1b80ffb89c59b0f40ed15a9f453805 100644 (file)
@@ -692,8 +692,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
        tx_desc->ctrl.vlan_tag = cpu_to_be16(vlan_tag);
        tx_desc->ctrl.ins_vlan = MLX4_WQE_CTRL_INS_VLAN * !!vlan_tag;
        tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
-       tx_desc->ctrl.srcrb_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE |
-                                               MLX4_WQE_CTRL_SOLICITED);
+       tx_desc->ctrl.srcrb_flags = priv->ctrl_flags;
        if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
                tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
                                                         MLX4_WQE_CTRL_TCP_UDP_CSUM);
index 6e555c7cdce6d8c7b5b7ccd08d70ae34ddda7649..df9053af3b6d381892e9bc5c98747231cf646202 100644 (file)
@@ -463,6 +463,7 @@ struct mlx4_en_priv {
        int base_qpn;
 
        struct mlx4_en_rss_map rss_map;
+       u32 ctrl_flags;
        u32 flags;
 #define MLX4_EN_FLAG_PROMISC   0x1
 #define MLX4_EN_FLAG_MC_PROMISC        0x2
index 9e9eb21056ca4cd7c569e51a37c30e17745835f4..aa2c829d55bac84e483d470324911d4e18e5b059 100644 (file)
@@ -182,6 +182,7 @@ struct mlx4_wqe_ctrl_seg {
         * [4]   IP checksum
         * [3:2] C (generate completion queue entry)
         * [1]   SE (solicited event)
+        * [0]   FL (force loopback)
         */
        __be32                  srcrb_flags;
        /*
index 33b5968e738187fa9dda5d9dd9af75cb47e26ded..f19686d7bb6f9bff81be24777ff10d08c31576a9 100644 (file)
@@ -980,6 +980,7 @@ struct net_device_ops {
                                                    u32 features);
 };
 
+typedef u32 netdev_features_t;
 /*
  *     The DEVICE structure.
  *     Actually, this whole structure is a big mistake.  It mixes I/O