[ofa-general] [PATCH v2] IB/ipoib: fix netdev offload features support for child (VLAN) devices

Or Gerlitz ogerlitz at voltaire.com
Thu Oct 16 06:20:50 PDT 2008


Child devices were created without any offload features set, fix this by
moving the code that computes the features into generic function which is
now called through non-child and child device creation.

Signed-off-by: Or Gerlitz <ogerlitz at voltaire.com>

-- v1 has a bug where the 'result' flag in ipoib_vlan_add may be used uninitialized

Index: linux-2.6.27/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- linux-2.6.27.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ linux-2.6.27/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1185,11 +1185,48 @@ int ipoib_add_pkey_attr(struct net_devic
 	return device_create_file(&dev->dev, &dev_attr_pkey);
 }

+int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
+{
+	struct ib_device_attr *device_attr;
+	int result = -ENOMEM;
+
+	device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
+	if (!device_attr) {
+		printk(KERN_WARNING "%s: allocation of %zu bytes failed\n",
+		       hca->name, sizeof *device_attr);
+		return result;
+	}
+
+	result = ib_query_device(hca, device_attr);
+	if (result) {
+		printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n",
+		       hca->name, result);
+		kfree(device_attr);
+		return result;
+	}
+	priv->hca_caps = device_attr->device_cap_flags;
+
+	kfree(device_attr);
+
+	if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
+		set_bit(IPOIB_FLAG_CSUM, &priv->flags);
+		priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+	}
+
+	if (lro)
+		priv->dev->features |= NETIF_F_LRO;
+
+	if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
+		priv->dev->features |= NETIF_F_TSO;
+
+	return 0;
+}
+
+
 static struct net_device *ipoib_add_port(const char *format,
 					 struct ib_device *hca, u8 port)
 {
 	struct ipoib_dev_priv *priv;
-	struct ib_device_attr *device_attr;
 	struct ib_port_attr attr;
 	int result = -ENOMEM;

@@ -1218,31 +1255,8 @@ static struct net_device *ipoib_add_port
 		goto device_init_failed;
 	}

-	device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
-	if (!device_attr) {
-		printk(KERN_WARNING "%s: allocation of %zu bytes failed\n",
-		       hca->name, sizeof *device_attr);
+	if (ipoib_set_dev_features(priv, hca))
 		goto device_init_failed;
-	}
-
-	result = ib_query_device(hca, device_attr);
-	if (result) {
-		printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n",
-		       hca->name, result);
-		kfree(device_attr);
-		goto device_init_failed;
-	}
-	priv->hca_caps = device_attr->device_cap_flags;
-
-	kfree(device_attr);
-
-	if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
-		set_bit(IPOIB_FLAG_CSUM, &priv->flags);
-		priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-	}
-
-	if (lro)
-		priv->dev->features |= NETIF_F_LRO;

 	/*
 	 * Set the full membership bit, so that we join the right
@@ -1278,9 +1292,6 @@ static struct net_device *ipoib_add_port
 		goto event_failed;
 	}

-	if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
-		priv->dev->features |= NETIF_F_TSO;
-
 	result = register_netdev(priv->dev);
 	if (result) {
 		printk(KERN_WARNING "%s: couldn't register ipoib port %d; error %d\n",
Index: linux-2.6.27/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- linux-2.6.27.orig/drivers/infiniband/ulp/ipoib/ipoib.h
+++ linux-2.6.27/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -509,6 +509,7 @@ int ipoib_pkey_dev_delay_open(struct net
 void ipoib_drain_cq(struct net_device *dev);

 void ipoib_set_ethtool_ops(struct net_device *dev);
+int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca);

 #ifdef CONFIG_INFINIBAND_IPOIB_CM

Index: linux-2.6.27/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
===================================================================
--- linux-2.6.27.orig/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ linux-2.6.27/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -93,6 +93,10 @@ int ipoib_vlan_add(struct net_device *pd
 	priv->mcast_mtu  = priv->admin_mtu = priv->dev->mtu;
 	set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);

+	result = ipoib_set_dev_features(priv, ppriv->ca);
+	if (result)
+		goto device_init_failed;
+
 	priv->pkey = pkey;

 	memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN);



More information about the general mailing list