[ofa-general] [PATCH] ipoib checksum offload

Eli Cohen eli at mellanox.co.il
Sun Aug 12 04:44:11 PDT 2007


Add high checksum offload support to ipoib

Signed-off-by: Eli Cohen <eli at mellnaox.co.il>
Signed-off-by: Ali Ayub <ali at mellnaox.co.il>

---

Index: linux-2.6.23-rc1/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- linux-2.6.23-rc1.orig/drivers/infiniband/ulp/ipoib/ipoib.h	2007-08-08 12:15:53.000000000 +0300
+++ linux-2.6.23-rc1/drivers/infiniband/ulp/ipoib/ipoib.h	2007-08-08 19:12:27.000000000 +0300
@@ -86,6 +86,7 @@ enum {
 	IPOIB_MCAST_STARTED       = 8,
 	IPOIB_FLAG_NETIF_STOPPED  = 9,
 	IPOIB_FLAG_ADMIN_CM 	  = 10,
+	IPOIB_FLAG_RX_CSUM        = 11,
 
 	IPOIB_MAX_BACKOFF_SECONDS = 16,
 
@@ -298,6 +299,8 @@ struct ipoib_dev_priv {
 	struct dentry *mcg_dentry;
 	struct dentry *path_dentry;
 #endif
+	unsigned long long rx_csum_pkts_good;
+	unsigned long long rx_csum_pkts_err;
 };
 
 struct ipoib_ah {
Index: linux-2.6.23-rc1/drivers/infiniband/ulp/ipoib/ipoib_cm.c
===================================================================
--- linux-2.6.23-rc1.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2007-08-08 12:15:53.000000000 +0300
+++ linux-2.6.23-rc1/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2007-08-08 12:23:11.000000000 +0300
@@ -1252,6 +1252,9 @@ static ssize_t set_mode(struct device *d
 	/* flush paths if we switch modes so that connections are restarted */
 	if (IPOIB_CM_SUPPORTED(dev->dev_addr) && !strcmp(buf, "connected\n")) {
 		set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
+		/* on CM mode, turn off tx_csum offloading */
+		dev->features &= ~NETIF_F_HW_CSUM;
+		priv->tx_wr.send_flags &= ~IB_SEND_UDP_TCP_CSUM;
 		ipoib_warn(priv, "enabling connected mode "
 			   "will cause multicast packet drops\n");
 		ipoib_flush_paths(dev);
Index: linux-2.6.23-rc1/drivers/infiniband/ulp/ipoib/ipoib_ib.c
===================================================================
--- linux-2.6.23-rc1.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2007-08-08 12:15:53.000000000 +0300
+++ linux-2.6.23-rc1/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2007-08-08 19:12:27.000000000 +0300
@@ -37,6 +37,7 @@
 
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/ip.h>
 
 #include <rdma/ib_cache.h>
 
@@ -231,6 +232,20 @@ 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))
+		if (likely(ntohs(skb->protocol) == ETH_P_IP  &&
+			   /* no IP header options */
+			   ip_hdr(skb)->ihl == 5 	     &&
+			   wc->checksum == 0xffff)) {
+			if (likely(wc->checksum_ok)) {
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+				++priv->rx_csum_pkts_good;
+			} else
+				++priv->rx_csum_pkts_err;
+		}
+
 	netif_receive_skb(skb);
 
 repost:
Index: linux-2.6.23-rc1/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- linux-2.6.23-rc1.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c	2007-08-08 12:15:53.000000000 +0300
+++ linux-2.6.23-rc1/drivers/infiniband/ulp/ipoib/ipoib_main.c	2007-08-08 19:14:12.000000000 +0300
@@ -1068,6 +1068,65 @@ int ipoib_add_pkey_attr(struct net_devic
 	return device_create_file(&dev->dev, &dev_attr_pkey);
 }
 
+static ssize_t show_tx_csum(struct device *d, struct device_attribute *attr,
+			    char *buf)
+{
+	struct net_device *dev = to_net_dev(d);
+
+	return sprintf(buf, dev->features & NETIF_F_HW_CSUM ? "on\n" : "off\n");
+}
+
+static int set_tx_csum(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags))
+		return -EINVAL;
+
+	if (!(priv->ca->flags & IB_DEVICE_IP_CSUM))
+		return -EINVAL;
+
+	dev->features |= NETIF_F_HW_CSUM;
+	priv->tx_wr.send_flags |= IB_SEND_UDP_TCP_CSUM | IB_SEND_IP_CSUM;
+	return 0;
+}
+
+static DEVICE_ATTR(tx_csum, S_IWUSR | S_IRUGO, show_tx_csum, NULL);
+
+static ssize_t show_rx_csum(struct device *d,
+			    struct device_attribute *attr,
+			    char *buf)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(d));
+
+	return sprintf(buf, test_bit(IPOIB_FLAG_RX_CSUM, &priv->flags) ? "on\n" : "off\n");
+}
+
+static void set_rx_csum(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	if (!(priv->ca->flags & IB_DEVICE_IP_CSUM))
+		return;
+
+	set_bit(IPOIB_FLAG_RX_CSUM, &priv->flags);
+}
+
+static DEVICE_ATTR(rx_csum, S_IWUSR | S_IRUGO, show_rx_csum, NULL);
+
+static ssize_t show_rx_csum_stats(struct device *d, struct device_attribute *attr,
+				  char *buf)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(d));
+
+	return sprintf(buf, "csum_pkts_good %llu\n"
+			    "csum_pkts_err  %llu\n",
+		       priv->rx_csum_pkts_good,
+		       priv->rx_csum_pkts_err);
+}
+
+static DEVICE_ATTR(rx_csum_stats, S_IRUGO, show_rx_csum_stats, NULL);
+
 static struct net_device *ipoib_add_port(const char *format,
 					 struct ib_device *hca, u8 port)
 {
@@ -1083,7 +1142,7 @@ static struct net_device *ipoib_add_port
 
 	pdev = to_pci_dev(hca->dma_device);
 	if (pdev->dma_mask & DMA_64BIT_MASK)
-		priv->dev->features |= NETIF_F_HIGHDMA | NETIF_F_SG;
+		priv->dev->features |= NETIF_F_HIGHDMA;
 
 	result = ib_query_pkey(hca, port, 0, &priv->pkey);
 	if (result) {
@@ -1127,6 +1186,11 @@ static struct net_device *ipoib_add_port
 		goto event_failed;
 	}
 
+	if (!set_tx_csum(priv->dev))
+		priv->dev->features |= NETIF_F_SG;
+
+	set_rx_csum(priv->dev);
+
 	result = register_netdev(priv->dev);
 	if (result) {
 		printk(KERN_WARNING "%s: couldn't register ipoib port %d; error %d\n",
@@ -1144,6 +1208,12 @@ static struct net_device *ipoib_add_port
 		goto sysfs_failed;
 	if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
 		goto sysfs_failed;
+	if (device_create_file(&priv->dev->dev, &dev_attr_tx_csum))
+		goto sysfs_failed;
+	if (device_create_file(&priv->dev->dev, &dev_attr_rx_csum))
+		goto sysfs_failed;
+	if (device_create_file(&priv->dev->dev, &dev_attr_rx_csum_stats))
+		goto sysfs_failed;
 
 	return priv->dev;
 




More information about the general mailing list