Add checksum offload support to ipoib

Signed-off-by: Eli Cohen <[EMAIL PROTECTED]>
Signed-off-by: Ali Ayub <[EMAIL PROTECTED]>

---

Add checksum offload support to ipoib

Signed-off-by: Eli Cohen <[EMAIL PROTECTED]>
Signed-off-by: Ali Ayub <[EMAIL PROTECTED]>

---

This version make sure that set_tx_csum() and set_rx_csum() get called
before ipoib_dev_init() so that whether NETIF_F_SG is set or not will
properly affect the size the create QP.

Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib.h        
2007-10-14 18:07:31.000000000 +0200
+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib.h     2007-10-14 
18:07:37.000000000 +0200
@@ -87,6 +87,7 @@ enum {
        IPOIB_FLAG_NETIF_STOPPED  = 9,
        IPOIB_FLAG_ADMIN_CM       = 10,
        IPOIB_FLAG_HW_CSUM        = 11,
+       IPOIB_FLAG_RX_CSUM        = 12,
 
        IPOIB_MAX_BACKOFF_SECONDS = 16,
 
Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_cm.c
===================================================================
--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c     
2007-10-14 18:07:31.000000000 +0200
+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_cm.c  2007-10-14 
18:07:37.000000000 +0200
@@ -1262,6 +1262,13 @@ static ssize_t set_mode(struct device *d
                set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
                ipoib_warn(priv, "enabling connected mode "
                           "will cause multicast packet drops\n");
+
+               /* clear ipv6 flag too */
+               dev->features &= ~NETIF_F_IP_CSUM;
+
+               priv->tx_wr.send_flags &=
+                       ~(IB_SEND_UDP_TCP_CSUM | IB_SEND_IP_CSUM);
+
                ipoib_flush_paths(dev);
                return count;
        }
@@ -1270,6 +1277,10 @@ static ssize_t set_mode(struct device *d
                clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
                dev->mtu = min(priv->mcast_mtu, dev->mtu);
                ipoib_flush_paths(dev);
+
+               if (priv->ca->flags & IB_DEVICE_IP_CSUM)
+                       dev->features |= NETIF_F_IP_CSUM; /* ipv6 too */
+
                return count;
        }
 
Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_ib.c
===================================================================
--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c     
2007-10-14 18:07:31.000000000 +0200
+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_ib.c  2007-10-14 
18:07:37.000000000 +0200
@@ -37,6 +37,7 @@
 
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/ip.h>
 
 #include <rdma/ib_cache.h>
 
@@ -235,6 +236,16 @@ static void ipoib_ib_handle_rx_wc(struct
        skb->dev = dev;
        /* XXX get correct PACKET_ type here */
        skb->pkt_type = PACKET_HOST;
+
+       /* check rx csum */
+       if (test_bit(IPOIB_FLAG_RX_CSUM, &priv->flags) && likely(wc->csum_ok)) {
+               /* Note: this is a specific requirement for Mellanox
+                  HW but since it is the only HW currently supporting
+                  checksum offload I put it here */
+               if ((((struct iphdr *)(skb->data))->ihl) == 5)
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+       }
+
        netif_receive_skb(skb);
 
 repost:
@@ -400,6 +411,15 @@ void ipoib_send(struct net_device *dev, 
                return;
        }
 
+       if (priv->ca->flags & IB_DEVICE_IP_CSUM &&
+           skb->ip_summed == CHECKSUM_PARTIAL)
+               priv->tx_wr.send_flags |=
+                       IB_SEND_UDP_TCP_CSUM | IB_SEND_IP_CSUM;
+       else
+               priv->tx_wr.send_flags &=
+                       ~(IB_SEND_UDP_TCP_CSUM | IB_SEND_IP_CSUM);
+
+
        if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
                               address->ah, qpn,
                               tx_req->mapping, skb_headlen(skb),
Index: ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- ofa_1_3_dev_kernel.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c   
2007-10-14 18:07:31.000000000 +0200
+++ ofa_1_3_dev_kernel/drivers/infiniband/ulp/ipoib/ipoib_main.c        
2007-10-14 18:08:10.000000000 +0200
@@ -1128,6 +1128,29 @@ int ipoib_add_pkey_attr(struct net_devic
        return device_create_file(&dev->dev, &dev_attr_pkey);
 }
 
+static void set_tx_csum(struct net_device *dev, struct ib_device *hca)
+{
+       struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+       if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags))
+               return;
+
+       if (!(hca->flags & IB_DEVICE_IP_CSUM))
+               return;
+
+       dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; /* turn on ipv6 too */
+}
+
+static void set_rx_csum(struct net_device *dev, struct ib_device *hca)
+{
+       struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+       if (!(hca->flags & IB_DEVICE_IP_CSUM))
+               return;
+
+       set_bit(IPOIB_FLAG_RX_CSUM, &priv->flags);
+}
+
 static struct net_device *ipoib_add_port(const char *format,
                                         struct ib_device *hca, u8 port)
 {
@@ -1166,6 +1189,8 @@ static struct net_device *ipoib_add_port
        } else
                memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof 
(union ib_gid));
 
+       set_tx_csum(priv->dev, hca);
+       set_rx_csum(priv->dev, hca);
 
        result = ipoib_dev_init(priv->dev, hca, port);
        if (result < 0) {


_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to