]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/infiniband/ulp/ipoib/ipoib_main.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux...
[linux-2.6-omap-h63xx.git] / drivers / infiniband / ulp / ipoib / ipoib_main.c
index a082466f4a83d58858120addcd7dbb77c73fb47f..bd07f02cf02be6e36864db79fca3494d8a9bed05 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/vmalloc.h>
 
 #include <linux/if_arp.h>      /* For ARPHRD_xxx */
 
@@ -358,8 +359,7 @@ void ipoib_flush_paths(struct net_device *dev)
        spin_lock_irq(&priv->tx_lock);
        spin_lock(&priv->lock);
 
-       list_splice(&priv->path_list, &remove_list);
-       INIT_LIST_HEAD(&priv->path_list);
+       list_splice_init(&priv->path_list, &remove_list);
 
        list_for_each_entry(path, &remove_list, list)
                rb_erase(&path->rb_node, &priv->path_tree);
@@ -680,12 +680,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
                neigh = *to_ipoib_neigh(skb->dst->neighbour);
 
-               if (ipoib_cm_get(neigh)) {
-                       if (ipoib_cm_up(neigh)) {
-                               ipoib_cm_send(dev, skb, ipoib_cm_get(neigh));
-                               goto out;
-                       }
-               } else if (neigh->ah) {
+               if (neigh->ah)
                        if (unlikely((memcmp(&neigh->dgid.raw,
                                            skb->dst->neighbour->ha + 4,
                                            sizeof(union ib_gid))) ||
@@ -706,6 +701,12 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                goto out;
                        }
 
+               if (ipoib_cm_get(neigh)) {
+                       if (ipoib_cm_up(neigh)) {
+                               ipoib_cm_send(dev, skb, ipoib_cm_get(neigh));
+                               goto out;
+                       }
+               } else if (neigh->ah) {
                        ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha));
                        goto out;
                }
@@ -813,11 +814,9 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
        struct ipoib_ah *ah = NULL;
 
        neigh = *to_ipoib_neigh(n);
-       if (neigh) {
+       if (neigh)
                priv = netdev_priv(neigh->dev);
-               ipoib_dbg(priv, "neigh_destructor for bonding device: %s\n",
-                         n->dev->name);
-       } else
+       else
                return;
        ipoib_dbg(priv,
                  "neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
@@ -888,13 +887,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
                goto out;
        }
 
-       priv->tx_ring = kzalloc(ipoib_sendq_size * sizeof *priv->tx_ring,
-                               GFP_KERNEL);
+       priv->tx_ring = vmalloc(ipoib_sendq_size * sizeof *priv->tx_ring);
        if (!priv->tx_ring) {
                printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n",
                       ca->name, ipoib_sendq_size);
                goto out_rx_ring_cleanup;
        }
+       memset(priv->tx_ring, 0, ipoib_sendq_size * sizeof *priv->tx_ring);
 
        /* priv->tx_head, tx_tail & tx_outstanding are already 0 */
 
@@ -904,7 +903,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
        return 0;
 
 out_tx_ring_cleanup:
-       kfree(priv->tx_ring);
+       vfree(priv->tx_ring);
 
 out_rx_ring_cleanup:
        kfree(priv->rx_ring);
@@ -929,7 +928,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
        ipoib_ib_dev_cleanup(dev);
 
        kfree(priv->rx_ring);
-       kfree(priv->tx_ring);
+       vfree(priv->tx_ring);
 
        priv->rx_ring = NULL;
        priv->tx_ring = NULL;
@@ -952,6 +951,8 @@ static void ipoib_setup(struct net_device *dev)
        dev->set_multicast_list  = ipoib_set_mcast_list;
        dev->neigh_setup         = ipoib_neigh_setup_dev;
 
+       ipoib_set_ethtool_ops(dev);
+
        netif_napi_add(dev, &priv->napi, ipoib_poll, 100);
 
        dev->watchdog_timeo      = HZ;
@@ -966,7 +967,9 @@ static void ipoib_setup(struct net_device *dev)
        dev->addr_len            = INFINIBAND_ALEN;
        dev->type                = ARPHRD_INFINIBAND;
        dev->tx_queue_len        = ipoib_sendq_size * 2;
-       dev->features            = NETIF_F_VLAN_CHALLENGED | NETIF_F_LLTX;
+       dev->features            = (NETIF_F_VLAN_CHALLENGED     |
+                                   NETIF_F_LLTX                |
+                                   NETIF_F_HIGHDMA);
 
        /* MTU will be reset when mcast join happens */
        dev->mtu                 = IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN;
@@ -1103,6 +1106,7 @@ 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;
        int result = -ENOMEM;
 
        priv = ipoib_intf_alloc(format);
@@ -1118,6 +1122,29 @@ static struct net_device *ipoib_add_port(const char *format,
                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);
+               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;
+       }
+
        /*
         * Set the full membership bit, so that we join the right
         * broadcast group, etc.
@@ -1135,7 +1162,6 @@ static struct net_device *ipoib_add_port(const char *format,
        } else
                memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid));
 
-
        result = ipoib_dev_init(priv->dev, hca, port);
        if (result < 0) {
                printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n",
@@ -1153,6 +1179,9 @@ static struct net_device *ipoib_add_port(const char *format,
                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",