Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
[linux-drm-fsl-dcu.git] / drivers / infiniband / ulp / ipoib / ipoib_main.c
index 475d98fa9e26645c2b76b001d08bbea0fc6d12a7..0ebacd558ff6508919631d214283b8e49fb38897 100644 (file)
@@ -47,6 +47,8 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 
+#include <net/dst.h>
+
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
 MODULE_LICENSE("Dual BSD/GPL");
@@ -103,7 +105,7 @@ int ipoib_open(struct net_device *dev)
                struct ipoib_dev_priv *cpriv;
 
                /* Bring up any child interfaces too */
-               down(&priv->vlan_mutex);
+               mutex_lock(&priv->vlan_mutex);
                list_for_each_entry(cpriv, &priv->child_intfs, list) {
                        int flags;
 
@@ -113,7 +115,7 @@ int ipoib_open(struct net_device *dev)
 
                        dev_change_flags(cpriv->dev, flags | IFF_UP);
                }
-               up(&priv->vlan_mutex);
+               mutex_unlock(&priv->vlan_mutex);
        }
 
        netif_start_queue(dev);
@@ -131,14 +133,20 @@ static int ipoib_stop(struct net_device *dev)
 
        netif_stop_queue(dev);
 
-       ipoib_ib_dev_down(dev);
+       /*
+        * Now flush workqueue to make sure a scheduled task doesn't
+        * bring our internal state back up.
+        */
+       flush_workqueue(ipoib_workqueue);
+
+       ipoib_ib_dev_down(dev, 1);
        ipoib_ib_dev_stop(dev);
 
        if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
                struct ipoib_dev_priv *cpriv;
 
                /* Bring down any child interfaces too */
-               down(&priv->vlan_mutex);
+               mutex_lock(&priv->vlan_mutex);
                list_for_each_entry(cpriv, &priv->child_intfs, list) {
                        int flags;
 
@@ -148,7 +156,7 @@ static int ipoib_stop(struct net_device *dev)
 
                        dev_change_flags(cpriv->dev, flags & ~IFF_UP);
                }
-               up(&priv->vlan_mutex);
+               mutex_unlock(&priv->vlan_mutex);
        }
 
        return 0;
@@ -503,7 +511,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
 
        list_add_tail(&neigh->list, &path->neigh_list);
 
-       if (path->pathrec.dlid) {
+       if (path->ah) {
                kref_get(&path->ah->ref);
                neigh->ah = path->ah;
 
@@ -511,12 +519,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
                           be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
        } else {
                neigh->ah  = NULL;
-               if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
-                       __skb_queue_tail(&neigh->queue, skb);
-               } else {
-                       ++priv->stats.tx_dropped;
-                       dev_kfree_skb_any(skb);
-               }
+               __skb_queue_tail(&neigh->queue, skb);
 
                if (!path->query && path_rec_start(dev, path))
                        goto err;
@@ -589,7 +592,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
                return;
        }
 
-       if (path->pathrec.dlid) {
+       if (path->ah) {
                ipoib_dbg(priv, "Send unicast ARP to %04x\n",
                          be16_to_cpu(path->pathrec.dlid));
 
@@ -890,8 +893,8 @@ static void ipoib_setup(struct net_device *dev)
        spin_lock_init(&priv->lock);
        spin_lock_init(&priv->tx_lock);
 
-       init_MUTEX(&priv->mcast_mutex);
-       init_MUTEX(&priv->vlan_mutex);
+       mutex_init(&priv->mcast_mutex);
+       mutex_init(&priv->vlan_mutex);
 
        INIT_LIST_HEAD(&priv->path_list);
        INIT_LIST_HEAD(&priv->child_intfs);