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 <[EMAIL PROTECTED]>

-- 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);
_______________________________________________
general mailing list
general@lists.openfabrics.org
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

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

Reply via email to