xref: /linux/drivers/scsi/fcoe/fcoe_transport.c (revision af1737dab07c861c3de4576f19dcfbd8f2329eb8)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
4  *
5  * Maintained at www.Open-FCoE.org
6  */
7 
8 #include <linux/types.h>
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/list.h>
12 #include <linux/netdevice.h>
13 #include <linux/ethtool.h>
14 #include <linux/errno.h>
15 #include <linux/crc32.h>
16 #include <scsi/libfcoe.h>
17 
18 #include "libfcoe.h"
19 
20 MODULE_AUTHOR("Open-FCoE.org");
21 MODULE_DESCRIPTION("FIP discovery protocol and FCoE transport for FCoE HBAs");
22 MODULE_LICENSE("GPL v2");
23 
24 static int fcoe_transport_create(const char *, const struct kernel_param *);
25 static int fcoe_transport_destroy(const char *, const struct kernel_param *);
26 static int fcoe_transport_show(char *buffer, const struct kernel_param *kp);
27 static struct fcoe_transport *fcoe_transport_lookup(struct net_device *device);
28 static struct fcoe_transport *fcoe_netdev_map_lookup(struct net_device *device);
29 static int fcoe_transport_enable(const char *, const struct kernel_param *);
30 static int fcoe_transport_disable(const char *, const struct kernel_param *);
31 static int libfcoe_device_notification(struct notifier_block *notifier,
32 				    ulong event, void *ptr);
33 
34 static LIST_HEAD(fcoe_transports);
35 static DEFINE_MUTEX(ft_mutex);
36 static LIST_HEAD(fcoe_netdevs);
37 static DEFINE_MUTEX(fn_mutex);
38 
39 unsigned int libfcoe_debug_logging;
40 module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR);
41 MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
42 
43 module_param_call(show, NULL, fcoe_transport_show, NULL, S_IRUSR);
44 __MODULE_PARM_TYPE(show, "string");
45 MODULE_PARM_DESC(show, " Show attached FCoE transports");
46 
47 module_param_call(create, fcoe_transport_create, NULL,
48 		  (void *)FIP_MODE_FABRIC, S_IWUSR);
49 __MODULE_PARM_TYPE(create, "string");
50 MODULE_PARM_DESC(create, " Creates fcoe instance on an ethernet interface");
51 
52 module_param_call(create_vn2vn, fcoe_transport_create, NULL,
53 		  (void *)FIP_MODE_VN2VN, S_IWUSR);
54 __MODULE_PARM_TYPE(create_vn2vn, "string");
55 MODULE_PARM_DESC(create_vn2vn, " Creates a VN_node to VN_node FCoE instance "
56 		 "on an Ethernet interface");
57 
58 module_param_call(destroy, fcoe_transport_destroy, NULL, NULL, S_IWUSR);
59 __MODULE_PARM_TYPE(destroy, "string");
60 MODULE_PARM_DESC(destroy, " Destroys fcoe instance on an ethernet interface");
61 
62 module_param_call(enable, fcoe_transport_enable, NULL, NULL, S_IWUSR);
63 __MODULE_PARM_TYPE(enable, "string");
64 MODULE_PARM_DESC(enable, " Enables fcoe on an ethernet interface.");
65 
66 module_param_call(disable, fcoe_transport_disable, NULL, NULL, S_IWUSR);
67 __MODULE_PARM_TYPE(disable, "string");
68 MODULE_PARM_DESC(disable, " Disables fcoe on an ethernet interface.");
69 
70 /* notification function for packets from net device */
71 static struct notifier_block libfcoe_notifier = {
72 	.notifier_call = libfcoe_device_notification,
73 };
74 
75 static const struct {
76 	u32 fc_port_speed;
77 #define SPEED_2000	2000
78 #define SPEED_4000	4000
79 #define SPEED_8000	8000
80 #define SPEED_16000	16000
81 #define SPEED_32000	32000
82 	u32 eth_port_speed;
83 } fcoe_port_speed_mapping[] = {
84 	{ FC_PORTSPEED_1GBIT,   SPEED_1000   },
85 	{ FC_PORTSPEED_2GBIT,   SPEED_2000   },
86 	{ FC_PORTSPEED_4GBIT,   SPEED_4000   },
87 	{ FC_PORTSPEED_8GBIT,   SPEED_8000   },
88 	{ FC_PORTSPEED_10GBIT,  SPEED_10000  },
89 	{ FC_PORTSPEED_16GBIT,  SPEED_16000  },
90 	{ FC_PORTSPEED_20GBIT,  SPEED_20000  },
91 	{ FC_PORTSPEED_25GBIT,  SPEED_25000  },
92 	{ FC_PORTSPEED_32GBIT,  SPEED_32000  },
93 	{ FC_PORTSPEED_40GBIT,  SPEED_40000  },
94 	{ FC_PORTSPEED_50GBIT,  SPEED_50000  },
95 	{ FC_PORTSPEED_100GBIT, SPEED_100000 },
96 };
97 
98 static inline u32 eth2fc_speed(u32 eth_port_speed)
99 {
100 	int i;
101 
102 	for (i = 0; i < ARRAY_SIZE(fcoe_port_speed_mapping); i++) {
103 		if (fcoe_port_speed_mapping[i].eth_port_speed == eth_port_speed)
104 			return fcoe_port_speed_mapping[i].fc_port_speed;
105 	}
106 
107 	return FC_PORTSPEED_UNKNOWN;
108 }
109 
110 /**
111  * fcoe_link_speed_update() - Update the supported and actual link speeds
112  * @lport: The local port to update speeds for
113  *
114  * Caller must hold the netdev's ops lock.
115  *
116  * Returns: 0 if the ethtool query was successful
117  *          -1 if the ethtool query failed
118  */
119 int fcoe_link_speed_update(struct fc_lport *lport)
120 {
121 	struct net_device *netdev = fcoe_get_netdev(lport);
122 	struct ethtool_link_ksettings ecmd;
123 
124 	if (!netif_get_link_ksettings(netdev, &ecmd)) {
125 		lport->link_supported_speeds &= ~(FC_PORTSPEED_1GBIT  |
126 		                                  FC_PORTSPEED_10GBIT |
127 		                                  FC_PORTSPEED_20GBIT |
128 		                                  FC_PORTSPEED_40GBIT);
129 
130 		if (ecmd.link_modes.supported[0] & (
131 			    SUPPORTED_1000baseT_Half |
132 			    SUPPORTED_1000baseT_Full |
133 			    SUPPORTED_1000baseKX_Full))
134 			lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
135 
136 		if (ecmd.link_modes.supported[0] & (
137 			    SUPPORTED_10000baseT_Full   |
138 			    SUPPORTED_10000baseKX4_Full |
139 			    SUPPORTED_10000baseKR_Full  |
140 			    SUPPORTED_10000baseR_FEC))
141 			lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
142 
143 		if (ecmd.link_modes.supported[0] & (
144 			    SUPPORTED_20000baseMLD2_Full |
145 			    SUPPORTED_20000baseKR2_Full))
146 			lport->link_supported_speeds |= FC_PORTSPEED_20GBIT;
147 
148 		if (ecmd.link_modes.supported[0] & (
149 			    SUPPORTED_40000baseKR4_Full |
150 			    SUPPORTED_40000baseCR4_Full |
151 			    SUPPORTED_40000baseSR4_Full |
152 			    SUPPORTED_40000baseLR4_Full))
153 			lport->link_supported_speeds |= FC_PORTSPEED_40GBIT;
154 
155 		lport->link_speed = eth2fc_speed(ecmd.base.speed);
156 		return 0;
157 	}
158 	return -1;
159 }
160 EXPORT_SYMBOL_GPL(fcoe_link_speed_update);
161 
162 /**
163  * __fcoe_get_lesb() - Get the Link Error Status Block (LESB) for a given lport
164  * @lport: The local port to update speeds for
165  * @fc_lesb: Pointer to the LESB to be filled up
166  * @netdev: Pointer to the netdev that is associated with the lport
167  *
168  * Note, the Link Error Status Block (LESB) for FCoE is defined in FC-BB-6
169  * Clause 7.11 in v1.04.
170  */
171 void __fcoe_get_lesb(struct fc_lport *lport,
172 		     struct fc_els_lesb *fc_lesb,
173 		     struct net_device *netdev)
174 {
175 	unsigned int cpu;
176 	u32 lfc, vlfc, mdac;
177 	struct fc_stats *stats;
178 	struct fcoe_fc_els_lesb *lesb;
179 	struct rtnl_link_stats64 temp;
180 
181 	lfc = 0;
182 	vlfc = 0;
183 	mdac = 0;
184 	lesb = (struct fcoe_fc_els_lesb *)fc_lesb;
185 	memset(lesb, 0, sizeof(*lesb));
186 	for_each_possible_cpu(cpu) {
187 		stats = per_cpu_ptr(lport->stats, cpu);
188 		lfc += READ_ONCE(stats->LinkFailureCount);
189 		vlfc += READ_ONCE(stats->VLinkFailureCount);
190 		mdac += READ_ONCE(stats->MissDiscAdvCount);
191 	}
192 	lesb->lesb_link_fail = htonl(lfc);
193 	lesb->lesb_vlink_fail = htonl(vlfc);
194 	lesb->lesb_miss_fka = htonl(mdac);
195 	lesb->lesb_fcs_error =
196 			htonl(dev_get_stats(netdev, &temp)->rx_crc_errors);
197 }
198 EXPORT_SYMBOL_GPL(__fcoe_get_lesb);
199 
200 /**
201  * fcoe_get_lesb() - Fill the FCoE Link Error Status Block
202  * @lport: the local port
203  * @fc_lesb: the link error status block
204  */
205 void fcoe_get_lesb(struct fc_lport *lport,
206 			 struct fc_els_lesb *fc_lesb)
207 {
208 	struct net_device *netdev = fcoe_get_netdev(lport);
209 
210 	__fcoe_get_lesb(lport, fc_lesb, netdev);
211 }
212 EXPORT_SYMBOL_GPL(fcoe_get_lesb);
213 
214 /**
215  * fcoe_ctlr_get_lesb() - Get the Link Error Status Block (LESB) for a given
216  * fcoe controller device
217  * @ctlr_dev: The given fcoe controller device
218  *
219  */
220 void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
221 {
222 	struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
223 	struct net_device *netdev = fcoe_get_netdev(fip->lp);
224 	struct fc_els_lesb *fc_lesb;
225 
226 	fc_lesb = (struct fc_els_lesb *)(&ctlr_dev->lesb);
227 	__fcoe_get_lesb(fip->lp, fc_lesb, netdev);
228 }
229 EXPORT_SYMBOL_GPL(fcoe_ctlr_get_lesb);
230 
231 void fcoe_wwn_to_str(u64 wwn, char *buf, int len)
232 {
233 	u8 wwpn[8];
234 
235 	u64_to_wwn(wwn, wwpn);
236 	snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x",
237 		 wwpn[0], wwpn[1], wwpn[2], wwpn[3],
238 		 wwpn[4], wwpn[5], wwpn[6], wwpn[7]);
239 }
240 EXPORT_SYMBOL_GPL(fcoe_wwn_to_str);
241 
242 /**
243  * fcoe_validate_vport_create() - Validate a vport before creating it
244  * @vport: NPIV port to be created
245  *
246  * This routine is meant to add validation for a vport before creating it
247  * via fcoe_vport_create().
248  * Current validations are:
249  *      - WWPN supplied is unique for given lport
250  */
251 int fcoe_validate_vport_create(struct fc_vport *vport)
252 {
253 	struct Scsi_Host *shost = vport_to_shost(vport);
254 	struct fc_lport *n_port = shost_priv(shost);
255 	struct fc_lport *vn_port;
256 	int rc = 0;
257 	char buf[32];
258 
259 	mutex_lock(&n_port->lp_mutex);
260 
261 	fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf));
262 	/* Check if the wwpn is not same as that of the lport */
263 	if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) {
264 		LIBFCOE_TRANSPORT_DBG("vport WWPN 0x%s is same as that of the "
265 				      "base port WWPN\n", buf);
266 		rc = -EINVAL;
267 		goto out;
268 	}
269 
270 	/* Check if there is any existing vport with same wwpn */
271 	list_for_each_entry(vn_port, &n_port->vports, list) {
272 		if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) {
273 			LIBFCOE_TRANSPORT_DBG("vport with given WWPN 0x%s "
274 					      "already exists\n", buf);
275 			rc = -EINVAL;
276 			break;
277 		}
278 	}
279 out:
280 	mutex_unlock(&n_port->lp_mutex);
281 	return rc;
282 }
283 EXPORT_SYMBOL_GPL(fcoe_validate_vport_create);
284 
285 /**
286  * fcoe_get_wwn() - Get the world wide name from LLD if it supports it
287  * @netdev: the associated net device
288  * @wwn: the output WWN
289  * @type: the type of WWN (WWPN or WWNN)
290  *
291  * Returns: 0 for success
292  */
293 int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
294 {
295 	const struct net_device_ops *ops = netdev->netdev_ops;
296 
297 	if (ops->ndo_fcoe_get_wwn)
298 		return ops->ndo_fcoe_get_wwn(netdev, wwn, type);
299 	return -EINVAL;
300 }
301 EXPORT_SYMBOL_GPL(fcoe_get_wwn);
302 
303 /**
304  * fcoe_fc_crc() - Calculates the CRC for a given frame
305  * @fp: The frame to be checksumed
306  *
307  * This uses crc32() routine to calculate the CRC for a frame
308  *
309  * Return: The 32 bit CRC value
310  */
311 u32 fcoe_fc_crc(struct fc_frame *fp)
312 {
313 	struct sk_buff *skb = fp_skb(fp);
314 	skb_frag_t *frag;
315 	unsigned char *data;
316 	unsigned long off, len, clen;
317 	u32 crc;
318 	unsigned i;
319 
320 	crc = crc32(~0, skb->data, skb_headlen(skb));
321 
322 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
323 		frag = &skb_shinfo(skb)->frags[i];
324 		off = skb_frag_off(frag);
325 		len = skb_frag_size(frag);
326 		while (len > 0) {
327 			clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
328 			data = kmap_atomic(
329 				skb_frag_page(frag) + (off >> PAGE_SHIFT));
330 			crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
331 			kunmap_atomic(data);
332 			off += clen;
333 			len -= clen;
334 		}
335 	}
336 	return crc;
337 }
338 EXPORT_SYMBOL_GPL(fcoe_fc_crc);
339 
340 /**
341  * fcoe_start_io() - Start FCoE I/O
342  * @skb: The packet to be transmitted
343  *
344  * This routine is called from the net device to start transmitting
345  * FCoE packets.
346  *
347  * Returns: 0 for success
348  */
349 int fcoe_start_io(struct sk_buff *skb)
350 {
351 	struct sk_buff *nskb;
352 	int rc;
353 
354 	nskb = skb_clone(skb, GFP_ATOMIC);
355 	if (!nskb)
356 		return -ENOMEM;
357 	rc = dev_queue_xmit(nskb);
358 	if (rc != 0)
359 		return rc;
360 	kfree_skb(skb);
361 	return 0;
362 }
363 EXPORT_SYMBOL_GPL(fcoe_start_io);
364 
365 
366 /**
367  * fcoe_clean_pending_queue() - Dequeue a skb and free it
368  * @lport: The local port to dequeue a skb on
369  */
370 void fcoe_clean_pending_queue(struct fc_lport *lport)
371 {
372 	struct fcoe_port  *port = lport_priv(lport);
373 	struct sk_buff *skb;
374 
375 	spin_lock_bh(&port->fcoe_pending_queue.lock);
376 	while ((skb = __skb_dequeue(&port->fcoe_pending_queue)) != NULL) {
377 		spin_unlock_bh(&port->fcoe_pending_queue.lock);
378 		kfree_skb(skb);
379 		spin_lock_bh(&port->fcoe_pending_queue.lock);
380 	}
381 	spin_unlock_bh(&port->fcoe_pending_queue.lock);
382 }
383 EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
384 
385 /**
386  * fcoe_check_wait_queue() - Attempt to clear the transmit backlog
387  * @lport: The local port whose backlog is to be cleared
388  * @skb: The received FIP packet
389  *
390  * This empties the wait_queue, dequeues the head of the wait_queue queue
391  * and calls fcoe_start_io() for each packet. If all skb have been
392  * transmitted it returns the qlen. If an error occurs it restores
393  * wait_queue (to try again later) and returns -1.
394  *
395  * The wait_queue is used when the skb transmit fails. The failed skb
396  * will go in the wait_queue which will be emptied by the timer function or
397  * by the next skb transmit.
398  */
399 void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb)
400 {
401 	struct fcoe_port *port = lport_priv(lport);
402 	int rc;
403 
404 	spin_lock_bh(&port->fcoe_pending_queue.lock);
405 
406 	if (skb)
407 		__skb_queue_tail(&port->fcoe_pending_queue, skb);
408 
409 	if (port->fcoe_pending_queue_active)
410 		goto out;
411 	port->fcoe_pending_queue_active = 1;
412 
413 	while (port->fcoe_pending_queue.qlen) {
414 		/* keep qlen > 0 until fcoe_start_io succeeds */
415 		port->fcoe_pending_queue.qlen++;
416 		skb = __skb_dequeue(&port->fcoe_pending_queue);
417 
418 		spin_unlock_bh(&port->fcoe_pending_queue.lock);
419 		rc = fcoe_start_io(skb);
420 		spin_lock_bh(&port->fcoe_pending_queue.lock);
421 
422 		if (rc) {
423 			__skb_queue_head(&port->fcoe_pending_queue, skb);
424 			/* undo temporary increment above */
425 			port->fcoe_pending_queue.qlen--;
426 			break;
427 		}
428 		/* undo temporary increment above */
429 		port->fcoe_pending_queue.qlen--;
430 	}
431 
432 	if (port->fcoe_pending_queue.qlen < port->min_queue_depth)
433 		lport->qfull = 0;
434 	if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer))
435 		mod_timer(&port->timer, jiffies + 2);
436 	port->fcoe_pending_queue_active = 0;
437 out:
438 	if (port->fcoe_pending_queue.qlen > port->max_queue_depth)
439 		lport->qfull = 1;
440 	spin_unlock_bh(&port->fcoe_pending_queue.lock);
441 }
442 EXPORT_SYMBOL_GPL(fcoe_check_wait_queue);
443 
444 /**
445  * fcoe_queue_timer() - The fcoe queue timer
446  * @t: Timer context use to obtain the FCoE port
447  *
448  * Calls fcoe_check_wait_queue on timeout
449  */
450 void fcoe_queue_timer(struct timer_list *t)
451 {
452 	struct fcoe_port *port = timer_container_of(port, t, timer);
453 
454 	fcoe_check_wait_queue(port->lport, NULL);
455 }
456 EXPORT_SYMBOL_GPL(fcoe_queue_timer);
457 
458 /**
459  * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC
460  * @skb:  The packet to be transmitted
461  * @tlen: The total length of the trailer
462  * @fps:  The fcoe context
463  *
464  * This routine allocates a page for frame trailers. The page is re-used if
465  * there is enough room left on it for the current trailer. If there isn't
466  * enough buffer left a new page is allocated for the trailer. Reference to
467  * the page from this function as well as the skbs using the page fragments
468  * ensure that the page is freed at the appropriate time.
469  *
470  * Returns: 0 for success
471  */
472 int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen,
473 			   struct fcoe_percpu_s *fps)
474 {
475 	struct page *page;
476 
477 	page = fps->crc_eof_page;
478 	if (!page) {
479 		page = alloc_page(GFP_ATOMIC);
480 		if (!page)
481 			return -ENOMEM;
482 
483 		fps->crc_eof_page = page;
484 		fps->crc_eof_offset = 0;
485 	}
486 
487 	get_page(page);
488 	skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
489 			   fps->crc_eof_offset, tlen);
490 	skb->len += tlen;
491 	skb->data_len += tlen;
492 	skb->truesize += tlen;
493 	fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
494 
495 	if (fps->crc_eof_offset >= PAGE_SIZE) {
496 		fps->crc_eof_page = NULL;
497 		fps->crc_eof_offset = 0;
498 		put_page(page);
499 	}
500 
501 	return 0;
502 }
503 EXPORT_SYMBOL_GPL(fcoe_get_paged_crc_eof);
504 
505 /**
506  * fcoe_transport_lookup - find an fcoe transport that matches a netdev
507  * @netdev: The netdev to look for from all attached transports
508  *
509  * Returns : ptr to the fcoe transport that supports this netdev or NULL
510  * if not found.
511  *
512  * The ft_mutex should be held when this is called
513  */
514 static struct fcoe_transport *fcoe_transport_lookup(struct net_device *netdev)
515 {
516 	struct fcoe_transport *ft = NULL;
517 
518 	list_for_each_entry(ft, &fcoe_transports, list)
519 		if (ft->match && ft->match(netdev))
520 			return ft;
521 	return NULL;
522 }
523 
524 /**
525  * fcoe_transport_attach - Attaches an FCoE transport
526  * @ft: The fcoe transport to be attached
527  *
528  * Returns : 0 for success
529  */
530 int fcoe_transport_attach(struct fcoe_transport *ft)
531 {
532 	int rc = 0;
533 
534 	mutex_lock(&ft_mutex);
535 	if (ft->attached) {
536 		LIBFCOE_TRANSPORT_DBG("transport %s already attached\n",
537 				       ft->name);
538 		rc = -EEXIST;
539 		goto out_attach;
540 	}
541 
542 	/* Add default transport to the tail */
543 	if (strcmp(ft->name, FCOE_TRANSPORT_DEFAULT))
544 		list_add(&ft->list, &fcoe_transports);
545 	else
546 		list_add_tail(&ft->list, &fcoe_transports);
547 
548 	ft->attached = true;
549 	LIBFCOE_TRANSPORT_DBG("attaching transport %s\n", ft->name);
550 
551 out_attach:
552 	mutex_unlock(&ft_mutex);
553 	return rc;
554 }
555 EXPORT_SYMBOL(fcoe_transport_attach);
556 
557 /**
558  * fcoe_transport_detach - Detaches an FCoE transport
559  * @ft: The fcoe transport to be attached
560  *
561  * Returns : 0 for success
562  */
563 int fcoe_transport_detach(struct fcoe_transport *ft)
564 {
565 	int rc = 0;
566 	struct fcoe_netdev_mapping *nm = NULL, *tmp;
567 
568 	mutex_lock(&ft_mutex);
569 	if (!ft->attached) {
570 		LIBFCOE_TRANSPORT_DBG("transport %s already detached\n",
571 			ft->name);
572 		rc = -ENODEV;
573 		goto out_attach;
574 	}
575 
576 	/* remove netdev mapping for this transport as it is going away */
577 	mutex_lock(&fn_mutex);
578 	list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) {
579 		if (nm->ft == ft) {
580 			LIBFCOE_TRANSPORT_DBG("transport %s going away, "
581 				"remove its netdev mapping for %s\n",
582 				ft->name, nm->netdev->name);
583 			list_del(&nm->list);
584 			kfree(nm);
585 		}
586 	}
587 	mutex_unlock(&fn_mutex);
588 
589 	list_del(&ft->list);
590 	ft->attached = false;
591 	LIBFCOE_TRANSPORT_DBG("detaching transport %s\n", ft->name);
592 
593 out_attach:
594 	mutex_unlock(&ft_mutex);
595 	return rc;
596 
597 }
598 EXPORT_SYMBOL(fcoe_transport_detach);
599 
600 static int fcoe_transport_show(char *buffer, const struct kernel_param *kp)
601 {
602 	int i, j;
603 	struct fcoe_transport *ft = NULL;
604 
605 	i = j = sprintf(buffer, "Attached FCoE transports:");
606 	mutex_lock(&ft_mutex);
607 	list_for_each_entry(ft, &fcoe_transports, list) {
608 		if (i >= PAGE_SIZE - IFNAMSIZ)
609 			break;
610 		i += snprintf(&buffer[i], IFNAMSIZ, "%s ", ft->name);
611 	}
612 	mutex_unlock(&ft_mutex);
613 	if (i == j)
614 		i += snprintf(&buffer[i], IFNAMSIZ, "none");
615 	return i;
616 }
617 
618 static int __init fcoe_transport_init(void)
619 {
620 	register_netdevice_notifier(&libfcoe_notifier);
621 	return 0;
622 }
623 
624 static int fcoe_transport_exit(void)
625 {
626 	struct fcoe_transport *ft;
627 
628 	unregister_netdevice_notifier(&libfcoe_notifier);
629 	mutex_lock(&ft_mutex);
630 	list_for_each_entry(ft, &fcoe_transports, list)
631 		printk(KERN_ERR "FCoE transport %s is still attached!\n",
632 		      ft->name);
633 	mutex_unlock(&ft_mutex);
634 	return 0;
635 }
636 
637 
638 static int fcoe_add_netdev_mapping(struct net_device *netdev,
639 					struct fcoe_transport *ft)
640 {
641 	struct fcoe_netdev_mapping *nm;
642 
643 	nm = kmalloc_obj(*nm);
644 	if (!nm) {
645 		printk(KERN_ERR "Unable to allocate netdev_mapping");
646 		return -ENOMEM;
647 	}
648 
649 	nm->netdev = netdev;
650 	nm->ft = ft;
651 
652 	mutex_lock(&fn_mutex);
653 	list_add(&nm->list, &fcoe_netdevs);
654 	mutex_unlock(&fn_mutex);
655 	return 0;
656 }
657 
658 
659 static void fcoe_del_netdev_mapping(struct net_device *netdev)
660 {
661 	struct fcoe_netdev_mapping *nm = NULL, *tmp;
662 
663 	mutex_lock(&fn_mutex);
664 	list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) {
665 		if (nm->netdev == netdev) {
666 			list_del(&nm->list);
667 			kfree(nm);
668 			mutex_unlock(&fn_mutex);
669 			return;
670 		}
671 	}
672 	mutex_unlock(&fn_mutex);
673 }
674 
675 
676 /**
677  * fcoe_netdev_map_lookup - find the fcoe transport that matches the netdev on which
678  * it was created
679  * @netdev: The net device that the FCoE interface is on
680  *
681  * Returns : ptr to the fcoe transport that supports this netdev or NULL
682  * if not found.
683  *
684  * The ft_mutex should be held when this is called
685  */
686 static struct fcoe_transport *fcoe_netdev_map_lookup(struct net_device *netdev)
687 {
688 	struct fcoe_transport *ft = NULL;
689 	struct fcoe_netdev_mapping *nm;
690 
691 	mutex_lock(&fn_mutex);
692 	list_for_each_entry(nm, &fcoe_netdevs, list) {
693 		if (netdev == nm->netdev) {
694 			ft = nm->ft;
695 			mutex_unlock(&fn_mutex);
696 			return ft;
697 		}
698 	}
699 
700 	mutex_unlock(&fn_mutex);
701 	return NULL;
702 }
703 
704 /**
705  * fcoe_if_to_netdev() - Parse a name buffer to get a net device
706  * @buffer: The name of the net device
707  *
708  * Returns: NULL or a ptr to net_device
709  */
710 static struct net_device *fcoe_if_to_netdev(const char *buffer)
711 {
712 	char *cp;
713 	char ifname[IFNAMSIZ + 2];
714 
715 	if (buffer) {
716 		strscpy(ifname, buffer, IFNAMSIZ);
717 		cp = ifname + strlen(ifname);
718 		while (--cp >= ifname && *cp == '\n')
719 			*cp = '\0';
720 		return dev_get_by_name(&init_net, ifname);
721 	}
722 	return NULL;
723 }
724 
725 /**
726  * libfcoe_device_notification() - Handler for net device events
727  * @notifier: The context of the notification
728  * @event:    The type of event
729  * @ptr:      The net device that the event was on
730  *
731  * This function is called by the Ethernet driver in case of link change event.
732  *
733  * Returns: 0 for success
734  */
735 static int libfcoe_device_notification(struct notifier_block *notifier,
736 				    ulong event, void *ptr)
737 {
738 	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
739 
740 	switch (event) {
741 	case NETDEV_UNREGISTER:
742 		LIBFCOE_TRANSPORT_DBG("NETDEV_UNREGISTER %s\n",
743 				      netdev->name);
744 		fcoe_del_netdev_mapping(netdev);
745 		break;
746 	}
747 	return NOTIFY_OK;
748 }
749 
750 ssize_t fcoe_ctlr_create_store(const char *buf, size_t count)
751 {
752 	struct net_device *netdev = NULL;
753 	struct fcoe_transport *ft = NULL;
754 	int rc = 0;
755 	int err;
756 
757 	mutex_lock(&ft_mutex);
758 
759 	netdev = fcoe_if_to_netdev(buf);
760 	if (!netdev) {
761 		LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buf);
762 		rc = -ENODEV;
763 		goto out_nodev;
764 	}
765 
766 	ft = fcoe_netdev_map_lookup(netdev);
767 	if (ft) {
768 		LIBFCOE_TRANSPORT_DBG("transport %s already has existing "
769 				      "FCoE instance on %s.\n",
770 				      ft->name, netdev->name);
771 		rc = -EEXIST;
772 		goto out_putdev;
773 	}
774 
775 	ft = fcoe_transport_lookup(netdev);
776 	if (!ft) {
777 		LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
778 				      netdev->name);
779 		rc = -ENODEV;
780 		goto out_putdev;
781 	}
782 
783 	/* pass to transport create */
784 	err = ft->alloc ? ft->alloc(netdev) : -ENODEV;
785 	if (err) {
786 		fcoe_del_netdev_mapping(netdev);
787 		rc = -ENOMEM;
788 		goto out_putdev;
789 	}
790 
791 	err = fcoe_add_netdev_mapping(netdev, ft);
792 	if (err) {
793 		LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping "
794 				      "for FCoE transport %s for %s.\n",
795 				      ft->name, netdev->name);
796 		rc = -ENODEV;
797 		goto out_putdev;
798 	}
799 
800 	LIBFCOE_TRANSPORT_DBG("transport %s succeeded to create fcoe on %s.\n",
801 			      ft->name, netdev->name);
802 
803 out_putdev:
804 	dev_put(netdev);
805 out_nodev:
806 	mutex_unlock(&ft_mutex);
807 	if (rc)
808 		return rc;
809 	return count;
810 }
811 
812 ssize_t fcoe_ctlr_destroy_store(const char *buf, size_t count)
813 {
814 	int rc = -ENODEV;
815 	struct net_device *netdev = NULL;
816 	struct fcoe_transport *ft = NULL;
817 
818 	mutex_lock(&ft_mutex);
819 
820 	netdev = fcoe_if_to_netdev(buf);
821 	if (!netdev) {
822 		LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buf);
823 		goto out_nodev;
824 	}
825 
826 	ft = fcoe_netdev_map_lookup(netdev);
827 	if (!ft) {
828 		LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
829 				      netdev->name);
830 		goto out_putdev;
831 	}
832 
833 	/* pass to transport destroy */
834 	rc = ft->destroy(netdev);
835 	if (rc)
836 		goto out_putdev;
837 
838 	fcoe_del_netdev_mapping(netdev);
839 	LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n",
840 			      ft->name, (rc) ? "failed" : "succeeded",
841 			      netdev->name);
842 	rc = count; /* required for successful return */
843 out_putdev:
844 	dev_put(netdev);
845 out_nodev:
846 	mutex_unlock(&ft_mutex);
847 	return rc;
848 }
849 
850 /**
851  * fcoe_transport_create() - Create a fcoe interface
852  * @buffer: The name of the Ethernet interface to create on
853  * @kp:	    The associated kernel param
854  *
855  * Called from sysfs. This holds the ft_mutex while calling the
856  * registered fcoe transport's create function.
857  *
858  * Returns: 0 for success
859  */
860 static int fcoe_transport_create(const char *buffer,
861 				 const struct kernel_param *kp)
862 {
863 	int rc = -ENODEV;
864 	struct net_device *netdev = NULL;
865 	struct fcoe_transport *ft = NULL;
866 	enum fip_mode fip_mode = (enum fip_mode)(uintptr_t)kp->arg;
867 
868 	mutex_lock(&ft_mutex);
869 
870 	netdev = fcoe_if_to_netdev(buffer);
871 	if (!netdev) {
872 		LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buffer);
873 		goto out_nodev;
874 	}
875 
876 	ft = fcoe_netdev_map_lookup(netdev);
877 	if (ft) {
878 		LIBFCOE_TRANSPORT_DBG("transport %s already has existing "
879 				      "FCoE instance on %s.\n",
880 				      ft->name, netdev->name);
881 		rc = -EEXIST;
882 		goto out_putdev;
883 	}
884 
885 	ft = fcoe_transport_lookup(netdev);
886 	if (!ft) {
887 		LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
888 				      netdev->name);
889 		goto out_putdev;
890 	}
891 
892 	rc = fcoe_add_netdev_mapping(netdev, ft);
893 	if (rc) {
894 		LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping "
895 				      "for FCoE transport %s for %s.\n",
896 				      ft->name, netdev->name);
897 		goto out_putdev;
898 	}
899 
900 	/* pass to transport create */
901 	rc = ft->create ? ft->create(netdev, fip_mode) : -ENODEV;
902 	if (rc)
903 		fcoe_del_netdev_mapping(netdev);
904 
905 	LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n",
906 			      ft->name, (rc) ? "failed" : "succeeded",
907 			      netdev->name);
908 
909 out_putdev:
910 	dev_put(netdev);
911 out_nodev:
912 	mutex_unlock(&ft_mutex);
913 	return rc;
914 }
915 
916 /**
917  * fcoe_transport_destroy() - Destroy a FCoE interface
918  * @buffer: The name of the Ethernet interface to be destroyed
919  * @kp:	    The associated kernel parameter
920  *
921  * Called from sysfs. This holds the ft_mutex while calling the
922  * registered fcoe transport's destroy function.
923  *
924  * Returns: 0 for success
925  */
926 static int fcoe_transport_destroy(const char *buffer,
927 				  const struct kernel_param *kp)
928 {
929 	int rc = -ENODEV;
930 	struct net_device *netdev = NULL;
931 	struct fcoe_transport *ft = NULL;
932 
933 	mutex_lock(&ft_mutex);
934 
935 	netdev = fcoe_if_to_netdev(buffer);
936 	if (!netdev) {
937 		LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buffer);
938 		goto out_nodev;
939 	}
940 
941 	ft = fcoe_netdev_map_lookup(netdev);
942 	if (!ft) {
943 		LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
944 				      netdev->name);
945 		goto out_putdev;
946 	}
947 
948 	/* pass to transport destroy */
949 	rc = ft->destroy ? ft->destroy(netdev) : -ENODEV;
950 	fcoe_del_netdev_mapping(netdev);
951 	LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n",
952 			      ft->name, (rc) ? "failed" : "succeeded",
953 			      netdev->name);
954 
955 out_putdev:
956 	dev_put(netdev);
957 out_nodev:
958 	mutex_unlock(&ft_mutex);
959 	return rc;
960 }
961 
962 /**
963  * fcoe_transport_disable() - Disables a FCoE interface
964  * @buffer: The name of the Ethernet interface to be disabled
965  * @kp:	    The associated kernel parameter
966  *
967  * Called from sysfs.
968  *
969  * Returns: 0 for success
970  */
971 static int fcoe_transport_disable(const char *buffer,
972 				  const struct kernel_param *kp)
973 {
974 	int rc = -ENODEV;
975 	struct net_device *netdev = NULL;
976 	struct fcoe_transport *ft = NULL;
977 
978 	mutex_lock(&ft_mutex);
979 
980 	netdev = fcoe_if_to_netdev(buffer);
981 	if (!netdev)
982 		goto out_nodev;
983 
984 	ft = fcoe_netdev_map_lookup(netdev);
985 	if (!ft)
986 		goto out_putdev;
987 
988 	rc = ft->disable ? ft->disable(netdev) : -ENODEV;
989 
990 out_putdev:
991 	dev_put(netdev);
992 out_nodev:
993 	mutex_unlock(&ft_mutex);
994 	return rc;
995 }
996 
997 /**
998  * fcoe_transport_enable() - Enables a FCoE interface
999  * @buffer: The name of the Ethernet interface to be enabled
1000  * @kp:     The associated kernel parameter
1001  *
1002  * Called from sysfs.
1003  *
1004  * Returns: 0 for success
1005  */
1006 static int fcoe_transport_enable(const char *buffer,
1007 				 const struct kernel_param *kp)
1008 {
1009 	int rc = -ENODEV;
1010 	struct net_device *netdev = NULL;
1011 	struct fcoe_transport *ft = NULL;
1012 
1013 	mutex_lock(&ft_mutex);
1014 
1015 	netdev = fcoe_if_to_netdev(buffer);
1016 	if (!netdev)
1017 		goto out_nodev;
1018 
1019 	ft = fcoe_netdev_map_lookup(netdev);
1020 	if (!ft)
1021 		goto out_putdev;
1022 
1023 	rc = ft->enable ? ft->enable(netdev) : -ENODEV;
1024 
1025 out_putdev:
1026 	dev_put(netdev);
1027 out_nodev:
1028 	mutex_unlock(&ft_mutex);
1029 	return rc;
1030 }
1031 
1032 /**
1033  * libfcoe_init() - Initialization routine for libfcoe.ko
1034  */
1035 static int __init libfcoe_init(void)
1036 {
1037 	int rc = 0;
1038 
1039 	rc = fcoe_transport_init();
1040 	if (rc)
1041 		return rc;
1042 
1043 	rc = fcoe_sysfs_setup();
1044 	if (rc)
1045 		fcoe_transport_exit();
1046 
1047 	return rc;
1048 }
1049 module_init(libfcoe_init);
1050 
1051 /**
1052  * libfcoe_exit() - Tear down libfcoe.ko
1053  */
1054 static void __exit libfcoe_exit(void)
1055 {
1056 	fcoe_sysfs_teardown();
1057 	fcoe_transport_exit();
1058 }
1059 module_exit(libfcoe_exit);
1060