aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp/ipoib')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h34
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c27
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c28
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c17
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c3
5 files changed, 54 insertions, 55 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 12a1e0572ef2..491d2afaf5b4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -272,8 +272,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
272void ipoib_dev_cleanup(struct net_device *dev); 272void ipoib_dev_cleanup(struct net_device *dev);
273 273
274void ipoib_mcast_join_task(void *dev_ptr); 274void ipoib_mcast_join_task(void *dev_ptr);
275void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, 275void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
276 struct sk_buff *skb);
277 276
278void ipoib_mcast_restart_task(void *dev_ptr); 277void ipoib_mcast_restart_task(void *dev_ptr);
279int ipoib_mcast_start_thread(struct net_device *dev); 278int ipoib_mcast_start_thread(struct net_device *dev);
@@ -369,15 +368,26 @@ extern int ipoib_debug_level;
369#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG_DATA */ 368#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG_DATA */
370 369
371 370
372#define IPOIB_GID_FMT "%x:%x:%x:%x:%x:%x:%x:%x" 371#define IPOIB_GID_FMT "%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:" \
373 372 "%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x"
374#define IPOIB_GID_ARG(gid) be16_to_cpup((__be16 *) ((gid).raw + 0)), \ 373
375 be16_to_cpup((__be16 *) ((gid).raw + 2)), \ 374#define IPOIB_GID_RAW_ARG(gid) ((u8 *)(gid))[0], \
376 be16_to_cpup((__be16 *) ((gid).raw + 4)), \ 375 ((u8 *)(gid))[1], \
377 be16_to_cpup((__be16 *) ((gid).raw + 6)), \ 376 ((u8 *)(gid))[2], \
378 be16_to_cpup((__be16 *) ((gid).raw + 8)), \ 377 ((u8 *)(gid))[3], \
379 be16_to_cpup((__be16 *) ((gid).raw + 10)), \ 378 ((u8 *)(gid))[4], \
380 be16_to_cpup((__be16 *) ((gid).raw + 12)), \ 379 ((u8 *)(gid))[5], \
381 be16_to_cpup((__be16 *) ((gid).raw + 14)) 380 ((u8 *)(gid))[6], \
381 ((u8 *)(gid))[7], \
382 ((u8 *)(gid))[8], \
383 ((u8 *)(gid))[9], \
384 ((u8 *)(gid))[10],\
385 ((u8 *)(gid))[11],\
386 ((u8 *)(gid))[12],\
387 ((u8 *)(gid))[13],\
388 ((u8 *)(gid))[14],\
389 ((u8 *)(gid))[15]
390
391#define IPOIB_GID_ARG(gid) IPOIB_GID_RAW_ARG((gid).raw)
382 392
383#endif /* _IPOIB_H */ 393#endif /* _IPOIB_H */
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 8406839b91cf..5033666b1481 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -84,15 +84,9 @@ void ipoib_free_ah(struct kref *kref)
84 84
85 unsigned long flags; 85 unsigned long flags;
86 86
87 if ((int) priv->tx_tail - (int) ah->last_send >= 0) { 87 spin_lock_irqsave(&priv->lock, flags);
88 ipoib_dbg(priv, "Freeing ah %p\n", ah->ah); 88 list_add_tail(&ah->list, &priv->dead_ahs);
89 ib_destroy_ah(ah->ah); 89 spin_unlock_irqrestore(&priv->lock, flags);
90 kfree(ah);
91 } else {
92 spin_lock_irqsave(&priv->lock, flags);
93 list_add_tail(&ah->list, &priv->dead_ahs);
94 spin_unlock_irqrestore(&priv->lock, flags);
95 }
96} 90}
97 91
98static int ipoib_ib_post_receive(struct net_device *dev, int id) 92static int ipoib_ib_post_receive(struct net_device *dev, int id)
@@ -377,19 +371,16 @@ static void __ipoib_reap_ah(struct net_device *dev)
377 struct ipoib_ah *ah, *tah; 371 struct ipoib_ah *ah, *tah;
378 LIST_HEAD(remove_list); 372 LIST_HEAD(remove_list);
379 373
380 spin_lock_irq(&priv->lock); 374 spin_lock_irq(&priv->tx_lock);
375 spin_lock(&priv->lock);
381 list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list) 376 list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)
382 if ((int) priv->tx_tail - (int) ah->last_send >= 0) { 377 if ((int) priv->tx_tail - (int) ah->last_send >= 0) {
383 list_del(&ah->list); 378 list_del(&ah->list);
384 list_add_tail(&ah->list, &remove_list); 379 ib_destroy_ah(ah->ah);
380 kfree(ah);
385 } 381 }
386 spin_unlock_irq(&priv->lock); 382 spin_unlock(&priv->lock);
387 383 spin_unlock_irq(&priv->tx_lock);
388 list_for_each_entry_safe(ah, tah, &remove_list, list) {
389 ipoib_dbg(priv, "Reaping ah %p\n", ah->ah);
390 ib_destroy_ah(ah->ah);
391 kfree(ah);
392 }
393} 384}
394 385
395void ipoib_reap_ah(void *dev_ptr) 386void ipoib_reap_ah(void *dev_ptr)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index cb078a7d0bf5..1c6ea1c682a5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -185,8 +185,7 @@ static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
185 return 0; 185 return 0;
186} 186}
187 187
188static struct ipoib_path *__path_find(struct net_device *dev, 188static struct ipoib_path *__path_find(struct net_device *dev, void *gid)
189 union ib_gid *gid)
190{ 189{
191 struct ipoib_dev_priv *priv = netdev_priv(dev); 190 struct ipoib_dev_priv *priv = netdev_priv(dev);
192 struct rb_node *n = priv->path_tree.rb_node; 191 struct rb_node *n = priv->path_tree.rb_node;
@@ -196,7 +195,7 @@ static struct ipoib_path *__path_find(struct net_device *dev,
196 while (n) { 195 while (n) {
197 path = rb_entry(n, struct ipoib_path, rb_node); 196 path = rb_entry(n, struct ipoib_path, rb_node);
198 197
199 ret = memcmp(gid->raw, path->pathrec.dgid.raw, 198 ret = memcmp(gid, path->pathrec.dgid.raw,
200 sizeof (union ib_gid)); 199 sizeof (union ib_gid));
201 200
202 if (ret < 0) 201 if (ret < 0)
@@ -424,8 +423,7 @@ static void path_rec_completion(int status,
424 } 423 }
425} 424}
426 425
427static struct ipoib_path *path_rec_create(struct net_device *dev, 426static struct ipoib_path *path_rec_create(struct net_device *dev, void *gid)
428 union ib_gid *gid)
429{ 427{
430 struct ipoib_dev_priv *priv = netdev_priv(dev); 428 struct ipoib_dev_priv *priv = netdev_priv(dev);
431 struct ipoib_path *path; 429 struct ipoib_path *path;
@@ -440,7 +438,7 @@ static struct ipoib_path *path_rec_create(struct net_device *dev,
440 438
441 INIT_LIST_HEAD(&path->neigh_list); 439 INIT_LIST_HEAD(&path->neigh_list);
442 440
443 memcpy(path->pathrec.dgid.raw, gid->raw, sizeof (union ib_gid)); 441 memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid));
444 path->pathrec.sgid = priv->local_gid; 442 path->pathrec.sgid = priv->local_gid;
445 path->pathrec.pkey = cpu_to_be16(priv->pkey); 443 path->pathrec.pkey = cpu_to_be16(priv->pkey);
446 path->pathrec.numb_path = 1; 444 path->pathrec.numb_path = 1;
@@ -498,10 +496,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
498 */ 496 */
499 spin_lock(&priv->lock); 497 spin_lock(&priv->lock);
500 498
501 path = __path_find(dev, (union ib_gid *) (skb->dst->neighbour->ha + 4)); 499 path = __path_find(dev, skb->dst->neighbour->ha + 4);
502 if (!path) { 500 if (!path) {
503 path = path_rec_create(dev, 501 path = path_rec_create(dev, skb->dst->neighbour->ha + 4);
504 (union ib_gid *) (skb->dst->neighbour->ha + 4));
505 if (!path) 502 if (!path)
506 goto err_path; 503 goto err_path;
507 504
@@ -551,7 +548,7 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
551 /* Add in the P_Key for multicasts */ 548 /* Add in the P_Key for multicasts */
552 skb->dst->neighbour->ha[8] = (priv->pkey >> 8) & 0xff; 549 skb->dst->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
553 skb->dst->neighbour->ha[9] = priv->pkey & 0xff; 550 skb->dst->neighbour->ha[9] = priv->pkey & 0xff;
554 ipoib_mcast_send(dev, (union ib_gid *) (skb->dst->neighbour->ha + 4), skb); 551 ipoib_mcast_send(dev, skb->dst->neighbour->ha + 4, skb);
555} 552}
556 553
557static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, 554static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
@@ -566,10 +563,9 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
566 */ 563 */
567 spin_lock(&priv->lock); 564 spin_lock(&priv->lock);
568 565
569 path = __path_find(dev, (union ib_gid *) (phdr->hwaddr + 4)); 566 path = __path_find(dev, phdr->hwaddr + 4);
570 if (!path) { 567 if (!path) {
571 path = path_rec_create(dev, 568 path = path_rec_create(dev, phdr->hwaddr + 4);
572 (union ib_gid *) (phdr->hwaddr + 4));
573 if (path) { 569 if (path) {
574 /* put pseudoheader back on for next time */ 570 /* put pseudoheader back on for next time */
575 skb_push(skb, sizeof *phdr); 571 skb_push(skb, sizeof *phdr);
@@ -660,7 +656,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
660 phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff; 656 phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff;
661 phdr->hwaddr[9] = priv->pkey & 0xff; 657 phdr->hwaddr[9] = priv->pkey & 0xff;
662 658
663 ipoib_mcast_send(dev, (union ib_gid *) (phdr->hwaddr + 4), skb); 659 ipoib_mcast_send(dev, phdr->hwaddr + 4, skb);
664 } else { 660 } else {
665 /* unicast GID -- should be ARP or RARP reply */ 661 /* unicast GID -- should be ARP or RARP reply */
666 662
@@ -671,7 +667,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
671 skb->dst ? "neigh" : "dst", 667 skb->dst ? "neigh" : "dst",
672 be16_to_cpup((__be16 *) skb->data), 668 be16_to_cpup((__be16 *) skb->data),
673 be32_to_cpup((__be32 *) phdr->hwaddr), 669 be32_to_cpup((__be32 *) phdr->hwaddr),
674 IPOIB_GID_ARG(*(union ib_gid *) (phdr->hwaddr + 4))); 670 IPOIB_GID_RAW_ARG(phdr->hwaddr + 4));
675 dev_kfree_skb_any(skb); 671 dev_kfree_skb_any(skb);
676 ++priv->stats.tx_dropped; 672 ++priv->stats.tx_dropped;
677 goto out; 673 goto out;
@@ -754,7 +750,7 @@ static void ipoib_neigh_destructor(struct neighbour *n)
754 ipoib_dbg(priv, 750 ipoib_dbg(priv,
755 "neigh_destructor for %06x " IPOIB_GID_FMT "\n", 751 "neigh_destructor for %06x " IPOIB_GID_FMT "\n",
756 be32_to_cpup((__be32 *) n->ha), 752 be32_to_cpup((__be32 *) n->ha),
757 IPOIB_GID_ARG(*((union ib_gid *) (n->ha + 4)))); 753 IPOIB_GID_RAW_ARG(n->ha + 4));
758 754
759 spin_lock_irqsave(&priv->lock, flags); 755 spin_lock_irqsave(&priv->lock, flags);
760 756
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 1dae4b238252..216471fa01cc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -154,7 +154,7 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev,
154 return mcast; 154 return mcast;
155} 155}
156 156
157static struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, union ib_gid *mgid) 157static struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, void *mgid)
158{ 158{
159 struct ipoib_dev_priv *priv = netdev_priv(dev); 159 struct ipoib_dev_priv *priv = netdev_priv(dev);
160 struct rb_node *n = priv->multicast_tree.rb_node; 160 struct rb_node *n = priv->multicast_tree.rb_node;
@@ -165,7 +165,7 @@ static struct ipoib_mcast *__ipoib_mcast_find(struct net_device *dev, union ib_g
165 165
166 mcast = rb_entry(n, struct ipoib_mcast, rb_node); 166 mcast = rb_entry(n, struct ipoib_mcast, rb_node);
167 167
168 ret = memcmp(mgid->raw, mcast->mcmember.mgid.raw, 168 ret = memcmp(mgid, mcast->mcmember.mgid.raw,
169 sizeof (union ib_gid)); 169 sizeof (union ib_gid));
170 if (ret < 0) 170 if (ret < 0)
171 n = n->rb_left; 171 n = n->rb_left;
@@ -694,8 +694,7 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
694 return 0; 694 return 0;
695} 695}
696 696
697void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid, 697void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
698 struct sk_buff *skb)
699{ 698{
700 struct ipoib_dev_priv *priv = netdev_priv(dev); 699 struct ipoib_dev_priv *priv = netdev_priv(dev);
701 struct ipoib_mcast *mcast; 700 struct ipoib_mcast *mcast;
@@ -718,7 +717,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
718 if (!mcast) { 717 if (!mcast) {
719 /* Let's create a new send only group now */ 718 /* Let's create a new send only group now */
720 ipoib_dbg_mcast(priv, "setting up send only multicast group for " 719 ipoib_dbg_mcast(priv, "setting up send only multicast group for "
721 IPOIB_GID_FMT "\n", IPOIB_GID_ARG(*mgid)); 720 IPOIB_GID_FMT "\n", IPOIB_GID_RAW_ARG(mgid));
722 721
723 mcast = ipoib_mcast_alloc(dev, 0); 722 mcast = ipoib_mcast_alloc(dev, 0);
724 if (!mcast) { 723 if (!mcast) {
@@ -730,7 +729,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
730 } 729 }
731 730
732 set_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags); 731 set_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags);
733 mcast->mcmember.mgid = *mgid; 732 memcpy(mcast->mcmember.mgid.raw, mgid, sizeof (union ib_gid));
734 __ipoib_mcast_add(dev, mcast); 733 __ipoib_mcast_add(dev, mcast);
735 list_add_tail(&mcast->list, &priv->multicast_list); 734 list_add_tail(&mcast->list, &priv->multicast_list);
736 } 735 }
@@ -821,7 +820,8 @@ void ipoib_mcast_restart_task(void *dev_ptr)
821 820
822 ipoib_mcast_stop_thread(dev, 0); 821 ipoib_mcast_stop_thread(dev, 0);
823 822
824 spin_lock_irqsave(&dev->xmit_lock, flags); 823 local_irq_save(flags);
824 netif_tx_lock(dev);
825 spin_lock(&priv->lock); 825 spin_lock(&priv->lock);
826 826
827 /* 827 /*
@@ -896,7 +896,8 @@ void ipoib_mcast_restart_task(void *dev_ptr)
896 } 896 }
897 897
898 spin_unlock(&priv->lock); 898 spin_unlock(&priv->lock);
899 spin_unlock_irqrestore(&dev->xmit_lock, flags); 899 netif_tx_unlock(dev);
900 local_irq_restore(flags);
900 901
901 /* We have to cancel outside of the spinlock */ 902 /* We have to cancel outside of the spinlock */
902 list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { 903 list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 1d49d1643c59..7b717c648f72 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -255,7 +255,8 @@ void ipoib_event(struct ib_event_handler *handler,
255 record->event == IB_EVENT_PKEY_CHANGE || 255 record->event == IB_EVENT_PKEY_CHANGE ||
256 record->event == IB_EVENT_PORT_ACTIVE || 256 record->event == IB_EVENT_PORT_ACTIVE ||
257 record->event == IB_EVENT_LID_CHANGE || 257 record->event == IB_EVENT_LID_CHANGE ||
258 record->event == IB_EVENT_SM_CHANGE) { 258 record->event == IB_EVENT_SM_CHANGE ||
259 record->event == IB_EVENT_CLIENT_REREGISTER) {
259 ipoib_dbg(priv, "Port state change event\n"); 260 ipoib_dbg(priv, "Port state change event\n");
260 queue_work(ipoib_workqueue, &priv->flush_task); 261 queue_work(ipoib_workqueue, &priv->flush_task);
261 } 262 }