liquidio: store the L4 hash of rx packets in skb
authorPrasad Kanneganti <prasad.kanneganti@cavium.com>
Mon, 9 Jan 2017 22:42:40 +0000 (14:42 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 10 Jan 2017 19:22:34 +0000 (14:22 -0500)
Store the L4 hash of received packets in the skb; the hash is computed in
the NIC firmware.

Signed-off-by: Prasad Kanneganti <prasad.kanneganti@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: Derek Chickles <derek.chickles@cavium.com>
Signed-off-by: Satanand Burla <satananda.burla@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/cavium/liquidio/lio_main.c
drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
drivers/net/ethernet/cavium/liquidio/liquidio_common.h

index 13f67a32cc4da8312936c34b1112bd75484ecb14..b8b579d8043fddfa5d26f71185a838a753e6be39 100644 (file)
@@ -2263,6 +2263,7 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
        struct skb_shared_hwtstamps *shhwtstamps;
        u64 ns;
        u16 vtag = 0;
+       u32 r_dh_off;
        struct net_device *netdev = (struct net_device *)arg;
        struct octeon_droq *droq = container_of(param, struct octeon_droq,
                                                napi);
@@ -2308,6 +2309,8 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
                        put_page(pg_info->page);
                }
 
+               r_dh_off = (rh->r_dh.len - 1) * BYTES_PER_DHLEN_UNIT;
+
                if (((oct->chip_id == OCTEON_CN66XX) ||
                     (oct->chip_id == OCTEON_CN68XX)) &&
                    ptp_enable) {
@@ -2320,16 +2323,27 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
                                        /* Nanoseconds are in the first 64-bits
                                         * of the packet.
                                         */
-                                       memcpy(&ns, (skb->data), sizeof(ns));
+                                       memcpy(&ns, (skb->data + r_dh_off),
+                                              sizeof(ns));
+                                       r_dh_off -= BYTES_PER_DHLEN_UNIT;
                                        shhwtstamps = skb_hwtstamps(skb);
                                        shhwtstamps->hwtstamp =
                                                ns_to_ktime(ns +
                                                            lio->ptp_adjust);
                                }
-                               skb_pull(skb, sizeof(ns));
                        }
                }
 
+               if (rh->r_dh.has_hash) {
+                       __be32 *hash_be = (__be32 *)(skb->data + r_dh_off);
+                       u32 hash = be32_to_cpu(*hash_be);
+
+                       skb_set_hash(skb, hash, PKT_HASH_TYPE_L4);
+                       r_dh_off -= BYTES_PER_DHLEN_UNIT;
+               }
+
+               skb_pull(skb, rh->r_dh.len * BYTES_PER_DHLEN_UNIT);
+
                skb->protocol = eth_type_trans(skb, skb->dev);
                if ((netdev->features & NETIF_F_RXCSUM) &&
                    (((rh->r_dh.encap_on) &&
index 55846f2d7e46d1970cb4c47d3966667ac47cb131..ad2e72d7d522ce0d4c94ad928c3e1e2d01004f2d 100644 (file)
@@ -1497,6 +1497,7 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
        struct net_device *netdev = (struct net_device *)arg;
        struct sk_buff *skb = (struct sk_buff *)skbuff;
        u16 vtag = 0;
+       u32 r_dh_off;
 
        if (netdev) {
                struct lio *lio = GET_LIO(netdev);
@@ -1540,7 +1541,20 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)),
                        put_page(pg_info->page);
                }
 
-               skb_pull(skb, rh->r_dh.len * 8);
+               r_dh_off = (rh->r_dh.len - 1) * BYTES_PER_DHLEN_UNIT;
+
+               if (rh->r_dh.has_hwtstamp)
+                       r_dh_off -= BYTES_PER_DHLEN_UNIT;
+
+               if (rh->r_dh.has_hash) {
+                       __be32 *hash_be = (__be32 *)(skb->data + r_dh_off);
+                       u32 hash = be32_to_cpu(*hash_be);
+
+                       skb_set_hash(skb, hash, PKT_HASH_TYPE_L4);
+                       r_dh_off -= BYTES_PER_DHLEN_UNIT;
+               }
+
+               skb_pull(skb, rh->r_dh.len * BYTES_PER_DHLEN_UNIT);
                skb->protocol = eth_type_trans(skb, skb->dev);
 
                if ((netdev->features & NETIF_F_RXCSUM) &&
index ba329f6ca779d5c11925ba7b42dae9d51e015652..bc0af8af1a0ca975e3ceb23a9f976afcddb51c1b 100644 (file)
@@ -98,6 +98,8 @@ enum octeon_tag_type {
 #define CVM_DRV_INVALID_APP         (CVM_DRV_APP_START + 0x2)
 #define CVM_DRV_APP_END             (CVM_DRV_INVALID_APP - 1)
 
+#define BYTES_PER_DHLEN_UNIT        8
+
 static inline u32 incr_index(u32 index, u32 count, u32 max)
 {
        if ((index + count) >= max)