[SCSI] fcoe: Add a header file defining the FIP protocol for FCoE.
[deliverable/linux.git] / drivers / scsi / fcoe / fcoe.c
CommitLineData
85b4aa49
RL
1/*
2 * Copyright(c) 2007 - 2008 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/module.h>
21#include <linux/version.h>
85b4aa49 22#include <linux/spinlock.h>
85b4aa49
RL
23#include <linux/netdevice.h>
24#include <linux/etherdevice.h>
25#include <linux/ethtool.h>
26#include <linux/if_ether.h>
27#include <linux/if_vlan.h>
85b4aa49
RL
28#include <linux/crc32.h>
29#include <linux/cpu.h>
30#include <linux/fs.h>
31#include <linux/sysfs.h>
32#include <linux/ctype.h>
33#include <scsi/scsi_tcq.h>
34#include <scsi/scsicam.h>
35#include <scsi/scsi_transport.h>
36#include <scsi/scsi_transport_fc.h>
37#include <net/rtnetlink.h>
38
39#include <scsi/fc/fc_encaps.h>
40
41#include <scsi/libfc.h>
42#include <scsi/fc_frame.h>
43#include <scsi/libfcoe.h>
85b4aa49 44
fdd78027 45#include "fcoe.h"
7f349142 46
fdd78027 47static int debug_fcoe;
7f349142 48
85b4aa49
RL
49MODULE_AUTHOR("Open-FCoE.org");
50MODULE_DESCRIPTION("FCoE");
9b34ecff 51MODULE_LICENSE("GPL v2");
85b4aa49
RL
52
53/* fcoe host list */
54LIST_HEAD(fcoe_hostlist);
55DEFINE_RWLOCK(fcoe_hostlist_lock);
56DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
5e5e92df 57DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
85b4aa49 58
85b4aa49 59/* Function Prototyes */
fdd78027
VD
60static int fcoe_reset(struct Scsi_Host *shost);
61static int fcoe_xmit(struct fc_lport *, struct fc_frame *);
62static int fcoe_rcv(struct sk_buff *, struct net_device *,
63 struct packet_type *, struct net_device *);
64static int fcoe_percpu_receive_thread(void *arg);
65static void fcoe_clean_pending_queue(struct fc_lport *lp);
66static void fcoe_percpu_clean(struct fc_lport *lp);
67static int fcoe_link_ok(struct fc_lport *lp);
68
69static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
70static int fcoe_hostlist_add(const struct fc_lport *);
71static int fcoe_hostlist_remove(const struct fc_lport *);
72
85b4aa49 73static int fcoe_check_wait_queue(struct fc_lport *);
85b4aa49 74static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *);
85b4aa49
RL
75static int fcoe_device_notification(struct notifier_block *, ulong, void *);
76static void fcoe_dev_setup(void);
77static void fcoe_dev_cleanup(void);
78
79/* notification function from net device */
80static struct notifier_block fcoe_notifier = {
81 .notifier_call = fcoe_device_notification,
82};
83
7f349142
VD
84static struct scsi_transport_template *scsi_transport_fcoe_sw;
85
86struct fc_function_template fcoe_transport_function = {
87 .show_host_node_name = 1,
88 .show_host_port_name = 1,
89 .show_host_supported_classes = 1,
90 .show_host_supported_fc4s = 1,
91 .show_host_active_fc4s = 1,
92 .show_host_maxframe_size = 1,
93
94 .show_host_port_id = 1,
95 .show_host_supported_speeds = 1,
96 .get_host_speed = fc_get_host_speed,
97 .show_host_speed = 1,
98 .show_host_port_type = 1,
99 .get_host_port_state = fc_get_host_port_state,
100 .show_host_port_state = 1,
101 .show_host_symbolic_name = 1,
102
103 .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
104 .show_rport_maxframe_size = 1,
105 .show_rport_supported_classes = 1,
106
107 .show_host_fabric_name = 1,
108 .show_starget_node_name = 1,
109 .show_starget_port_name = 1,
110 .show_starget_port_id = 1,
111 .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
112 .show_rport_dev_loss_tmo = 1,
113 .get_fc_host_stats = fc_get_host_stats,
114 .issue_fc_host_lip = fcoe_reset,
115
116 .terminate_rport_io = fc_rport_terminate_io,
117};
118
119static struct scsi_host_template fcoe_shost_template = {
120 .module = THIS_MODULE,
121 .name = "FCoE Driver",
122 .proc_name = FCOE_NAME,
123 .queuecommand = fc_queuecommand,
124 .eh_abort_handler = fc_eh_abort,
125 .eh_device_reset_handler = fc_eh_device_reset,
126 .eh_host_reset_handler = fc_eh_host_reset,
127 .slave_alloc = fc_slave_alloc,
128 .change_queue_depth = fc_change_queue_depth,
129 .change_queue_type = fc_change_queue_type,
130 .this_id = -1,
131 .cmd_per_lun = 32,
132 .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
133 .use_clustering = ENABLE_CLUSTERING,
134 .sg_tablesize = SG_ALL,
135 .max_sectors = 0xffff,
136};
137
138/**
139 * fcoe_lport_config() - sets up the fc_lport
140 * @lp: ptr to the fc_lport
141 * @shost: ptr to the parent scsi host
142 *
143 * Returns: 0 for success
144 */
145static int fcoe_lport_config(struct fc_lport *lp)
146{
147 lp->link_up = 0;
148 lp->qfull = 0;
149 lp->max_retry_count = 3;
150 lp->e_d_tov = 2 * 1000; /* FC-FS default */
151 lp->r_a_tov = 2 * 2 * 1000;
152 lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
153 FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
154
155 fc_lport_init_stats(lp);
156
157 /* lport fc_lport related configuration */
158 fc_lport_config(lp);
159
160 /* offload related configuration */
161 lp->crc_offload = 0;
162 lp->seq_offload = 0;
163 lp->lro_enabled = 0;
164 lp->lro_xid = 0;
165 lp->lso_max = 0;
166
167 return 0;
168}
169
170/**
171 * fcoe_netdev_config() - Set up netdev for SW FCoE
172 * @lp : ptr to the fc_lport
173 * @netdev : ptr to the associated netdevice struct
174 *
175 * Must be called after fcoe_lport_config() as it will use lport mutex
176 *
177 * Returns : 0 for success
178 */
179static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
180{
181 u32 mfs;
182 u64 wwnn, wwpn;
183 struct fcoe_softc *fc;
184 u8 flogi_maddr[ETH_ALEN];
185
186 /* Setup lport private data to point to fcoe softc */
187 fc = lport_priv(lp);
188 fc->lp = lp;
189 fc->real_dev = netdev;
190 fc->phys_dev = netdev;
191
192 /* Require support for get_pauseparam ethtool op. */
193 if (netdev->priv_flags & IFF_802_1Q_VLAN)
194 fc->phys_dev = vlan_dev_real_dev(netdev);
195
196 /* Do not support for bonding device */
197 if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
198 (fc->real_dev->priv_flags & IFF_SLAVE_INACTIVE) ||
199 (fc->real_dev->priv_flags & IFF_MASTER_8023AD)) {
200 return -EOPNOTSUPP;
201 }
202
203 /*
204 * Determine max frame size based on underlying device and optional
205 * user-configured limit. If the MFS is too low, fcoe_link_ok()
206 * will return 0, so do this first.
207 */
208 mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) +
209 sizeof(struct fcoe_crc_eof));
210 if (fc_set_mfs(lp, mfs))
211 return -EINVAL;
212
213 if (!fcoe_link_ok(lp))
214 lp->link_up = 1;
215
216 /* offload features support */
217 if (fc->real_dev->features & NETIF_F_SG)
218 lp->sg_supp = 1;
219
220#ifdef NETIF_F_FCOE_CRC
221 if (netdev->features & NETIF_F_FCOE_CRC) {
222 lp->crc_offload = 1;
223 printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n",
224 netdev->name);
225 }
226#endif
227#ifdef NETIF_F_FSO
228 if (netdev->features & NETIF_F_FSO) {
229 lp->seq_offload = 1;
230 lp->lso_max = netdev->gso_max_size;
231 printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n",
232 netdev->name, lp->lso_max);
233 }
234#endif
235 if (netdev->fcoe_ddp_xid) {
236 lp->lro_enabled = 1;
237 lp->lro_xid = netdev->fcoe_ddp_xid;
238 printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n",
239 netdev->name, lp->lro_xid);
240 }
241 skb_queue_head_init(&fc->fcoe_pending_queue);
242 fc->fcoe_pending_queue_active = 0;
243
244 /* setup Source Mac Address */
245 memcpy(fc->ctl_src_addr, fc->real_dev->dev_addr,
246 fc->real_dev->addr_len);
247
248 wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
249 fc_set_wwnn(lp, wwnn);
250 /* XXX - 3rd arg needs to be vlan id */
251 wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0);
252 fc_set_wwpn(lp, wwpn);
253
254 /*
255 * Add FCoE MAC address as second unicast MAC address
256 * or enter promiscuous mode if not capable of listening
257 * for multiple unicast MACs.
258 */
259 rtnl_lock();
260 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
261 dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
262 rtnl_unlock();
263
264 /*
265 * setup the receive function from ethernet driver
266 * on the ethertype for the given device
267 */
268 fc->fcoe_packet_type.func = fcoe_rcv;
269 fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
270 fc->fcoe_packet_type.dev = fc->real_dev;
271 dev_add_pack(&fc->fcoe_packet_type);
272
273 return 0;
274}
275
276/**
277 * fcoe_shost_config() - Sets up fc_lport->host
278 * @lp : ptr to the fc_lport
279 * @shost : ptr to the associated scsi host
280 * @dev : device associated to scsi host
281 *
282 * Must be called after fcoe_lport_config() and fcoe_netdev_config()
283 *
284 * Returns : 0 for success
285 */
286static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
287 struct device *dev)
288{
289 int rc = 0;
290
291 /* lport scsi host config */
292 lp->host = shost;
293
294 lp->host->max_lun = FCOE_MAX_LUN;
295 lp->host->max_id = FCOE_MAX_FCP_TARGET;
296 lp->host->max_channel = 0;
297 lp->host->transportt = scsi_transport_fcoe_sw;
298
299 /* add the new host to the SCSI-ml */
300 rc = scsi_add_host(lp->host, dev);
301 if (rc) {
302 FC_DBG("fcoe_shost_config:error on scsi_add_host\n");
303 return rc;
304 }
305 sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
306 FCOE_NAME, FCOE_VERSION,
307 fcoe_netdev(lp)->name);
308
309 return 0;
310}
311
312/**
313 * fcoe_em_config() - allocates em for this lport
314 * @lp: the port that em is to allocated for
315 *
316 * Returns : 0 on success
317 */
318static inline int fcoe_em_config(struct fc_lport *lp)
319{
320 BUG_ON(lp->emp);
321
322 lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
323 FCOE_MIN_XID, FCOE_MAX_XID);
324 if (!lp->emp)
325 return -ENOMEM;
326
327 return 0;
328}
329
330/**
331 * fcoe_if_destroy() - FCoE software HBA tear-down function
332 * @netdev: ptr to the associated net_device
333 *
334 * Returns: 0 if link is OK for use by FCoE.
335 */
336static int fcoe_if_destroy(struct net_device *netdev)
337{
338 struct fc_lport *lp = NULL;
339 struct fcoe_softc *fc;
340 u8 flogi_maddr[ETH_ALEN];
341
342 BUG_ON(!netdev);
343
344 printk(KERN_DEBUG "fcoe_if_destroy:interface on %s\n",
345 netdev->name);
346
347 lp = fcoe_hostlist_lookup(netdev);
348 if (!lp)
349 return -ENODEV;
350
351 fc = lport_priv(lp);
352
353 /* Logout of the fabric */
354 fc_fabric_logoff(lp);
355
356 /* Remove the instance from fcoe's list */
357 fcoe_hostlist_remove(lp);
358
359 /* Don't listen for Ethernet packets anymore */
360 dev_remove_pack(&fc->fcoe_packet_type);
361
362 /* Cleanup the fc_lport */
363 fc_lport_destroy(lp);
364 fc_fcp_destroy(lp);
365
366 /* Detach from the scsi-ml */
367 fc_remove_host(lp->host);
368 scsi_remove_host(lp->host);
369
370 /* There are no more rports or I/O, free the EM */
371 if (lp->emp)
372 fc_exch_mgr_free(lp->emp);
373
374 /* Delete secondary MAC addresses */
375 rtnl_lock();
376 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
377 dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
378 if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
379 dev_unicast_delete(fc->real_dev, fc->data_src_addr, ETH_ALEN);
380 rtnl_unlock();
381
382 /* Free the per-CPU revieve threads */
383 fcoe_percpu_clean(lp);
384
385 /* Free existing skbs */
386 fcoe_clean_pending_queue(lp);
387
388 /* Free memory used by statistical counters */
389 fc_lport_free_stats(lp);
390
391 /* Release the net_device and Scsi_Host */
392 dev_put(fc->real_dev);
393 scsi_host_put(lp->host);
394
395 return 0;
396}
397
398/*
399 * fcoe_ddp_setup - calls LLD's ddp_setup through net_device
400 * @lp: the corresponding fc_lport
401 * @xid: the exchange id for this ddp transfer
402 * @sgl: the scatterlist describing this transfer
403 * @sgc: number of sg items
404 *
405 * Returns : 0 no ddp
406 */
407static int fcoe_ddp_setup(struct fc_lport *lp, u16 xid,
408 struct scatterlist *sgl, unsigned int sgc)
409{
410 struct net_device *n = fcoe_netdev(lp);
411
412 if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
413 return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
414
415 return 0;
416}
417
418/*
419 * fcoe_ddp_done - calls LLD's ddp_done through net_device
420 * @lp: the corresponding fc_lport
421 * @xid: the exchange id for this ddp transfer
422 *
423 * Returns : the length of data that have been completed by ddp
424 */
425static int fcoe_ddp_done(struct fc_lport *lp, u16 xid)
426{
427 struct net_device *n = fcoe_netdev(lp);
428
429 if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
430 return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
431 return 0;
432}
433
434static struct libfc_function_template fcoe_libfc_fcn_templ = {
435 .frame_send = fcoe_xmit,
436 .ddp_setup = fcoe_ddp_setup,
437 .ddp_done = fcoe_ddp_done,
438};
439
440/**
441 * fcoe_if_create() - this function creates the fcoe interface
442 * @netdev: pointer the associated netdevice
443 *
444 * Creates fc_lport struct and scsi_host for lport, configures lport
445 * and starts fabric login.
446 *
447 * Returns : 0 on success
448 */
449static int fcoe_if_create(struct net_device *netdev)
450{
451 int rc;
452 struct fc_lport *lp = NULL;
453 struct fcoe_softc *fc;
454 struct Scsi_Host *shost;
455
456 BUG_ON(!netdev);
457
458 printk(KERN_DEBUG "fcoe_if_create:interface on %s\n",
459 netdev->name);
460
461 lp = fcoe_hostlist_lookup(netdev);
462 if (lp)
463 return -EEXIST;
464
a0a25da2
VD
465 shost = libfc_host_alloc(&fcoe_shost_template,
466 sizeof(struct fcoe_softc));
7f349142
VD
467 if (!shost) {
468 FC_DBG("Could not allocate host structure\n");
469 return -ENOMEM;
470 }
471 lp = shost_priv(shost);
472 fc = lport_priv(lp);
473
474 /* configure fc_lport, e.g., em */
475 rc = fcoe_lport_config(lp);
476 if (rc) {
477 FC_DBG("Could not configure lport\n");
478 goto out_host_put;
479 }
480
481 /* configure lport network properties */
482 rc = fcoe_netdev_config(lp, netdev);
483 if (rc) {
484 FC_DBG("Could not configure netdev for lport\n");
485 goto out_host_put;
486 }
487
488 /* configure lport scsi host properties */
489 rc = fcoe_shost_config(lp, shost, &netdev->dev);
490 if (rc) {
491 FC_DBG("Could not configure shost for lport\n");
492 goto out_host_put;
493 }
494
495 /* lport exch manager allocation */
496 rc = fcoe_em_config(lp);
497 if (rc) {
498 FC_DBG("Could not configure em for lport\n");
499 goto out_host_put;
500 }
501
502 /* Initialize the library */
503 rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ);
504 if (rc) {
505 FC_DBG("Could not configure libfc for lport!\n");
506 goto out_lp_destroy;
507 }
508
509 /* add to lports list */
510 fcoe_hostlist_add(lp);
511
512 lp->boot_time = jiffies;
513
514 fc_fabric_login(lp);
515
516 dev_hold(netdev);
517
518 return rc;
519
520out_lp_destroy:
521 fc_exch_mgr_free(lp->emp); /* Free the EM */
522out_host_put:
523 scsi_host_put(lp->host);
524 return rc;
525}
526
527/**
528 * fcoe_if_init() - attach to scsi transport
529 *
530 * Returns : 0 on success
531 */
532static int __init fcoe_if_init(void)
533{
534 /* attach to scsi transport */
535 scsi_transport_fcoe_sw =
536 fc_attach_transport(&fcoe_transport_function);
537
538 if (!scsi_transport_fcoe_sw) {
539 printk(KERN_ERR "fcoe_init:fc_attach_transport() failed\n");
540 return -ENODEV;
541 }
542
543 return 0;
544}
545
546/**
547 * fcoe_if_exit() - detach from scsi transport
548 *
549 * Returns : 0 on success
550 */
551int __exit fcoe_if_exit(void)
552{
553 fc_release_transport(scsi_transport_fcoe_sw);
554 return 0;
555}
556
8976f424
RL
557/**
558 * fcoe_percpu_thread_create() - Create a receive thread for an online cpu
559 * @cpu: cpu index for the online cpu
560 */
561static void fcoe_percpu_thread_create(unsigned int cpu)
562{
563 struct fcoe_percpu_s *p;
564 struct task_struct *thread;
565
566 p = &per_cpu(fcoe_percpu, cpu);
567
568 thread = kthread_create(fcoe_percpu_receive_thread,
569 (void *)p, "fcoethread/%d", cpu);
570
571 if (likely(!IS_ERR(p->thread))) {
572 kthread_bind(thread, cpu);
573 wake_up_process(thread);
574
575 spin_lock_bh(&p->fcoe_rx_list.lock);
576 p->thread = thread;
577 spin_unlock_bh(&p->fcoe_rx_list.lock);
578 }
579}
580
581/**
582 * fcoe_percpu_thread_destroy() - removes the rx thread for the given cpu
583 * @cpu: cpu index the rx thread is to be removed
584 *
585 * Destroys a per-CPU Rx thread. Any pending skbs are moved to the
586 * current CPU's Rx thread. If the thread being destroyed is bound to
587 * the CPU processing this context the skbs will be freed.
588 */
589static void fcoe_percpu_thread_destroy(unsigned int cpu)
590{
591 struct fcoe_percpu_s *p;
592 struct task_struct *thread;
593 struct page *crc_eof;
594 struct sk_buff *skb;
595#ifdef CONFIG_SMP
596 struct fcoe_percpu_s *p0;
597 unsigned targ_cpu = smp_processor_id();
598#endif /* CONFIG_SMP */
599
600 printk(KERN_DEBUG "fcoe: Destroying receive thread for CPU %d\n", cpu);
601
602 /* Prevent any new skbs from being queued for this CPU. */
603 p = &per_cpu(fcoe_percpu, cpu);
604 spin_lock_bh(&p->fcoe_rx_list.lock);
605 thread = p->thread;
606 p->thread = NULL;
607 crc_eof = p->crc_eof_page;
608 p->crc_eof_page = NULL;
609 p->crc_eof_offset = 0;
610 spin_unlock_bh(&p->fcoe_rx_list.lock);
611
612#ifdef CONFIG_SMP
613 /*
614 * Don't bother moving the skb's if this context is running
615 * on the same CPU that is having its thread destroyed. This
616 * can easily happen when the module is removed.
617 */
618 if (cpu != targ_cpu) {
619 p0 = &per_cpu(fcoe_percpu, targ_cpu);
620 spin_lock_bh(&p0->fcoe_rx_list.lock);
621 if (p0->thread) {
622 FC_DBG("Moving frames from CPU %d to CPU %d\n",
623 cpu, targ_cpu);
624
625 while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
626 __skb_queue_tail(&p0->fcoe_rx_list, skb);
627 spin_unlock_bh(&p0->fcoe_rx_list.lock);
628 } else {
629 /*
630 * The targeted CPU is not initialized and cannot accept
631 * new skbs. Unlock the targeted CPU and drop the skbs
632 * on the CPU that is going offline.
633 */
634 while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
635 kfree_skb(skb);
636 spin_unlock_bh(&p0->fcoe_rx_list.lock);
637 }
638 } else {
639 /*
640 * This scenario occurs when the module is being removed
641 * and all threads are being destroyed. skbs will continue
642 * to be shifted from the CPU thread that is being removed
643 * to the CPU thread associated with the CPU that is processing
644 * the module removal. Once there is only one CPU Rx thread it
645 * will reach this case and we will drop all skbs and later
646 * stop the thread.
647 */
648 spin_lock_bh(&p->fcoe_rx_list.lock);
649 while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
650 kfree_skb(skb);
651 spin_unlock_bh(&p->fcoe_rx_list.lock);
652 }
653#else
654 /*
655 * This a non-SMP scenario where the singluar Rx thread is
656 * being removed. Free all skbs and stop the thread.
657 */
658 spin_lock_bh(&p->fcoe_rx_list.lock);
659 while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
660 kfree_skb(skb);
661 spin_unlock_bh(&p->fcoe_rx_list.lock);
662#endif
663
664 if (thread)
665 kthread_stop(thread);
666
667 if (crc_eof)
668 put_page(crc_eof);
669}
670
671/**
672 * fcoe_cpu_callback() - fcoe cpu hotplug event callback
673 * @nfb: callback data block
674 * @action: event triggering the callback
675 * @hcpu: index for the cpu of this event
676 *
677 * This creates or destroys per cpu data for fcoe
678 *
679 * Returns NOTIFY_OK always.
680 */
681static int fcoe_cpu_callback(struct notifier_block *nfb,
682 unsigned long action, void *hcpu)
683{
684 unsigned cpu = (unsigned long)hcpu;
685
686 switch (action) {
687 case CPU_ONLINE:
688 case CPU_ONLINE_FROZEN:
689 FC_DBG("CPU %x online: Create Rx thread\n", cpu);
690 fcoe_percpu_thread_create(cpu);
691 break;
692 case CPU_DEAD:
693 case CPU_DEAD_FROZEN:
694 FC_DBG("CPU %x offline: Remove Rx thread\n", cpu);
695 fcoe_percpu_thread_destroy(cpu);
696 break;
697 default:
698 break;
699 }
700 return NOTIFY_OK;
701}
702
703static struct notifier_block fcoe_cpu_notifier = {
704 .notifier_call = fcoe_cpu_callback,
705};
706
85b4aa49 707/**
34f42a07 708 * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
85b4aa49
RL
709 * @skb: the receive skb
710 * @dev: associated net device
711 * @ptype: context
712 * @odldev: last device
713 *
714 * this function will receive the packet and build fc frame and pass it up
715 *
716 * Returns: 0 for success
34f42a07 717 */
85b4aa49
RL
718int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
719 struct packet_type *ptype, struct net_device *olddev)
720{
721 struct fc_lport *lp;
722 struct fcoe_rcv_info *fr;
723 struct fcoe_softc *fc;
85b4aa49 724 struct fc_frame_header *fh;
85b4aa49 725 struct fcoe_percpu_s *fps;
38eccabd 726 unsigned short oxid;
8976f424 727 unsigned int cpu = 0;
85b4aa49
RL
728
729 fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
730 lp = fc->lp;
731 if (unlikely(lp == NULL)) {
732 FC_DBG("cannot find hba structure");
733 goto err2;
734 }
735
736 if (unlikely(debug_fcoe)) {
737 FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p tail:%p "
738 "end:%p sum:%d dev:%s", skb->len, skb->data_len,
739 skb->head, skb->data, skb_tail_pointer(skb),
740 skb_end_pointer(skb), skb->csum,
741 skb->dev ? skb->dev->name : "<NULL>");
742
743 }
744
745 /* check for FCOE packet type */
746 if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
747 FC_DBG("wrong FC type frame");
748 goto err;
749 }
750
751 /*
752 * Check for minimum frame length, and make sure required FCoE
753 * and FC headers are pulled into the linear data area.
754 */
755 if (unlikely((skb->len < FCOE_MIN_FRAME) ||
756 !pskb_may_pull(skb, FCOE_HEADER_LEN)))
757 goto err;
758
759 skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
760 fh = (struct fc_frame_header *) skb_transport_header(skb);
761
762 oxid = ntohs(fh->fh_ox_id);
763
764 fr = fcoe_dev_from_skb(skb);
765 fr->fr_dev = lp;
766 fr->ptype = ptype;
5e5e92df 767
85b4aa49
RL
768#ifdef CONFIG_SMP
769 /*
770 * The incoming frame exchange id(oxid) is ANDed with num of online
8976f424
RL
771 * cpu bits to get cpu and then this cpu is used for selecting
772 * a per cpu kernel thread from fcoe_percpu.
85b4aa49 773 */
8976f424 774 cpu = oxid & (num_online_cpus() - 1);
85b4aa49 775#endif
5e5e92df 776
8976f424 777 fps = &per_cpu(fcoe_percpu, cpu);
85b4aa49 778 spin_lock_bh(&fps->fcoe_rx_list.lock);
8976f424
RL
779 if (unlikely(!fps->thread)) {
780 /*
781 * The targeted CPU is not ready, let's target
782 * the first CPU now. For non-SMP systems this
783 * will check the same CPU twice.
784 */
785 FC_DBG("CPU is online, but no receive thread ready "
786 "for incoming skb- using first online CPU.\n");
787
788 spin_unlock_bh(&fps->fcoe_rx_list.lock);
789 cpu = first_cpu(cpu_online_map);
790 fps = &per_cpu(fcoe_percpu, cpu);
791 spin_lock_bh(&fps->fcoe_rx_list.lock);
792 if (!fps->thread) {
793 spin_unlock_bh(&fps->fcoe_rx_list.lock);
794 goto err;
795 }
796 }
797
798 /*
799 * We now have a valid CPU that we're targeting for
800 * this skb. We also have this receive thread locked,
801 * so we're free to queue skbs into it's queue.
802 */
85b4aa49
RL
803 __skb_queue_tail(&fps->fcoe_rx_list, skb);
804 if (fps->fcoe_rx_list.qlen == 1)
805 wake_up_process(fps->thread);
806
807 spin_unlock_bh(&fps->fcoe_rx_list.lock);
808
809 return 0;
810err:
582b45bc 811 fc_lport_get_stats(lp)->ErrorFrames++;
85b4aa49
RL
812
813err2:
814 kfree_skb(skb);
815 return -1;
816}
817EXPORT_SYMBOL_GPL(fcoe_rcv);
818
819/**
34f42a07 820 * fcoe_start_io() - pass to netdev to start xmit for fcoe
85b4aa49
RL
821 * @skb: the skb to be xmitted
822 *
823 * Returns: 0 for success
34f42a07 824 */
85b4aa49
RL
825static inline int fcoe_start_io(struct sk_buff *skb)
826{
827 int rc;
828
829 skb_get(skb);
830 rc = dev_queue_xmit(skb);
831 if (rc != 0)
832 return rc;
833 kfree_skb(skb);
834 return 0;
835}
836
837/**
34f42a07 838 * fcoe_get_paged_crc_eof() - in case we need alloc a page for crc_eof
85b4aa49
RL
839 * @skb: the skb to be xmitted
840 * @tlen: total len
841 *
842 * Returns: 0 for success
34f42a07 843 */
85b4aa49
RL
844static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
845{
846 struct fcoe_percpu_s *fps;
847 struct page *page;
85b4aa49 848
5e5e92df 849 fps = &get_cpu_var(fcoe_percpu);
85b4aa49
RL
850 page = fps->crc_eof_page;
851 if (!page) {
852 page = alloc_page(GFP_ATOMIC);
853 if (!page) {
5e5e92df 854 put_cpu_var(fcoe_percpu);
85b4aa49
RL
855 return -ENOMEM;
856 }
857 fps->crc_eof_page = page;
8976f424 858 fps->crc_eof_offset = 0;
85b4aa49
RL
859 }
860
861 get_page(page);
862 skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
863 fps->crc_eof_offset, tlen);
864 skb->len += tlen;
865 skb->data_len += tlen;
866 skb->truesize += tlen;
867 fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
868
869 if (fps->crc_eof_offset >= PAGE_SIZE) {
870 fps->crc_eof_page = NULL;
871 fps->crc_eof_offset = 0;
872 put_page(page);
873 }
5e5e92df 874 put_cpu_var(fcoe_percpu);
85b4aa49
RL
875 return 0;
876}
877
878/**
34f42a07 879 * fcoe_fc_crc() - calculates FC CRC in this fcoe skb
85b4aa49
RL
880 * @fp: the fc_frame containg data to be checksummed
881 *
882 * This uses crc32() to calculate the crc for fc frame
883 * Return : 32 bit crc
34f42a07 884 */
85b4aa49
RL
885u32 fcoe_fc_crc(struct fc_frame *fp)
886{
887 struct sk_buff *skb = fp_skb(fp);
888 struct skb_frag_struct *frag;
889 unsigned char *data;
890 unsigned long off, len, clen;
891 u32 crc;
892 unsigned i;
893
894 crc = crc32(~0, skb->data, skb_headlen(skb));
895
896 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
897 frag = &skb_shinfo(skb)->frags[i];
898 off = frag->page_offset;
899 len = frag->size;
900 while (len > 0) {
901 clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
902 data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
903 KM_SKB_DATA_SOFTIRQ);
904 crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
905 kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
906 off += clen;
907 len -= clen;
908 }
909 }
910 return crc;
911}
85b4aa49
RL
912
913/**
34f42a07 914 * fcoe_xmit() - FCoE frame transmit function
85b4aa49
RL
915 * @lp: the associated local port
916 * @fp: the fc_frame to be transmitted
917 *
918 * Return : 0 for success
34f42a07 919 */
85b4aa49
RL
920int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
921{
922 int wlen, rc = 0;
923 u32 crc;
924 struct ethhdr *eh;
925 struct fcoe_crc_eof *cp;
926 struct sk_buff *skb;
927 struct fcoe_dev_stats *stats;
928 struct fc_frame_header *fh;
929 unsigned int hlen; /* header length implies the version */
930 unsigned int tlen; /* trailer length */
931 unsigned int elen; /* eth header, may include vlan */
932 int flogi_in_progress = 0;
933 struct fcoe_softc *fc;
934 u8 sof, eof;
935 struct fcoe_hdr *hp;
936
937 WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
938
fc47ff6b 939 fc = lport_priv(lp);
85b4aa49
RL
940 /*
941 * if it is a flogi then we need to learn gw-addr
942 * and my own fcid
943 */
944 fh = fc_frame_header_get(fp);
945 if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {
946 if (fc_frame_payload_op(fp) == ELS_FLOGI) {
947 fc->flogi_oxid = ntohs(fh->fh_ox_id);
948 fc->address_mode = FCOE_FCOUI_ADDR_MODE;
949 fc->flogi_progress = 1;
950 flogi_in_progress = 1;
951 } else if (fc->flogi_progress && ntoh24(fh->fh_s_id) != 0) {
952 /*
953 * Here we must've gotten an SID by accepting an FLOGI
954 * from a point-to-point connection. Switch to using
955 * the source mac based on the SID. The destination
956 * MAC in this case would have been set by receving the
957 * FLOGI.
958 */
959 fc_fcoe_set_mac(fc->data_src_addr, fh->fh_s_id);
960 fc->flogi_progress = 0;
961 }
962 }
963
964 skb = fp_skb(fp);
965 sof = fr_sof(fp);
966 eof = fr_eof(fp);
967
968 elen = (fc->real_dev->priv_flags & IFF_802_1Q_VLAN) ?
969 sizeof(struct vlan_ethhdr) : sizeof(struct ethhdr);
970 hlen = sizeof(struct fcoe_hdr);
971 tlen = sizeof(struct fcoe_crc_eof);
972 wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
973
974 /* crc offload */
975 if (likely(lp->crc_offload)) {
39ca9a06 976 skb->ip_summed = CHECKSUM_PARTIAL;
85b4aa49
RL
977 skb->csum_start = skb_headroom(skb);
978 skb->csum_offset = skb->len;
979 crc = 0;
980 } else {
981 skb->ip_summed = CHECKSUM_NONE;
982 crc = fcoe_fc_crc(fp);
983 }
984
985 /* copy fc crc and eof to the skb buff */
986 if (skb_is_nonlinear(skb)) {
987 skb_frag_t *frag;
988 if (fcoe_get_paged_crc_eof(skb, tlen)) {
e9041581 989 kfree_skb(skb);
85b4aa49
RL
990 return -ENOMEM;
991 }
992 frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
993 cp = kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ)
994 + frag->page_offset;
995 } else {
996 cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
997 }
998
999 memset(cp, 0, sizeof(*cp));
1000 cp->fcoe_eof = eof;
1001 cp->fcoe_crc32 = cpu_to_le32(~crc);
1002
1003 if (skb_is_nonlinear(skb)) {
1004 kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
1005 cp = NULL;
1006 }
1007
1008 /* adjust skb netowrk/transport offsets to match mac/fcoe/fc */
1009 skb_push(skb, elen + hlen);
1010 skb_reset_mac_header(skb);
1011 skb_reset_network_header(skb);
1012 skb->mac_len = elen;
211c738d 1013 skb->protocol = htons(ETH_P_FCOE);
85b4aa49
RL
1014 skb->dev = fc->real_dev;
1015
1016 /* fill up mac and fcoe headers */
1017 eh = eth_hdr(skb);
1018 eh->h_proto = htons(ETH_P_FCOE);
1019 if (fc->address_mode == FCOE_FCOUI_ADDR_MODE)
1020 fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
1021 else
1022 /* insert GW address */
1023 memcpy(eh->h_dest, fc->dest_addr, ETH_ALEN);
1024
1025 if (unlikely(flogi_in_progress))
1026 memcpy(eh->h_source, fc->ctl_src_addr, ETH_ALEN);
1027 else
1028 memcpy(eh->h_source, fc->data_src_addr, ETH_ALEN);
1029
1030 hp = (struct fcoe_hdr *)(eh + 1);
1031 memset(hp, 0, sizeof(*hp));
1032 if (FC_FCOE_VER)
1033 FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
1034 hp->fcoe_sof = sof;
1035
39ca9a06
YZ
1036#ifdef NETIF_F_FSO
1037 /* fcoe lso, mss is in max_payload which is non-zero for FCP data */
1038 if (lp->seq_offload && fr_max_payload(fp)) {
1039 skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
1040 skb_shinfo(skb)->gso_size = fr_max_payload(fp);
1041 } else {
1042 skb_shinfo(skb)->gso_type = 0;
1043 skb_shinfo(skb)->gso_size = 0;
1044 }
1045#endif
85b4aa49 1046 /* update tx stats: regardless if LLD fails */
582b45bc
RL
1047 stats = fc_lport_get_stats(lp);
1048 stats->TxFrames++;
1049 stats->TxWords += wlen;
85b4aa49
RL
1050
1051 /* send down to lld */
1052 fr_dev(fp) = lp;
1053 if (fc->fcoe_pending_queue.qlen)
1054 rc = fcoe_check_wait_queue(lp);
1055
1056 if (rc == 0)
1057 rc = fcoe_start_io(skb);
1058
1059 if (rc) {
55c8bafb
CL
1060 spin_lock_bh(&fc->fcoe_pending_queue.lock);
1061 __skb_queue_tail(&fc->fcoe_pending_queue, skb);
1062 spin_unlock_bh(&fc->fcoe_pending_queue.lock);
85b4aa49 1063 if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
bc0e17f6 1064 lp->qfull = 1;
85b4aa49
RL
1065 }
1066
1067 return 0;
1068}
1069EXPORT_SYMBOL_GPL(fcoe_xmit);
1070
34f42a07
RL
1071/**
1072 * fcoe_percpu_receive_thread() - recv thread per cpu
85b4aa49
RL
1073 * @arg: ptr to the fcoe per cpu struct
1074 *
1075 * Return: 0 for success
85b4aa49
RL
1076 */
1077int fcoe_percpu_receive_thread(void *arg)
1078{
1079 struct fcoe_percpu_s *p = arg;
1080 u32 fr_len;
1081 struct fc_lport *lp;
1082 struct fcoe_rcv_info *fr;
1083 struct fcoe_dev_stats *stats;
1084 struct fc_frame_header *fh;
1085 struct sk_buff *skb;
1086 struct fcoe_crc_eof crc_eof;
1087 struct fc_frame *fp;
1088 u8 *mac = NULL;
1089 struct fcoe_softc *fc;
1090 struct fcoe_hdr *hp;
1091
4469c195 1092 set_user_nice(current, -20);
85b4aa49
RL
1093
1094 while (!kthread_should_stop()) {
1095
1096 spin_lock_bh(&p->fcoe_rx_list.lock);
1097 while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) {
1098 set_current_state(TASK_INTERRUPTIBLE);
1099 spin_unlock_bh(&p->fcoe_rx_list.lock);
1100 schedule();
1101 set_current_state(TASK_RUNNING);
1102 if (kthread_should_stop())
1103 return 0;
1104 spin_lock_bh(&p->fcoe_rx_list.lock);
1105 }
1106 spin_unlock_bh(&p->fcoe_rx_list.lock);
1107 fr = fcoe_dev_from_skb(skb);
1108 lp = fr->fr_dev;
1109 if (unlikely(lp == NULL)) {
1110 FC_DBG("invalid HBA Structure");
1111 kfree_skb(skb);
1112 continue;
1113 }
1114
85b4aa49
RL
1115 if (unlikely(debug_fcoe)) {
1116 FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p "
1117 "tail:%p end:%p sum:%d dev:%s",
1118 skb->len, skb->data_len,
1119 skb->head, skb->data, skb_tail_pointer(skb),
1120 skb_end_pointer(skb), skb->csum,
1121 skb->dev ? skb->dev->name : "<NULL>");
1122 }
1123
1124 /*
1125 * Save source MAC address before discarding header.
1126 */
1127 fc = lport_priv(lp);
1128 if (unlikely(fc->flogi_progress))
1129 mac = eth_hdr(skb)->h_source;
1130
1131 if (skb_is_nonlinear(skb))
1132 skb_linearize(skb); /* not ideal */
1133
1134 /*
1135 * Frame length checks and setting up the header pointers
1136 * was done in fcoe_rcv already.
1137 */
1138 hp = (struct fcoe_hdr *) skb_network_header(skb);
1139 fh = (struct fc_frame_header *) skb_transport_header(skb);
1140
582b45bc 1141 stats = fc_lport_get_stats(lp);
85b4aa49 1142 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
582b45bc
RL
1143 if (stats->ErrorFrames < 5)
1144 printk(KERN_WARNING "FCoE version "
1145 "mismatch: The frame has "
1146 "version %x, but the "
1147 "initiator supports version "
1148 "%x\n", FC_FCOE_DECAPS_VER(hp),
1149 FC_FCOE_VER);
1150 stats->ErrorFrames++;
85b4aa49
RL
1151 kfree_skb(skb);
1152 continue;
1153 }
1154
1155 skb_pull(skb, sizeof(struct fcoe_hdr));
1156 fr_len = skb->len - sizeof(struct fcoe_crc_eof);
1157
582b45bc
RL
1158 stats->RxFrames++;
1159 stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
85b4aa49
RL
1160
1161 fp = (struct fc_frame *)skb;
1162 fc_frame_init(fp);
1163 fr_dev(fp) = lp;
1164 fr_sof(fp) = hp->fcoe_sof;
1165
1166 /* Copy out the CRC and EOF trailer for access */
1167 if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
1168 kfree_skb(skb);
1169 continue;
1170 }
1171 fr_eof(fp) = crc_eof.fcoe_eof;
1172 fr_crc(fp) = crc_eof.fcoe_crc32;
1173 if (pskb_trim(skb, fr_len)) {
1174 kfree_skb(skb);
1175 continue;
1176 }
1177
1178 /*
1179 * We only check CRC if no offload is available and if it is
1180 * it's solicited data, in which case, the FCP layer would
1181 * check it during the copy.
1182 */
07c00ec4 1183 if (lp->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY)
85b4aa49
RL
1184 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
1185 else
1186 fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
1187
1188 fh = fc_frame_header_get(fp);
1189 if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
1190 fh->fh_type == FC_TYPE_FCP) {
1191 fc_exch_recv(lp, lp->emp, fp);
1192 continue;
1193 }
1194 if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
1195 if (le32_to_cpu(fr_crc(fp)) !=
1196 ~crc32(~0, skb->data, fr_len)) {
1197 if (debug_fcoe || stats->InvalidCRCCount < 5)
1198 printk(KERN_WARNING "fcoe: dropping "
1199 "frame with CRC error\n");
1200 stats->InvalidCRCCount++;
1201 stats->ErrorFrames++;
1202 fc_frame_free(fp);
1203 continue;
1204 }
1205 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
1206 }
1207 /* non flogi and non data exchanges are handled here */
1208 if (unlikely(fc->flogi_progress))
1209 fcoe_recv_flogi(fc, fp, mac);
1210 fc_exch_recv(lp, lp->emp, fp);
1211 }
1212 return 0;
1213}
1214
1215/**
34f42a07 1216 * fcoe_recv_flogi() - flogi receive function
85b4aa49
RL
1217 * @fc: associated fcoe_softc
1218 * @fp: the recieved frame
1219 * @sa: the source address of this flogi
1220 *
1221 * This is responsible to parse the flogi response and sets the corresponding
1222 * mac address for the initiator, eitehr OUI based or GW based.
1223 *
1224 * Returns: none
34f42a07 1225 */
85b4aa49
RL
1226static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa)
1227{
1228 struct fc_frame_header *fh;
1229 u8 op;
1230
1231 fh = fc_frame_header_get(fp);
1232 if (fh->fh_type != FC_TYPE_ELS)
1233 return;
1234 op = fc_frame_payload_op(fp);
1235 if (op == ELS_LS_ACC && fh->fh_r_ctl == FC_RCTL_ELS_REP &&
1236 fc->flogi_oxid == ntohs(fh->fh_ox_id)) {
1237 /*
1238 * FLOGI accepted.
1239 * If the src mac addr is FC_OUI-based, then we mark the
1240 * address_mode flag to use FC_OUI-based Ethernet DA.
1241 * Otherwise we use the FCoE gateway addr
1242 */
1243 if (!compare_ether_addr(sa, (u8[6]) FC_FCOE_FLOGI_MAC)) {
1244 fc->address_mode = FCOE_FCOUI_ADDR_MODE;
1245 } else {
1246 memcpy(fc->dest_addr, sa, ETH_ALEN);
1247 fc->address_mode = FCOE_GW_ADDR_MODE;
1248 }
1249
1250 /*
1251 * Remove any previously-set unicast MAC filter.
1252 * Add secondary FCoE MAC address filter for our OUI.
1253 */
1254 rtnl_lock();
1255 if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
1256 dev_unicast_delete(fc->real_dev, fc->data_src_addr,
1257 ETH_ALEN);
1258 fc_fcoe_set_mac(fc->data_src_addr, fh->fh_d_id);
1259 dev_unicast_add(fc->real_dev, fc->data_src_addr, ETH_ALEN);
1260 rtnl_unlock();
1261
1262 fc->flogi_progress = 0;
1263 } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
1264 /*
1265 * Save source MAC for point-to-point responses.
1266 */
1267 memcpy(fc->dest_addr, sa, ETH_ALEN);
1268 fc->address_mode = FCOE_GW_ADDR_MODE;
1269 }
1270}
1271
1272/**
34f42a07 1273 * fcoe_watchdog() - fcoe timer callback
85b4aa49
RL
1274 * @vp:
1275 *
bc0e17f6 1276 * This checks the pending queue length for fcoe and set lport qfull
85b4aa49
RL
1277 * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the
1278 * fcoe_hostlist.
1279 *
1280 * Returns: 0 for success
34f42a07 1281 */
85b4aa49
RL
1282void fcoe_watchdog(ulong vp)
1283{
85b4aa49 1284 struct fcoe_softc *fc;
85b4aa49
RL
1285
1286 read_lock(&fcoe_hostlist_lock);
1287 list_for_each_entry(fc, &fcoe_hostlist, list) {
c826a314
VD
1288 if (fc->lp)
1289 fcoe_check_wait_queue(fc->lp);
85b4aa49
RL
1290 }
1291 read_unlock(&fcoe_hostlist_lock);
1292
1293 fcoe_timer.expires = jiffies + (1 * HZ);
1294 add_timer(&fcoe_timer);
1295}
1296
1297
1298/**
34f42a07 1299 * fcoe_check_wait_queue() - put the skb into fcoe pending xmit queue
85b4aa49
RL
1300 * @lp: the fc_port for this skb
1301 * @skb: the associated skb to be xmitted
1302 *
1303 * This empties the wait_queue, dequeue the head of the wait_queue queue
1304 * and calls fcoe_start_io() for each packet, if all skb have been
c826a314
VD
1305 * transmitted, return qlen or -1 if a error occurs, then restore
1306 * wait_queue and try again later.
85b4aa49
RL
1307 *
1308 * The wait_queue is used when the skb transmit fails. skb will go
1309 * in the wait_queue which will be emptied by the time function OR
1310 * by the next skb transmit.
1311 *
1312 * Returns: 0 for success
34f42a07 1313 */
85b4aa49
RL
1314static int fcoe_check_wait_queue(struct fc_lport *lp)
1315{
55c8bafb 1316 struct fcoe_softc *fc = lport_priv(lp);
85b4aa49 1317 struct sk_buff *skb;
c826a314 1318 int rc = -1;
85b4aa49 1319
85b4aa49 1320 spin_lock_bh(&fc->fcoe_pending_queue.lock);
c826a314
VD
1321 if (fc->fcoe_pending_queue_active)
1322 goto out;
1323 fc->fcoe_pending_queue_active = 1;
55c8bafb
CL
1324
1325 while (fc->fcoe_pending_queue.qlen) {
1326 /* keep qlen > 0 until fcoe_start_io succeeds */
1327 fc->fcoe_pending_queue.qlen++;
1328 skb = __skb_dequeue(&fc->fcoe_pending_queue);
1329
1330 spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1331 rc = fcoe_start_io(skb);
1332 spin_lock_bh(&fc->fcoe_pending_queue.lock);
1333
1334 if (rc) {
1335 __skb_queue_head(&fc->fcoe_pending_queue, skb);
1336 /* undo temporary increment above */
1337 fc->fcoe_pending_queue.qlen--;
1338 break;
85b4aa49 1339 }
55c8bafb
CL
1340 /* undo temporary increment above */
1341 fc->fcoe_pending_queue.qlen--;
85b4aa49 1342 }
55c8bafb
CL
1343
1344 if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
1345 lp->qfull = 0;
c826a314
VD
1346 fc->fcoe_pending_queue_active = 0;
1347 rc = fc->fcoe_pending_queue.qlen;
1348out:
85b4aa49 1349 spin_unlock_bh(&fc->fcoe_pending_queue.lock);
c826a314 1350 return rc;
85b4aa49
RL
1351}
1352
85b4aa49 1353/**
34f42a07
RL
1354 * fcoe_dev_setup() - setup link change notification interface
1355 */
1356static void fcoe_dev_setup()
85b4aa49
RL
1357{
1358 /*
1359 * here setup a interface specific wd time to
1360 * monitor the link state
1361 */
1362 register_netdevice_notifier(&fcoe_notifier);
1363}
1364
1365/**
34f42a07
RL
1366 * fcoe_dev_setup() - cleanup link change notification interface
1367 */
85b4aa49
RL
1368static void fcoe_dev_cleanup(void)
1369{
1370 unregister_netdevice_notifier(&fcoe_notifier);
1371}
1372
1373/**
34f42a07 1374 * fcoe_device_notification() - netdev event notification callback
85b4aa49
RL
1375 * @notifier: context of the notification
1376 * @event: type of event
1377 * @ptr: fixed array for output parsed ifname
1378 *
1379 * This function is called by the ethernet driver in case of link change event
1380 *
1381 * Returns: 0 for success
34f42a07 1382 */
85b4aa49
RL
1383static int fcoe_device_notification(struct notifier_block *notifier,
1384 ulong event, void *ptr)
1385{
1386 struct fc_lport *lp = NULL;
1387 struct net_device *real_dev = ptr;
1388 struct fcoe_softc *fc;
1389 struct fcoe_dev_stats *stats;
bc0e17f6 1390 u32 new_link_up;
85b4aa49
RL
1391 u32 mfs;
1392 int rc = NOTIFY_OK;
1393
1394 read_lock(&fcoe_hostlist_lock);
1395 list_for_each_entry(fc, &fcoe_hostlist, list) {
1396 if (fc->real_dev == real_dev) {
1397 lp = fc->lp;
1398 break;
1399 }
1400 }
1401 read_unlock(&fcoe_hostlist_lock);
1402 if (lp == NULL) {
1403 rc = NOTIFY_DONE;
1404 goto out;
1405 }
1406
bc0e17f6 1407 new_link_up = lp->link_up;
85b4aa49
RL
1408 switch (event) {
1409 case NETDEV_DOWN:
1410 case NETDEV_GOING_DOWN:
bc0e17f6 1411 new_link_up = 0;
85b4aa49
RL
1412 break;
1413 case NETDEV_UP:
1414 case NETDEV_CHANGE:
bc0e17f6 1415 new_link_up = !fcoe_link_ok(lp);
85b4aa49
RL
1416 break;
1417 case NETDEV_CHANGEMTU:
1418 mfs = fc->real_dev->mtu -
1419 (sizeof(struct fcoe_hdr) +
1420 sizeof(struct fcoe_crc_eof));
1421 if (mfs >= FC_MIN_MAX_FRAME)
1422 fc_set_mfs(lp, mfs);
bc0e17f6 1423 new_link_up = !fcoe_link_ok(lp);
85b4aa49
RL
1424 break;
1425 case NETDEV_REGISTER:
1426 break;
1427 default:
1428 FC_DBG("unknown event %ld call", event);
1429 }
bc0e17f6
VD
1430 if (lp->link_up != new_link_up) {
1431 if (new_link_up)
85b4aa49
RL
1432 fc_linkup(lp);
1433 else {
582b45bc
RL
1434 stats = fc_lport_get_stats(lp);
1435 stats->LinkFailureCount++;
85b4aa49
RL
1436 fc_linkdown(lp);
1437 fcoe_clean_pending_queue(lp);
1438 }
1439 }
1440out:
1441 return rc;
1442}
1443
1444/**
34f42a07 1445 * fcoe_if_to_netdev() - parse a name buffer to get netdev
85b4aa49
RL
1446 * @ifname: fixed array for output parsed ifname
1447 * @buffer: incoming buffer to be copied
1448 *
1449 * Returns: NULL or ptr to netdeive
34f42a07 1450 */
85b4aa49
RL
1451static struct net_device *fcoe_if_to_netdev(const char *buffer)
1452{
1453 char *cp;
1454 char ifname[IFNAMSIZ + 2];
1455
1456 if (buffer) {
1457 strlcpy(ifname, buffer, IFNAMSIZ);
1458 cp = ifname + strlen(ifname);
1459 while (--cp >= ifname && *cp == '\n')
1460 *cp = '\0';
1461 return dev_get_by_name(&init_net, ifname);
1462 }
1463 return NULL;
1464}
1465
1466/**
34f42a07 1467 * fcoe_netdev_to_module_owner() - finds out the nic drive moddule of the netdev
85b4aa49
RL
1468 * @netdev: the target netdev
1469 *
1470 * Returns: ptr to the struct module, NULL for failure
34f42a07 1471 */
b2ab99c9
RL
1472static struct module *
1473fcoe_netdev_to_module_owner(const struct net_device *netdev)
85b4aa49
RL
1474{
1475 struct device *dev;
1476
1477 if (!netdev)
1478 return NULL;
1479
1480 dev = netdev->dev.parent;
1481 if (!dev)
1482 return NULL;
1483
1484 if (!dev->driver)
1485 return NULL;
1486
1487 return dev->driver->owner;
1488}
1489
1490/**
34f42a07 1491 * fcoe_ethdrv_get() - Hold the Ethernet driver
85b4aa49
RL
1492 * @netdev: the target netdev
1493 *
34f42a07
RL
1494 * Holds the Ethernet driver module by try_module_get() for
1495 * the corresponding netdev.
1496 *
85b4aa49 1497 * Returns: 0 for succsss
34f42a07 1498 */
85b4aa49
RL
1499static int fcoe_ethdrv_get(const struct net_device *netdev)
1500{
1501 struct module *owner;
1502
1503 owner = fcoe_netdev_to_module_owner(netdev);
1504 if (owner) {
56b854bb
JB
1505 printk(KERN_DEBUG "fcoe:hold driver module %s for %s\n",
1506 module_name(owner), netdev->name);
85b4aa49
RL
1507 return try_module_get(owner);
1508 }
1509 return -ENODEV;
1510}
1511
1512/**
34f42a07 1513 * fcoe_ethdrv_put() - Release the Ethernet driver
85b4aa49
RL
1514 * @netdev: the target netdev
1515 *
34f42a07
RL
1516 * Releases the Ethernet driver module by module_put for
1517 * the corresponding netdev.
1518 *
85b4aa49 1519 * Returns: 0 for succsss
34f42a07 1520 */
85b4aa49
RL
1521static int fcoe_ethdrv_put(const struct net_device *netdev)
1522{
1523 struct module *owner;
1524
1525 owner = fcoe_netdev_to_module_owner(netdev);
1526 if (owner) {
56b854bb
JB
1527 printk(KERN_DEBUG "fcoe:release driver module %s for %s\n",
1528 module_name(owner), netdev->name);
85b4aa49
RL
1529 module_put(owner);
1530 return 0;
1531 }
1532 return -ENODEV;
1533}
1534
1535/**
34f42a07 1536 * fcoe_destroy() - handles the destroy from sysfs
85b4aa49
RL
1537 * @buffer: expcted to be a eth if name
1538 * @kp: associated kernel param
1539 *
1540 * Returns: 0 for success
34f42a07 1541 */
85b4aa49
RL
1542static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
1543{
1544 int rc;
1545 struct net_device *netdev;
1546
1547 netdev = fcoe_if_to_netdev(buffer);
1548 if (!netdev) {
1549 rc = -ENODEV;
1550 goto out_nodev;
1551 }
1552 /* look for existing lport */
1553 if (!fcoe_hostlist_lookup(netdev)) {
1554 rc = -ENODEV;
1555 goto out_putdev;
1556 }
7f349142 1557 rc = fcoe_if_destroy(netdev);
85b4aa49 1558 if (rc) {
7f349142 1559 printk(KERN_ERR "fcoe: fcoe_if_destroy(%s) failed\n",
85b4aa49
RL
1560 netdev->name);
1561 rc = -EIO;
1562 goto out_putdev;
1563 }
1564 fcoe_ethdrv_put(netdev);
1565 rc = 0;
1566out_putdev:
1567 dev_put(netdev);
1568out_nodev:
1569 return rc;
1570}
1571
1572/**
34f42a07 1573 * fcoe_create() - Handles the create call from sysfs
85b4aa49
RL
1574 * @buffer: expcted to be a eth if name
1575 * @kp: associated kernel param
1576 *
1577 * Returns: 0 for success
34f42a07 1578 */
85b4aa49
RL
1579static int fcoe_create(const char *buffer, struct kernel_param *kp)
1580{
1581 int rc;
1582 struct net_device *netdev;
1583
1584 netdev = fcoe_if_to_netdev(buffer);
1585 if (!netdev) {
1586 rc = -ENODEV;
1587 goto out_nodev;
1588 }
1589 /* look for existing lport */
1590 if (fcoe_hostlist_lookup(netdev)) {
1591 rc = -EEXIST;
1592 goto out_putdev;
1593 }
1594 fcoe_ethdrv_get(netdev);
1595
7f349142 1596 rc = fcoe_if_create(netdev);
85b4aa49 1597 if (rc) {
7f349142 1598 printk(KERN_ERR "fcoe: fcoe_if_create(%s) failed\n",
85b4aa49
RL
1599 netdev->name);
1600 fcoe_ethdrv_put(netdev);
1601 rc = -EIO;
1602 goto out_putdev;
1603 }
1604 rc = 0;
1605out_putdev:
1606 dev_put(netdev);
1607out_nodev:
1608 return rc;
1609}
1610
1611module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
1612__MODULE_PARM_TYPE(create, "string");
1613MODULE_PARM_DESC(create, "Create fcoe port using net device passed in.");
1614module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
1615__MODULE_PARM_TYPE(destroy, "string");
1616MODULE_PARM_DESC(destroy, "Destroy fcoe port");
1617
34f42a07
RL
1618/**
1619 * fcoe_link_ok() - Check if link is ok for the fc_lport
85b4aa49
RL
1620 * @lp: ptr to the fc_lport
1621 *
1622 * Any permanently-disqualifying conditions have been previously checked.
1623 * This also updates the speed setting, which may change with link for 100/1000.
1624 *
1625 * This function should probably be checking for PAUSE support at some point
1626 * in the future. Currently Per-priority-pause is not determinable using
1627 * ethtool, so we shouldn't be restrictive until that problem is resolved.
1628 *
1629 * Returns: 0 if link is OK for use by FCoE.
1630 *
1631 */
1632int fcoe_link_ok(struct fc_lport *lp)
1633{
fc47ff6b 1634 struct fcoe_softc *fc = lport_priv(lp);
85b4aa49
RL
1635 struct net_device *dev = fc->real_dev;
1636 struct ethtool_cmd ecmd = { ETHTOOL_GSET };
1637 int rc = 0;
1638
1639 if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
1640 dev = fc->phys_dev;
1641 if (dev->ethtool_ops->get_settings) {
1642 dev->ethtool_ops->get_settings(dev, &ecmd);
1643 lp->link_supported_speeds &=
1644 ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
1645 if (ecmd.supported & (SUPPORTED_1000baseT_Half |
1646 SUPPORTED_1000baseT_Full))
1647 lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
1648 if (ecmd.supported & SUPPORTED_10000baseT_Full)
1649 lp->link_supported_speeds |=
1650 FC_PORTSPEED_10GBIT;
1651 if (ecmd.speed == SPEED_1000)
1652 lp->link_speed = FC_PORTSPEED_1GBIT;
1653 if (ecmd.speed == SPEED_10000)
1654 lp->link_speed = FC_PORTSPEED_10GBIT;
1655 }
1656 } else
1657 rc = -1;
1658
1659 return rc;
1660}
1661EXPORT_SYMBOL_GPL(fcoe_link_ok);
1662
34f42a07
RL
1663/**
1664 * fcoe_percpu_clean() - Clear the pending skbs for an lport
85b4aa49
RL
1665 * @lp: the fc_lport
1666 */
1667void fcoe_percpu_clean(struct fc_lport *lp)
1668{
85b4aa49
RL
1669 struct fcoe_percpu_s *pp;
1670 struct fcoe_rcv_info *fr;
1671 struct sk_buff_head *list;
1672 struct sk_buff *skb, *next;
1673 struct sk_buff *head;
5e5e92df 1674 unsigned int cpu;
85b4aa49 1675
5e5e92df
RL
1676 for_each_possible_cpu(cpu) {
1677 pp = &per_cpu(fcoe_percpu, cpu);
1678 spin_lock_bh(&pp->fcoe_rx_list.lock);
1679 list = &pp->fcoe_rx_list;
1680 head = list->next;
1681 for (skb = head; skb != (struct sk_buff *)list;
1682 skb = next) {
1683 next = skb->next;
1684 fr = fcoe_dev_from_skb(skb);
1685 if (fr->fr_dev == lp) {
1686 __skb_unlink(skb, list);
1687 kfree_skb(skb);
85b4aa49 1688 }
85b4aa49 1689 }
5e5e92df 1690 spin_unlock_bh(&pp->fcoe_rx_list.lock);
85b4aa49
RL
1691 }
1692}
1693EXPORT_SYMBOL_GPL(fcoe_percpu_clean);
1694
1695/**
34f42a07 1696 * fcoe_clean_pending_queue() - Dequeue a skb and free it
85b4aa49
RL
1697 * @lp: the corresponding fc_lport
1698 *
1699 * Returns: none
34f42a07 1700 */
85b4aa49
RL
1701void fcoe_clean_pending_queue(struct fc_lport *lp)
1702{
1703 struct fcoe_softc *fc = lport_priv(lp);
1704 struct sk_buff *skb;
1705
1706 spin_lock_bh(&fc->fcoe_pending_queue.lock);
1707 while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
1708 spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1709 kfree_skb(skb);
1710 spin_lock_bh(&fc->fcoe_pending_queue.lock);
1711 }
1712 spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1713}
1714EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
1715
34f42a07
RL
1716/**
1717 * fcoe_reset() - Resets the fcoe
85b4aa49
RL
1718 * @shost: shost the reset is from
1719 *
1720 * Returns: always 0
1721 */
1722int fcoe_reset(struct Scsi_Host *shost)
1723{
1724 struct fc_lport *lport = shost_priv(shost);
1725 fc_lport_reset(lport);
1726 return 0;
1727}
1728EXPORT_SYMBOL_GPL(fcoe_reset);
1729
34f42a07
RL
1730/**
1731 * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device
85b4aa49
RL
1732 * @device: this is currently ptr to net_device
1733 *
1734 * Returns: NULL or the located fcoe_softc
1735 */
b2ab99c9
RL
1736static struct fcoe_softc *
1737fcoe_hostlist_lookup_softc(const struct net_device *dev)
85b4aa49
RL
1738{
1739 struct fcoe_softc *fc;
1740
1741 read_lock(&fcoe_hostlist_lock);
1742 list_for_each_entry(fc, &fcoe_hostlist, list) {
1743 if (fc->real_dev == dev) {
1744 read_unlock(&fcoe_hostlist_lock);
1745 return fc;
1746 }
1747 }
1748 read_unlock(&fcoe_hostlist_lock);
1749 return NULL;
1750}
1751
34f42a07
RL
1752/**
1753 * fcoe_hostlist_lookup() - Find the corresponding lport by netdev
85b4aa49
RL
1754 * @netdev: ptr to net_device
1755 *
1756 * Returns: 0 for success
1757 */
1758struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
1759{
1760 struct fcoe_softc *fc;
1761
1762 fc = fcoe_hostlist_lookup_softc(netdev);
1763
1764 return (fc) ? fc->lp : NULL;
1765}
1766EXPORT_SYMBOL_GPL(fcoe_hostlist_lookup);
1767
34f42a07
RL
1768/**
1769 * fcoe_hostlist_add() - Add a lport to lports list
85b4aa49
RL
1770 * @lp: ptr to the fc_lport to badded
1771 *
1772 * Returns: 0 for success
1773 */
1774int fcoe_hostlist_add(const struct fc_lport *lp)
1775{
1776 struct fcoe_softc *fc;
1777
1778 fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
1779 if (!fc) {
fc47ff6b 1780 fc = lport_priv(lp);
85b4aa49
RL
1781 write_lock_bh(&fcoe_hostlist_lock);
1782 list_add_tail(&fc->list, &fcoe_hostlist);
1783 write_unlock_bh(&fcoe_hostlist_lock);
1784 }
1785 return 0;
1786}
1787EXPORT_SYMBOL_GPL(fcoe_hostlist_add);
1788
34f42a07
RL
1789/**
1790 * fcoe_hostlist_remove() - remove a lport from lports list
85b4aa49
RL
1791 * @lp: ptr to the fc_lport to badded
1792 *
1793 * Returns: 0 for success
1794 */
1795int fcoe_hostlist_remove(const struct fc_lport *lp)
1796{
1797 struct fcoe_softc *fc;
1798
1799 fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
1800 BUG_ON(!fc);
1801 write_lock_bh(&fcoe_hostlist_lock);
1802 list_del(&fc->list);
1803 write_unlock_bh(&fcoe_hostlist_lock);
1804
1805 return 0;
1806}
1807EXPORT_SYMBOL_GPL(fcoe_hostlist_remove);
1808
85b4aa49 1809/**
34f42a07 1810 * fcoe_init() - fcoe module loading initialization
85b4aa49 1811 *
85b4aa49 1812 * Returns 0 on success, negative on failure
34f42a07 1813 */
85b4aa49
RL
1814static int __init fcoe_init(void)
1815{
38eccabd 1816 unsigned int cpu;
8976f424 1817 int rc = 0;
85b4aa49
RL
1818 struct fcoe_percpu_s *p;
1819
85b4aa49
RL
1820 INIT_LIST_HEAD(&fcoe_hostlist);
1821 rwlock_init(&fcoe_hostlist_lock);
1822
38eccabd 1823 for_each_possible_cpu(cpu) {
5e5e92df 1824 p = &per_cpu(fcoe_percpu, cpu);
38eccabd
RL
1825 skb_queue_head_init(&p->fcoe_rx_list);
1826 }
1827
8976f424
RL
1828 for_each_online_cpu(cpu)
1829 fcoe_percpu_thread_create(cpu);
85b4aa49 1830
8976f424
RL
1831 /* Initialize per CPU interrupt thread */
1832 rc = register_hotcpu_notifier(&fcoe_cpu_notifier);
1833 if (rc)
1834 goto out_free;
85b4aa49 1835
8976f424 1836 /* Setup link change notification */
85b4aa49
RL
1837 fcoe_dev_setup();
1838
a468f328
RL
1839 setup_timer(&fcoe_timer, fcoe_watchdog, 0);
1840
1841 mod_timer(&fcoe_timer, jiffies + (10 * HZ));
85b4aa49 1842
7f349142 1843 fcoe_if_init();
85b4aa49
RL
1844
1845 return 0;
8976f424
RL
1846
1847out_free:
1848 for_each_online_cpu(cpu) {
1849 fcoe_percpu_thread_destroy(cpu);
1850 }
1851
1852 return rc;
85b4aa49
RL
1853}
1854module_init(fcoe_init);
1855
1856/**
34f42a07 1857 * fcoe_exit() - fcoe module unloading cleanup
85b4aa49
RL
1858 *
1859 * Returns 0 on success, negative on failure
34f42a07 1860 */
85b4aa49
RL
1861static void __exit fcoe_exit(void)
1862{
5e5e92df 1863 unsigned int cpu;
85b4aa49 1864 struct fcoe_softc *fc, *tmp;
85b4aa49 1865
85b4aa49
RL
1866 fcoe_dev_cleanup();
1867
582b45bc 1868 /* Stop the timer */
85b4aa49
RL
1869 del_timer_sync(&fcoe_timer);
1870
5919a595 1871 /* releases the associated fcoe hosts */
85b4aa49 1872 list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
7f349142 1873 fcoe_if_destroy(fc->real_dev);
85b4aa49 1874
8976f424
RL
1875 unregister_hotcpu_notifier(&fcoe_cpu_notifier);
1876
1877 for_each_online_cpu(cpu) {
1878 fcoe_percpu_thread_destroy(cpu);
85b4aa49
RL
1879 }
1880
7f349142
VD
1881 /* detach from scsi transport */
1882 fcoe_if_exit();
85b4aa49
RL
1883}
1884module_exit(fcoe_exit);
This page took 0.17276 seconds and 5 git commands to generate.