IPoIB: Test for NULL broadcast object in ipiob_mcast_join_finish()
[cascardo/linux.git] / drivers / infiniband / ulp / ipoib / ipoib_multicast.c
index 9bcfc7a..3f663fb 100644 (file)
@@ -194,7 +194,13 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
        /* Set the cached Q_Key before we attach if it's the broadcast group */
        if (!memcmp(mcast->mcmember.mgid.raw, priv->dev->broadcast + 4,
                    sizeof (union ib_gid))) {
+               spin_lock_irq(&priv->lock);
+               if (!priv->broadcast) {
+                       spin_unlock_irq(&priv->lock);
+                       return -EAGAIN;
+               }
                priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey);
+               spin_unlock_irq(&priv->lock);
                priv->tx_wr.wr.ud.remote_qkey = priv->qkey;
        }
 
@@ -567,8 +573,7 @@ void ipoib_mcast_join_task(struct work_struct *work)
                return;
        }
 
-       priv->mcast_mtu = ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu) -
-               IPOIB_ENCAP_LEN;
+       priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu));
 
        if (!ipoib_cm_admin_enabled(dev))
                dev->mtu = min(priv->mcast_mtu, priv->admin_mtu);
@@ -650,7 +655,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
         */
        spin_lock(&priv->lock);
 
-       if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags)        ||
+       if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)         ||
            !priv->broadcast                                    ||
            !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
                ++dev->stats.tx_dropped;
@@ -702,7 +707,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
 
 out:
        if (mcast && mcast->ah) {
-               if (skb->dst            &&
+               if (skb->dst            &&
                    skb->dst->neighbour &&
                    !*to_ipoib_neigh(skb->dst->neighbour)) {
                        struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour,
@@ -710,7 +715,7 @@ out:
 
                        if (neigh) {
                                kref_get(&mcast->ah->ref);
-                               neigh->ah       = mcast->ah;
+                               neigh->ah       = mcast->ah;
                                list_add_tail(&neigh->list, &mcast->neigh_list);
                        }
                }
@@ -788,10 +793,6 @@ void ipoib_mcast_restart_task(struct work_struct *work)
 
                memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid);
 
-               /* Add in the P_Key */
-               mgid.raw[4] = (priv->pkey >> 8) & 0xff;
-               mgid.raw[5] = priv->pkey & 0xff;
-
                mcast = __ipoib_mcast_find(dev, &mgid);
                if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
                        struct ipoib_mcast *nmcast;