1 /*
2  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16  *
17  * Maintained at www.Open-FCoE.org
18  */
19 
20 #include <linux/types.h>
21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/list.h>
24 #include <linux/netdevice.h>
25 #include <linux/errno.h>
26 #include <linux/crc32.h>
27 #include <scsi/libfcoe.h>
28 
29 #include "libfcoe.h"
30 
31 MODULE_AUTHOR("Open-FCoE.org");
32 MODULE_DESCRIPTION("FIP discovery protocol and FCoE transport for FCoE HBAs");
33 MODULE_LICENSE("GPL v2");
34 
35 static int fcoe_transport_create(const char *, struct kernel_param *);
36 static int fcoe_transport_destroy(const char *, struct kernel_param *);
37 static int fcoe_transport_show(char *buffer, const struct kernel_param *kp);
38 static struct fcoe_transport *fcoe_transport_lookup(struct net_device *device);
39 static struct fcoe_transport *fcoe_netdev_map_lookup(struct net_device *device);
40 static int fcoe_transport_enable(const char *, struct kernel_param *);
41 static int fcoe_transport_disable(const char *, struct kernel_param *);
42 static int libfcoe_device_notification(struct notifier_block *notifier,
43 				    ulong event, void *ptr);
44 
45 static LIST_HEAD(fcoe_transports);
46 static DEFINE_MUTEX(ft_mutex);
47 static LIST_HEAD(fcoe_netdevs);
48 static DEFINE_MUTEX(fn_mutex);
49 
50 unsigned int libfcoe_debug_logging;
51 module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR);
52 MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
53 
54 module_param_call(show, NULL, fcoe_transport_show, NULL, S_IRUSR);
55 __MODULE_PARM_TYPE(show, "string");
56 MODULE_PARM_DESC(show, " Show attached FCoE transports");
57 
58 module_param_call(create, fcoe_transport_create, NULL,
59 		  (void *)FIP_MODE_FABRIC, S_IWUSR);
60 __MODULE_PARM_TYPE(create, "string");
61 MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface");
62 
63 module_param_call(create_vn2vn, fcoe_transport_create, NULL,
64 		  (void *)FIP_MODE_VN2VN, S_IWUSR);
65 __MODULE_PARM_TYPE(create_vn2vn, "string");
66 MODULE_PARM_DESC(create_vn2vn, " Creates a VN_node to VN_node FCoE instance "
67 		 "on an Ethernet interface");
68 
69 module_param_call(destroy, fcoe_transport_destroy, NULL, NULL, S_IWUSR);
70 __MODULE_PARM_TYPE(destroy, "string");
71 MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface");
72 
73 module_param_call(enable, fcoe_transport_enable, NULL, NULL, S_IWUSR);
74 __MODULE_PARM_TYPE(enable, "string");
75 MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface.");
76 
77 module_param_call(disable, fcoe_transport_disable, NULL, NULL, S_IWUSR);
78 __MODULE_PARM_TYPE(disable, "string");
79 MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface.");
80 
81 /* notification function for packets from net device */
82 static struct notifier_block libfcoe_notifier = {
83 	.notifier_call = libfcoe_device_notification,
84 };
85 
86 /**
87  * fcoe_fc_crc() - Calculates the CRC for a given frame
88  * @fp: The frame to be checksumed
89  *
90  * This uses crc32() routine to calculate the CRC for a frame
91  *
92  * Return: The 32 bit CRC value
93  */
94 u32 fcoe_fc_crc(struct fc_frame *fp)
95 {
96 	struct sk_buff *skb = fp_skb(fp);
97 	struct skb_frag_struct *frag;
98 	unsigned char *data;
99 	unsigned long off, len, clen;
100 	u32 crc;
101 	unsigned i;
102 
103 	crc = crc32(~0, skb->data, skb_headlen(skb));
104 
105 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
106 		frag = &skb_shinfo(skb)->frags[i];
107 		off = frag->page_offset;
108 		len = frag->size;
109 		while (len > 0) {
110 			clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
111 			data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
112 					   KM_SKB_DATA_SOFTIRQ);
113 			crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
114 			kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
115 			off += clen;
116 			len -= clen;
117 		}
118 	}
119 	return crc;
120 }
121 EXPORT_SYMBOL_GPL(fcoe_fc_crc);
122 
123 /**
124  * fcoe_start_io() - Start FCoE I/O
125  * @skb: The packet to be transmitted
126  *
127  * This routine is called from the net device to start transmitting
128  * FCoE packets.
129  *
130  * Returns: 0 for success
131  */
132 int fcoe_start_io(struct sk_buff *skb)
133 {
134 	struct sk_buff *nskb;
135 	int rc;
136 
137 	nskb = skb_clone(skb, GFP_ATOMIC);
138 	if (!nskb)
139 		return -ENOMEM;
140 	rc = dev_queue_xmit(nskb);
141 	if (rc != 0)
142 		return rc;
143 	kfree_skb(skb);
144 	return 0;
145 }
146 EXPORT_SYMBOL_GPL(fcoe_start_io);
147 
148 
149 /**
150  * fcoe_clean_pending_queue() - Dequeue a skb and free it
151  * @lport: The local port to dequeue a skb on
152  */
153 void fcoe_clean_pending_queue(struct fc_lport *lport)
154 {
155 	struct fcoe_port  *port = lport_priv(lport);
156 	struct sk_buff *skb;
157 
158 	spin_lock_bh(&port->fcoe_pending_queue.lock);
159 	while ((skb = __skb_dequeue(&port->fcoe_pending_queue)) != NULL) {
160 		spin_unlock_bh(&port->fcoe_pending_queue.lock);
161 		kfree_skb(skb);
162 		spin_lock_bh(&port->fcoe_pending_queue.lock);
163 	}
164 	spin_unlock_bh(&port->fcoe_pending_queue.lock);
165 }
166 EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
167 
168 /**
169  * fcoe_check_wait_queue() - Attempt to clear the transmit backlog
170  * @lport: The local port whose backlog is to be cleared
171  *
172  * This empties the wait_queue, dequeues the head of the wait_queue queue
173  * and calls fcoe_start_io() for each packet. If all skb have been
174  * transmitted it returns the qlen. If an error occurs it restores
175  * wait_queue (to try again later) and returns -1.
176  *
177  * The wait_queue is used when the skb transmit fails. The failed skb
178  * will go in the wait_queue which will be emptied by the timer function or
179  * by the next skb transmit.
180  */
181 void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb)
182 {
183 	struct fcoe_port *port = lport_priv(lport);
184 	int rc;
185 
186 	spin_lock_bh(&port->fcoe_pending_queue.lock);
187 
188 	if (skb)
189 		__skb_queue_tail(&port->fcoe_pending_queue, skb);
190 
191 	if (port->fcoe_pending_queue_active)
192 		goto out;
193 	port->fcoe_pending_queue_active = 1;
194 
195 	while (port->fcoe_pending_queue.qlen) {
196 		/* keep qlen > 0 until fcoe_start_io succeeds */
197 		port->fcoe_pending_queue.qlen++;
198 		skb = __skb_dequeue(&port->fcoe_pending_queue);
199 
200 		spin_unlock_bh(&port->fcoe_pending_queue.lock);
201 		rc = fcoe_start_io(skb);
202 		spin_lock_bh(&port->fcoe_pending_queue.lock);
203 
204 		if (rc) {
205 			__skb_queue_head(&port->fcoe_pending_queue, skb);
206 			/* undo temporary increment above */
207 			port->fcoe_pending_queue.qlen--;
208 			break;
209 		}
210 		/* undo temporary increment above */
211 		port->fcoe_pending_queue.qlen--;
212 	}
213 
214 	if (port->fcoe_pending_queue.qlen < port->min_queue_depth)
215 		lport->qfull = 0;
216 	if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer))
217 		mod_timer(&port->timer, jiffies + 2);
218 	port->fcoe_pending_queue_active = 0;
219 out:
220 	if (port->fcoe_pending_queue.qlen > port->max_queue_depth)
221 		lport->qfull = 1;
222 	spin_unlock_bh(&port->fcoe_pending_queue.lock);
223 }
224 EXPORT_SYMBOL_GPL(fcoe_check_wait_queue);
225 
226 /**
227  * fcoe_queue_timer() - The fcoe queue timer
228  * @lport: The local port
229  *
230  * Calls fcoe_check_wait_queue on timeout
231  */
232 void fcoe_queue_timer(ulong lport)
233 {
234 	fcoe_check_wait_queue((struct fc_lport *)lport, NULL);
235 }
236 EXPORT_SYMBOL_GPL(fcoe_queue_timer);
237 
238 /**
239  * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC
240  * @skb:  The packet to be transmitted
241  * @tlen: The total length of the trailer
242  * @fps:  The fcoe context
243  *
244  * This routine allocates a page for frame trailers. The page is re-used if
245  * there is enough room left on it for the current trailer. If there isn't
246  * enough buffer left a new page is allocated for the trailer. Reference to
247  * the page from this function as well as the skbs using the page fragments
248  * ensure that the page is freed at the appropriate time.
249  *
250  * Returns: 0 for success
251  */
252 int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen,
253 			   struct fcoe_percpu_s *fps)
254 {
255 	struct page *page;
256 
257 	page = fps->crc_eof_page;
258 	if (!page) {
259 		page = alloc_page(GFP_ATOMIC);
260 		if (!page)
261 			return -ENOMEM;
262 
263 		fps->crc_eof_page = page;
264 		fps->crc_eof_offset = 0;
265 	}
266 
267 	get_page(page);
268 	skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
269 			   fps->crc_eof_offset, tlen);
270 	skb->len += tlen;
271 	skb->data_len += tlen;
272 	skb->truesize += tlen;
273 	fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
274 
275 	if (fps->crc_eof_offset >= PAGE_SIZE) {
276 		fps->crc_eof_page = NULL;
277 		fps->crc_eof_offset = 0;
278 		put_page(page);
279 	}
280 
281 	return 0;
282 }
283 EXPORT_SYMBOL_GPL(fcoe_get_paged_crc_eof);
284 
285 /**
286  * fcoe_transport_lookup - find an fcoe transport that matches a netdev
287  * @netdev: The netdev to look for from all attached transports
288  *
289  * Returns : ptr to the fcoe transport that supports this netdev or NULL
290  * if not found.
291  *
292  * The ft_mutex should be held when this is called
293  */
294 static struct fcoe_transport *fcoe_transport_lookup(struct net_device *netdev)
295 {
296 	struct fcoe_transport *ft = NULL;
297 
298 	list_for_each_entry(ft, &fcoe_transports, list)
299 		if (ft->match && ft->match(netdev))
300 			return ft;
301 	return NULL;
302 }
303 
304 /**
305  * fcoe_transport_attach - Attaches an FCoE transport
306  * @ft: The fcoe transport to be attached
307  *
308  * Returns : 0 for success
309  */
310 int fcoe_transport_attach(struct fcoe_transport *ft)
311 {
312 	int rc = 0;
313 
314 	mutex_lock(&ft_mutex);
315 	if (ft->attached) {
316 		LIBFCOE_TRANSPORT_DBG("transport %s already attached\n",
317 				       ft->name);
318 		rc = -EEXIST;
319 		goto out_attach;
320 	}
321 
322 	/* Add default transport to the tail */
323 	if (strcmp(ft->name, FCOE_TRANSPORT_DEFAULT))
324 		list_add(&ft->list, &fcoe_transports);
325 	else
326 		list_add_tail(&ft->list, &fcoe_transports);
327 
328 	ft->attached = true;
329 	LIBFCOE_TRANSPORT_DBG("attaching transport %s\n", ft->name);
330 
331 out_attach:
332 	mutex_unlock(&ft_mutex);
333 	return rc;
334 }
335 EXPORT_SYMBOL(fcoe_transport_attach);
336 
337 /**
338  * fcoe_transport_detach - Detaches an FCoE transport
339  * @ft: The fcoe transport to be attached
340  *
341  * Returns : 0 for success
342  */
343 int fcoe_transport_detach(struct fcoe_transport *ft)
344 {
345 	int rc = 0;
346 	struct fcoe_netdev_mapping *nm = NULL, *tmp;
347 
348 	mutex_lock(&ft_mutex);
349 	if (!ft->attached) {
350 		LIBFCOE_TRANSPORT_DBG("transport %s already detached\n",
351 			ft->name);
352 		rc = -ENODEV;
353 		goto out_attach;
354 	}
355 
356 	/* remove netdev mapping for this transport as it is going away */
357 	mutex_lock(&fn_mutex);
358 	list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) {
359 		if (nm->ft == ft) {
360 			LIBFCOE_TRANSPORT_DBG("transport %s going away, "
361 				"remove its netdev mapping for %s\n",
362 				ft->name, nm->netdev->name);
363 			list_del(&nm->list);
364 			kfree(nm);
365 		}
366 	}
367 	mutex_unlock(&fn_mutex);
368 
369 	list_del(&ft->list);
370 	ft->attached = false;
371 	LIBFCOE_TRANSPORT_DBG("detaching transport %s\n", ft->name);
372 
373 out_attach:
374 	mutex_unlock(&ft_mutex);
375 	return rc;
376 
377 }
378 EXPORT_SYMBOL(fcoe_transport_detach);
379 
380 static int fcoe_transport_show(char *buffer, const struct kernel_param *kp)
381 {
382 	int i, j;
383 	struct fcoe_transport *ft = NULL;
384 
385 	i = j = sprintf(buffer, "Attached FCoE transports:");
386 	mutex_lock(&ft_mutex);
387 	list_for_each_entry(ft, &fcoe_transports, list) {
388 		if (i >= PAGE_SIZE - IFNAMSIZ)
389 			break;
390 		i += snprintf(&buffer[i], IFNAMSIZ, "%s ", ft->name);
391 	}
392 	mutex_unlock(&ft_mutex);
393 	if (i == j)
394 		i += snprintf(&buffer[i], IFNAMSIZ, "none");
395 	return i;
396 }
397 
398 static int __init fcoe_transport_init(void)
399 {
400 	register_netdevice_notifier(&libfcoe_notifier);
401 	return 0;
402 }
403 
404 static int __exit fcoe_transport_exit(void)
405 {
406 	struct fcoe_transport *ft;
407 
408 	unregister_netdevice_notifier(&libfcoe_notifier);
409 	mutex_lock(&ft_mutex);
410 	list_for_each_entry(ft, &fcoe_transports, list)
411 		printk(KERN_ERR "FCoE transport %s is still attached!\n",
412 		      ft->name);
413 	mutex_unlock(&ft_mutex);
414 	return 0;
415 }
416 
417 
418 static int fcoe_add_netdev_mapping(struct net_device *netdev,
419 					struct fcoe_transport *ft)
420 {
421 	struct fcoe_netdev_mapping *nm;
422 
423 	nm = kmalloc(sizeof(*nm), GFP_KERNEL);
424 	if (!nm) {
425 		printk(KERN_ERR "Unable to allocate netdev_mapping");
426 		return -ENOMEM;
427 	}
428 
429 	nm->netdev = netdev;
430 	nm->ft = ft;
431 
432 	mutex_lock(&fn_mutex);
433 	list_add(&nm->list, &fcoe_netdevs);
434 	mutex_unlock(&fn_mutex);
435 	return 0;
436 }
437 
438 
439 static void fcoe_del_netdev_mapping(struct net_device *netdev)
440 {
441 	struct fcoe_netdev_mapping *nm = NULL, *tmp;
442 
443 	mutex_lock(&fn_mutex);
444 	list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) {
445 		if (nm->netdev == netdev) {
446 			list_del(&nm->list);
447 			kfree(nm);
448 			mutex_unlock(&fn_mutex);
449 			return;
450 		}
451 	}
452 	mutex_unlock(&fn_mutex);
453 }
454 
455 
456 /**
457  * fcoe_netdev_map_lookup - find the fcoe transport that matches the netdev on which
458  * it was created
459  *
460  * Returns : ptr to the fcoe transport that supports this netdev or NULL
461  * if not found.
462  *
463  * The ft_mutex should be held when this is called
464  */
465 static struct fcoe_transport *fcoe_netdev_map_lookup(struct net_device *netdev)
466 {
467 	struct fcoe_transport *ft = NULL;
468 	struct fcoe_netdev_mapping *nm;
469 
470 	mutex_lock(&fn_mutex);
471 	list_for_each_entry(nm, &fcoe_netdevs, list) {
472 		if (netdev == nm->netdev) {
473 			ft = nm->ft;
474 			mutex_unlock(&fn_mutex);
475 			return ft;
476 		}
477 	}
478 
479 	mutex_unlock(&fn_mutex);
480 	return NULL;
481 }
482 
483 /**
484  * fcoe_if_to_netdev() - Parse a name buffer to get a net device
485  * @buffer: The name of the net device
486  *
487  * Returns: NULL or a ptr to net_device
488  */
489 static struct net_device *fcoe_if_to_netdev(const char *buffer)
490 {
491 	char *cp;
492 	char ifname[IFNAMSIZ + 2];
493 
494 	if (buffer) {
495 		strlcpy(ifname, buffer, IFNAMSIZ);
496 		cp = ifname + strlen(ifname);
497 		while (--cp >= ifname && *cp == '\n')
498 			*cp = '\0';
499 		return dev_get_by_name(&init_net, ifname);
500 	}
501 	return NULL;
502 }
503 
504 /**
505  * libfcoe_device_notification() - Handler for net device events
506  * @notifier: The context of the notification
507  * @event:    The type of event
508  * @ptr:      The net device that the event was on
509  *
510  * This function is called by the Ethernet driver in case of link change event.
511  *
512  * Returns: 0 for success
513  */
514 static int libfcoe_device_notification(struct notifier_block *notifier,
515 				    ulong event, void *ptr)
516 {
517 	struct net_device *netdev = ptr;
518 
519 	switch (event) {
520 	case NETDEV_UNREGISTER:
521 		printk(KERN_ERR "libfcoe_device_notification: NETDEV_UNREGISTER %s\n",
522 				netdev->name);
523 		fcoe_del_netdev_mapping(netdev);
524 		break;
525 	}
526 	return NOTIFY_OK;
527 }
528 
529 
530 /**
531  * fcoe_transport_create() - Create a fcoe interface
532  * @buffer: The name of the Ethernet interface to create on
533  * @kp:	    The associated kernel param
534  *
535  * Called from sysfs. This holds the ft_mutex while calling the
536  * registered fcoe transport's create function.
537  *
538  * Returns: 0 for success
539  */
540 static int fcoe_transport_create(const char *buffer, struct kernel_param *kp)
541 {
542 	int rc = -ENODEV;
543 	struct net_device *netdev = NULL;
544 	struct fcoe_transport *ft = NULL;
545 	enum fip_state fip_mode = (enum fip_state)(long)kp->arg;
546 
547 	mutex_lock(&ft_mutex);
548 
549 	netdev = fcoe_if_to_netdev(buffer);
550 	if (!netdev) {
551 		LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buffer);
552 		goto out_nodev;
553 	}
554 
555 	ft = fcoe_netdev_map_lookup(netdev);
556 	if (ft) {
557 		LIBFCOE_TRANSPORT_DBG("transport %s already has existing "
558 				      "FCoE instance on %s.\n",
559 				      ft->name, netdev->name);
560 		rc = -EEXIST;
561 		goto out_putdev;
562 	}
563 
564 	ft = fcoe_transport_lookup(netdev);
565 	if (!ft) {
566 		LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
567 				      netdev->name);
568 		goto out_putdev;
569 	}
570 
571 	rc = fcoe_add_netdev_mapping(netdev, ft);
572 	if (rc) {
573 		LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping "
574 				      "for FCoE transport %s for %s.\n",
575 				      ft->name, netdev->name);
576 		goto out_putdev;
577 	}
578 
579 	/* pass to transport create */
580 	rc = ft->create ? ft->create(netdev, fip_mode) : -ENODEV;
581 	if (rc)
582 		fcoe_del_netdev_mapping(netdev);
583 
584 	LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n",
585 			      ft->name, (rc) ? "failed" : "succeeded",
586 			      netdev->name);
587 
588 out_putdev:
589 	dev_put(netdev);
590 out_nodev:
591 	mutex_unlock(&ft_mutex);
592 	return rc;
593 }
594 
595 /**
596  * fcoe_transport_destroy() - Destroy a FCoE interface
597  * @buffer: The name of the Ethernet interface to be destroyed
598  * @kp:	    The associated kernel parameter
599  *
600  * Called from sysfs. This holds the ft_mutex while calling the
601  * registered fcoe transport's destroy function.
602  *
603  * Returns: 0 for success
604  */
605 static int fcoe_transport_destroy(const char *buffer, struct kernel_param *kp)
606 {
607 	int rc = -ENODEV;
608 	struct net_device *netdev = NULL;
609 	struct fcoe_transport *ft = NULL;
610 
611 	mutex_lock(&ft_mutex);
612 
613 	netdev = fcoe_if_to_netdev(buffer);
614 	if (!netdev) {
615 		LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buffer);
616 		goto out_nodev;
617 	}
618 
619 	ft = fcoe_netdev_map_lookup(netdev);
620 	if (!ft) {
621 		LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
622 				      netdev->name);
623 		goto out_putdev;
624 	}
625 
626 	/* pass to transport destroy */
627 	rc = ft->destroy ? ft->destroy(netdev) : -ENODEV;
628 	fcoe_del_netdev_mapping(netdev);
629 	LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n",
630 			      ft->name, (rc) ? "failed" : "succeeded",
631 			      netdev->name);
632 
633 out_putdev:
634 	dev_put(netdev);
635 out_nodev:
636 	mutex_unlock(&ft_mutex);
637 	return rc;
638 }
639 
640 /**
641  * fcoe_transport_disable() - Disables a FCoE interface
642  * @buffer: The name of the Ethernet interface to be disabled
643  * @kp:	    The associated kernel parameter
644  *
645  * Called from sysfs.
646  *
647  * Returns: 0 for success
648  */
649 static int fcoe_transport_disable(const char *buffer, struct kernel_param *kp)
650 {
651 	int rc = -ENODEV;
652 	struct net_device *netdev = NULL;
653 	struct fcoe_transport *ft = NULL;
654 
655 	mutex_lock(&ft_mutex);
656 
657 	netdev = fcoe_if_to_netdev(buffer);
658 	if (!netdev)
659 		goto out_nodev;
660 
661 	ft = fcoe_netdev_map_lookup(netdev);
662 	if (!ft)
663 		goto out_putdev;
664 
665 	rc = ft->disable ? ft->disable(netdev) : -ENODEV;
666 
667 out_putdev:
668 	dev_put(netdev);
669 out_nodev:
670 	mutex_unlock(&ft_mutex);
671 
672 	if (rc == -ERESTARTSYS)
673 		return restart_syscall();
674 	else
675 		return rc;
676 }
677 
678 /**
679  * fcoe_transport_enable() - Enables a FCoE interface
680  * @buffer: The name of the Ethernet interface to be enabled
681  * @kp:     The associated kernel parameter
682  *
683  * Called from sysfs.
684  *
685  * Returns: 0 for success
686  */
687 static int fcoe_transport_enable(const char *buffer, struct kernel_param *kp)
688 {
689 	int rc = -ENODEV;
690 	struct net_device *netdev = NULL;
691 	struct fcoe_transport *ft = NULL;
692 
693 	mutex_lock(&ft_mutex);
694 
695 	netdev = fcoe_if_to_netdev(buffer);
696 	if (!netdev)
697 		goto out_nodev;
698 
699 	ft = fcoe_netdev_map_lookup(netdev);
700 	if (!ft)
701 		goto out_putdev;
702 
703 	rc = ft->enable ? ft->enable(netdev) : -ENODEV;
704 
705 out_putdev:
706 	dev_put(netdev);
707 out_nodev:
708 	mutex_unlock(&ft_mutex);
709 	return rc;
710 }
711 
712 /**
713  * libfcoe_init() - Initialization routine for libfcoe.ko
714  */
715 static int __init libfcoe_init(void)
716 {
717 	fcoe_transport_init();
718 
719 	return 0;
720 }
721 module_init(libfcoe_init);
722 
723 /**
724  * libfcoe_exit() - Tear down libfcoe.ko
725  */
726 static void __exit libfcoe_exit(void)
727 {
728 	fcoe_transport_exit();
729 }
730 module_exit(libfcoe_exit);
731