diff options
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_main.c')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 83 |
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); | |||
58 | MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); | 58 | MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | struct ipoib_path_iter { | ||
62 | struct net_device *dev; | ||
63 | struct ipoib_path path; | ||
64 | }; | ||
65 | |||
61 | static const u8 ipv4_bcast_addr[] = { | 66 | static 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 | |||
262 | struct 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 | |||
281 | int 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 | |||
310 | void 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 | |||
253 | void ipoib_flush_paths(struct net_device *dev) | 318 | void 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 | ||
989 | sysfs_failed: | 1054 | sysfs_failed: |
990 | ipoib_delete_debug_file(priv->dev); | 1055 | ipoib_delete_debug_files(priv->dev); |
991 | |||
992 | debug_failed: | ||
993 | unregister_netdev(priv->dev); | 1056 | unregister_netdev(priv->dev); |
994 | 1057 | ||
995 | register_failed: | 1058 | register_failed: |