mlx4_en: Allow communication between functions on same host
authorEugenia Emantayev <eugenia@mellanox.co.il>
Tue, 13 Dec 2011 04:16:38 +0000 (04:16 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 13 Dec 2011 18:56:07 +0000 (13:56 -0500)
To enable internal loopback, always fill DMAC in control segment
when transmitting the packet, once this is done, the packet is subject
for loopback for if the DMAC mathces one of the multicast/unicast addresses
registered on the physical port.
In receive path if source MAC is our own MAC and we are not in selftest,
or not in force LB mode - drop this packet.

Signed-off-by: Eugenia Emantayev <eugenia@mellanox.co.il>
Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c

index ce1bc573d114e4e6fe161a42c1a3722e0410aa4e..630a7c113ab799ef92fd60a5a31f96f40758d229 100644 (file)
@@ -541,6 +541,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
        unsigned int length;
        int polled = 0;
        int ip_summed;
+       struct ethhdr *ethh;
+       u64 s_mac;
 
        if (!priv->port_up)
                return 0;
@@ -577,6 +579,19 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
                        goto next;
                }
 
+               /* Get pointer to first fragment since we haven't skb yet and
+                * cast it to ethhdr struct */
+               ethh = (struct ethhdr *)(page_address(skb_frags[0].page) +
+                                        skb_frags[0].offset);
+               s_mac = mlx4_en_mac_to_u64(ethh->h_source);
+
+               /* If source MAC is equal to our own MAC and not performing
+                * the selftest or flb disabled - drop the packet */
+               if (s_mac == priv->mac &&
+                       (!(dev->features & NETIF_F_LOOPBACK) ||
+                        !priv->validate_loopback))
+                       goto next;
+
                /*
                 * Packet is OK - process it.
                 */
index 7e76862de3559f4e6a951ad12452aa9ec10e05fb..9ef9038d0629972315a77a3019a8d565395761d0 100644 (file)
@@ -688,17 +688,15 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
                ring->tx_csum++;
        }
 
-       if (unlikely(priv->validate_loopback)) {
-               /* Copy dst mac address to wqe */
-               skb_reset_mac_header(skb);
-               ethh = eth_hdr(skb);
-               if (ethh && ethh->h_dest) {
-                       mac = mlx4_en_mac_to_u64(ethh->h_dest);
-                       mac_h = (u32) ((mac & 0xffff00000000ULL) >> 16);
-                       mac_l = (u32) (mac & 0xffffffff);
-                       tx_desc->ctrl.srcrb_flags |= cpu_to_be32(mac_h);
-                       tx_desc->ctrl.imm = cpu_to_be32(mac_l);
-               }
+       /* Copy dst mac address to wqe */
+       skb_reset_mac_header(skb);
+       ethh = eth_hdr(skb);
+       if (ethh && ethh->h_dest) {
+               mac = mlx4_en_mac_to_u64(ethh->h_dest);
+               mac_h = (u32) ((mac & 0xffff00000000ULL) >> 16);
+               mac_l = (u32) (mac & 0xffffffff);
+               tx_desc->ctrl.srcrb_flags |= cpu_to_be32(mac_h);
+               tx_desc->ctrl.imm = cpu_to_be32(mac_l);
        }
 
        /* Handle LSO (TSO) packets */