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