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