aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib/ipoib_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_main.c')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c83
1 files changed, 73 insertions, 10 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index ce0296273e76..475d98fa9e26 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -58,6 +58,11 @@ module_param_named(debug_level, ipoib_debug_level, int, 0644);
58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); 58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
59#endif 59#endif
60 60
61struct ipoib_path_iter {
62 struct net_device *dev;
63 struct ipoib_path path;
64};
65
61static const u8 ipv4_bcast_addr[] = { 66static const u8 ipv4_bcast_addr[] = {
62 0x00, 0xff, 0xff, 0xff, 67 0x00, 0xff, 0xff, 0xff,
63 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00, 68 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
@@ -89,8 +94,10 @@ int ipoib_open(struct net_device *dev)
89 if (ipoib_ib_dev_open(dev)) 94 if (ipoib_ib_dev_open(dev))
90 return -EINVAL; 95 return -EINVAL;
91 96
92 if (ipoib_ib_dev_up(dev)) 97 if (ipoib_ib_dev_up(dev)) {
98 ipoib_ib_dev_stop(dev);
93 return -EINVAL; 99 return -EINVAL;
100 }
94 101
95 if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { 102 if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
96 struct ipoib_dev_priv *cpriv; 103 struct ipoib_dev_priv *cpriv;
@@ -250,6 +257,64 @@ static void path_free(struct net_device *dev, struct ipoib_path *path)
250 kfree(path); 257 kfree(path);
251} 258}
252 259
260#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
261
262struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev)
263{
264 struct ipoib_path_iter *iter;
265
266 iter = kmalloc(sizeof *iter, GFP_KERNEL);
267 if (!iter)
268 return NULL;
269
270 iter->dev = dev;
271 memset(iter->path.pathrec.dgid.raw, 0, 16);
272
273 if (ipoib_path_iter_next(iter)) {
274 kfree(iter);
275 return NULL;
276 }
277
278 return iter;
279}
280
281int ipoib_path_iter_next(struct ipoib_path_iter *iter)
282{
283 struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
284 struct rb_node *n;
285 struct ipoib_path *path;
286 int ret = 1;
287
288 spin_lock_irq(&priv->lock);
289
290 n = rb_first(&priv->path_tree);
291
292 while (n) {
293 path = rb_entry(n, struct ipoib_path, rb_node);
294
295 if (memcmp(iter->path.pathrec.dgid.raw, path->pathrec.dgid.raw,
296 sizeof (union ib_gid)) < 0) {
297 iter->path = *path;
298 ret = 0;
299 break;
300 }
301
302 n = rb_next(n);
303 }
304
305 spin_unlock_irq(&priv->lock);
306
307 return ret;
308}
309
310void ipoib_path_iter_read(struct ipoib_path_iter *iter,
311 struct ipoib_path *path)
312{
313 *path = iter->path;
314}
315
316#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
317
253void ipoib_flush_paths(struct net_device *dev) 318void ipoib_flush_paths(struct net_device *dev)
254{ 319{
255 struct ipoib_dev_priv *priv = netdev_priv(dev); 320 struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -335,9 +400,9 @@ static void path_rec_completion(int status,
335 while ((skb = __skb_dequeue(&neigh->queue))) 400 while ((skb = __skb_dequeue(&neigh->queue)))
336 __skb_queue_tail(&skqueue, skb); 401 __skb_queue_tail(&skqueue, skb);
337 } 402 }
338 } else 403 }
339 path->query = NULL;
340 404
405 path->query = NULL;
341 complete(&path->done); 406 complete(&path->done);
342 407
343 spin_unlock_irqrestore(&priv->lock, flags); 408 spin_unlock_irqrestore(&priv->lock, flags);
@@ -365,7 +430,6 @@ static struct ipoib_path *path_rec_create(struct net_device *dev,
365 skb_queue_head_init(&path->queue); 430 skb_queue_head_init(&path->queue);
366 431
367 INIT_LIST_HEAD(&path->neigh_list); 432 INIT_LIST_HEAD(&path->neigh_list);
368 init_completion(&path->done);
369 433
370 memcpy(path->pathrec.dgid.raw, gid->raw, sizeof (union ib_gid)); 434 memcpy(path->pathrec.dgid.raw, gid->raw, sizeof (union ib_gid));
371 path->pathrec.sgid = priv->local_gid; 435 path->pathrec.sgid = priv->local_gid;
@@ -383,6 +447,8 @@ static int path_rec_start(struct net_device *dev,
383 ipoib_dbg(priv, "Start path record lookup for " IPOIB_GID_FMT "\n", 447 ipoib_dbg(priv, "Start path record lookup for " IPOIB_GID_FMT "\n",
384 IPOIB_GID_ARG(path->pathrec.dgid)); 448 IPOIB_GID_ARG(path->pathrec.dgid));
385 449
450 init_completion(&path->done);
451
386 path->query_id = 452 path->query_id =
387 ib_sa_path_rec_get(priv->ca, priv->port, 453 ib_sa_path_rec_get(priv->ca, priv->port,
388 &path->pathrec, 454 &path->pathrec,
@@ -763,7 +829,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
763{ 829{
764 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv; 830 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv;
765 831
766 ipoib_delete_debug_file(dev); 832 ipoib_delete_debug_files(dev);
767 833
768 /* Delete any child interfaces first */ 834 /* Delete any child interfaces first */
769 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) { 835 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
@@ -972,8 +1038,7 @@ static struct net_device *ipoib_add_port(const char *format,
972 goto register_failed; 1038 goto register_failed;
973 } 1039 }
974 1040
975 if (ipoib_create_debug_file(priv->dev)) 1041 ipoib_create_debug_files(priv->dev);
976 goto debug_failed;
977 1042
978 if (ipoib_add_pkey_attr(priv->dev)) 1043 if (ipoib_add_pkey_attr(priv->dev))
979 goto sysfs_failed; 1044 goto sysfs_failed;
@@ -987,9 +1052,7 @@ static struct net_device *ipoib_add_port(const char *format,
987 return priv->dev; 1052 return priv->dev;
988 1053
989sysfs_failed: 1054sysfs_failed:
990 ipoib_delete_debug_file(priv->dev); 1055 ipoib_delete_debug_files(priv->dev);
991
992debug_failed:
993 unregister_netdev(priv->dev); 1056 unregister_netdev(priv->dev);
994 1057
995register_failed: 1058register_failed: