diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 20:54:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 20:54:40 -0400 |
commit | c55d267de274d308927b60c3e740c1a826832317 (patch) | |
tree | 21b53a8c725d9f9650f60d94b349459d5b8dae10 /drivers/scsi/fcoe/fcoe.c | |
parent | 61ef46fd45c3c62dc7c880a45dd2aa841b9af8fb (diff) | |
parent | bc898c97f7ba24def788d9f80786cf028a197122 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (170 commits)
[SCSI] scsi_dh_rdac: Add MD36xxf into device list
[SCSI] scsi_debug: add consecutive medium errors
[SCSI] libsas: fix ata list corruption issue
[SCSI] hpsa: export resettable host attribute
[SCSI] hpsa: move device attributes to avoid forward declarations
[SCSI] scsi_debug: Logical Block Provisioning (SBC3r26)
[SCSI] sd: Logical Block Provisioning update
[SCSI] Include protection operation in SCSI command trace
[SCSI] hpsa: fix incorrect PCI IDs and add two new ones (2nd try)
[SCSI] target: Fix volume size misreporting for volumes > 2TB
[SCSI] bnx2fc: Broadcom FCoE offload driver
[SCSI] fcoe: fix broken fcoe interface reset
[SCSI] fcoe: precedence bug in fcoe_filter_frames()
[SCSI] libfcoe: Remove stale fcoe-netdev entries
[SCSI] libfcoe: Move FCOE_MTU definition from fcoe.h to libfcoe.h
[SCSI] libfc: introduce __fc_fill_fc_hdr that accepts fc_hdr as an argument
[SCSI] fcoe, libfc: initialize EM anchors list and then update npiv EMs
[SCSI] Revert "[SCSI] libfc: fix exchange being deleted when the abort itself is timed out"
[SCSI] libfc: Fixing a memory leak when destroying an interface
[SCSI] megaraid_sas: Version and Changelog update
...
Fix up trivial conflicts due to whitespace differences in
drivers/scsi/libsas/{sas_ata.c,sas_scsi_host.c}
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 621 |
1 files changed, 225 insertions, 396 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 3becc6a20a4f..bde6ee5333eb 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
32 | #include <linux/sysfs.h> | 32 | #include <linux/sysfs.h> |
33 | #include <linux/ctype.h> | 33 | #include <linux/ctype.h> |
34 | #include <linux/workqueue.h> | ||
34 | #include <scsi/scsi_tcq.h> | 35 | #include <scsi/scsi_tcq.h> |
35 | #include <scsi/scsicam.h> | 36 | #include <scsi/scsicam.h> |
36 | #include <scsi/scsi_transport.h> | 37 | #include <scsi/scsi_transport.h> |
@@ -58,6 +59,8 @@ MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for " \ | |||
58 | 59 | ||
59 | DEFINE_MUTEX(fcoe_config_mutex); | 60 | DEFINE_MUTEX(fcoe_config_mutex); |
60 | 61 | ||
62 | static struct workqueue_struct *fcoe_wq; | ||
63 | |||
61 | /* fcoe_percpu_clean completion. Waiter protected by fcoe_create_mutex */ | 64 | /* fcoe_percpu_clean completion. Waiter protected by fcoe_create_mutex */ |
62 | static DECLARE_COMPLETION(fcoe_flush_completion); | 65 | static DECLARE_COMPLETION(fcoe_flush_completion); |
63 | 66 | ||
@@ -72,7 +75,6 @@ static int fcoe_xmit(struct fc_lport *, struct fc_frame *); | |||
72 | static int fcoe_rcv(struct sk_buff *, struct net_device *, | 75 | static int fcoe_rcv(struct sk_buff *, struct net_device *, |
73 | struct packet_type *, struct net_device *); | 76 | struct packet_type *, struct net_device *); |
74 | static int fcoe_percpu_receive_thread(void *); | 77 | static int fcoe_percpu_receive_thread(void *); |
75 | static void fcoe_clean_pending_queue(struct fc_lport *); | ||
76 | static void fcoe_percpu_clean(struct fc_lport *); | 78 | static void fcoe_percpu_clean(struct fc_lport *); |
77 | static int fcoe_link_speed_update(struct fc_lport *); | 79 | static int fcoe_link_speed_update(struct fc_lport *); |
78 | static int fcoe_link_ok(struct fc_lport *); | 80 | static int fcoe_link_ok(struct fc_lport *); |
@@ -80,7 +82,6 @@ static int fcoe_link_ok(struct fc_lport *); | |||
80 | static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); | 82 | static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); |
81 | static int fcoe_hostlist_add(const struct fc_lport *); | 83 | static int fcoe_hostlist_add(const struct fc_lport *); |
82 | 84 | ||
83 | static void fcoe_check_wait_queue(struct fc_lport *, struct sk_buff *); | ||
84 | static int fcoe_device_notification(struct notifier_block *, ulong, void *); | 85 | static int fcoe_device_notification(struct notifier_block *, ulong, void *); |
85 | static void fcoe_dev_setup(void); | 86 | static void fcoe_dev_setup(void); |
86 | static void fcoe_dev_cleanup(void); | 87 | static void fcoe_dev_cleanup(void); |
@@ -101,10 +102,11 @@ static int fcoe_ddp_done(struct fc_lport *, u16); | |||
101 | 102 | ||
102 | static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); | 103 | static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); |
103 | 104 | ||
104 | static int fcoe_create(const char *, struct kernel_param *); | 105 | static bool fcoe_match(struct net_device *netdev); |
105 | static int fcoe_destroy(const char *, struct kernel_param *); | 106 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode); |
106 | static int fcoe_enable(const char *, struct kernel_param *); | 107 | static int fcoe_destroy(struct net_device *netdev); |
107 | static int fcoe_disable(const char *, struct kernel_param *); | 108 | static int fcoe_enable(struct net_device *netdev); |
109 | static int fcoe_disable(struct net_device *netdev); | ||
108 | 110 | ||
109 | static struct fc_seq *fcoe_elsct_send(struct fc_lport *, | 111 | static struct fc_seq *fcoe_elsct_send(struct fc_lport *, |
110 | u32 did, struct fc_frame *, | 112 | u32 did, struct fc_frame *, |
@@ -117,24 +119,6 @@ static void fcoe_recv_frame(struct sk_buff *skb); | |||
117 | 119 | ||
118 | static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *); | 120 | static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *); |
119 | 121 | ||
120 | module_param_call(create, fcoe_create, NULL, (void *)FIP_MODE_FABRIC, S_IWUSR); | ||
121 | __MODULE_PARM_TYPE(create, "string"); | ||
122 | MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface"); | ||
123 | module_param_call(create_vn2vn, fcoe_create, NULL, | ||
124 | (void *)FIP_MODE_VN2VN, S_IWUSR); | ||
125 | __MODULE_PARM_TYPE(create_vn2vn, "string"); | ||
126 | MODULE_PARM_DESC(create_vn2vn, " Creates a VN_node to VN_node FCoE instance " | ||
127 | "on an Ethernet interface"); | ||
128 | module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); | ||
129 | __MODULE_PARM_TYPE(destroy, "string"); | ||
130 | MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface"); | ||
131 | module_param_call(enable, fcoe_enable, NULL, NULL, S_IWUSR); | ||
132 | __MODULE_PARM_TYPE(enable, "string"); | ||
133 | MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface."); | ||
134 | module_param_call(disable, fcoe_disable, NULL, NULL, S_IWUSR); | ||
135 | __MODULE_PARM_TYPE(disable, "string"); | ||
136 | MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface."); | ||
137 | |||
138 | /* notification function for packets from net device */ | 122 | /* notification function for packets from net device */ |
139 | static struct notifier_block fcoe_notifier = { | 123 | static struct notifier_block fcoe_notifier = { |
140 | .notifier_call = fcoe_device_notification, | 124 | .notifier_call = fcoe_device_notification, |
@@ -145,8 +129,8 @@ static struct notifier_block fcoe_cpu_notifier = { | |||
145 | .notifier_call = fcoe_cpu_callback, | 129 | .notifier_call = fcoe_cpu_callback, |
146 | }; | 130 | }; |
147 | 131 | ||
148 | static struct scsi_transport_template *fcoe_transport_template; | 132 | static struct scsi_transport_template *fcoe_nport_scsi_transport; |
149 | static struct scsi_transport_template *fcoe_vport_transport_template; | 133 | static struct scsi_transport_template *fcoe_vport_scsi_transport; |
150 | 134 | ||
151 | static int fcoe_vport_destroy(struct fc_vport *); | 135 | static int fcoe_vport_destroy(struct fc_vport *); |
152 | static int fcoe_vport_create(struct fc_vport *, bool disabled); | 136 | static int fcoe_vport_create(struct fc_vport *, bool disabled); |
@@ -163,7 +147,7 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = { | |||
163 | .lport_set_port_id = fcoe_set_port_id, | 147 | .lport_set_port_id = fcoe_set_port_id, |
164 | }; | 148 | }; |
165 | 149 | ||
166 | struct fc_function_template fcoe_transport_function = { | 150 | struct fc_function_template fcoe_nport_fc_functions = { |
167 | .show_host_node_name = 1, | 151 | .show_host_node_name = 1, |
168 | .show_host_port_name = 1, | 152 | .show_host_port_name = 1, |
169 | .show_host_supported_classes = 1, | 153 | .show_host_supported_classes = 1, |
@@ -203,7 +187,7 @@ struct fc_function_template fcoe_transport_function = { | |||
203 | .bsg_request = fc_lport_bsg_request, | 187 | .bsg_request = fc_lport_bsg_request, |
204 | }; | 188 | }; |
205 | 189 | ||
206 | struct fc_function_template fcoe_vport_transport_function = { | 190 | struct fc_function_template fcoe_vport_fc_functions = { |
207 | .show_host_node_name = 1, | 191 | .show_host_node_name = 1, |
208 | .show_host_port_name = 1, | 192 | .show_host_port_name = 1, |
209 | .show_host_supported_classes = 1, | 193 | .show_host_supported_classes = 1, |
@@ -354,10 +338,18 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, | |||
354 | struct fcoe_interface *fcoe; | 338 | struct fcoe_interface *fcoe; |
355 | int err; | 339 | int err; |
356 | 340 | ||
341 | if (!try_module_get(THIS_MODULE)) { | ||
342 | FCOE_NETDEV_DBG(netdev, | ||
343 | "Could not get a reference to the module\n"); | ||
344 | fcoe = ERR_PTR(-EBUSY); | ||
345 | goto out; | ||
346 | } | ||
347 | |||
357 | fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL); | 348 | fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL); |
358 | if (!fcoe) { | 349 | if (!fcoe) { |
359 | FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); | 350 | FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); |
360 | return NULL; | 351 | fcoe = ERR_PTR(-ENOMEM); |
352 | goto out_nomod; | ||
361 | } | 353 | } |
362 | 354 | ||
363 | dev_hold(netdev); | 355 | dev_hold(netdev); |
@@ -376,9 +368,15 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, | |||
376 | fcoe_ctlr_destroy(&fcoe->ctlr); | 368 | fcoe_ctlr_destroy(&fcoe->ctlr); |
377 | kfree(fcoe); | 369 | kfree(fcoe); |
378 | dev_put(netdev); | 370 | dev_put(netdev); |
379 | return NULL; | 371 | fcoe = ERR_PTR(err); |
372 | goto out_nomod; | ||
380 | } | 373 | } |
381 | 374 | ||
375 | goto out; | ||
376 | |||
377 | out_nomod: | ||
378 | module_put(THIS_MODULE); | ||
379 | out: | ||
382 | return fcoe; | 380 | return fcoe; |
383 | } | 381 | } |
384 | 382 | ||
@@ -440,6 +438,7 @@ static void fcoe_interface_release(struct kref *kref) | |||
440 | fcoe_ctlr_destroy(&fcoe->ctlr); | 438 | fcoe_ctlr_destroy(&fcoe->ctlr); |
441 | kfree(fcoe); | 439 | kfree(fcoe); |
442 | dev_put(netdev); | 440 | dev_put(netdev); |
441 | module_put(THIS_MODULE); | ||
443 | } | 442 | } |
444 | 443 | ||
445 | /** | 444 | /** |
@@ -503,7 +502,7 @@ static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
503 | static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr) | 502 | static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr) |
504 | { | 503 | { |
505 | struct fcoe_port *port = lport_priv(lport); | 504 | struct fcoe_port *port = lport_priv(lport); |
506 | struct fcoe_interface *fcoe = port->fcoe; | 505 | struct fcoe_interface *fcoe = port->priv; |
507 | 506 | ||
508 | rtnl_lock(); | 507 | rtnl_lock(); |
509 | if (!is_zero_ether_addr(port->data_src_addr)) | 508 | if (!is_zero_ether_addr(port->data_src_addr)) |
@@ -559,17 +558,6 @@ static int fcoe_lport_config(struct fc_lport *lport) | |||
559 | } | 558 | } |
560 | 559 | ||
561 | /** | 560 | /** |
562 | * fcoe_queue_timer() - The fcoe queue timer | ||
563 | * @lport: The local port | ||
564 | * | ||
565 | * Calls fcoe_check_wait_queue on timeout | ||
566 | */ | ||
567 | static void fcoe_queue_timer(ulong lport) | ||
568 | { | ||
569 | fcoe_check_wait_queue((struct fc_lport *)lport, NULL); | ||
570 | } | ||
571 | |||
572 | /** | ||
573 | * fcoe_get_wwn() - Get the world wide name from LLD if it supports it | 561 | * fcoe_get_wwn() - Get the world wide name from LLD if it supports it |
574 | * @netdev: the associated net device | 562 | * @netdev: the associated net device |
575 | * @wwn: the output WWN | 563 | * @wwn: the output WWN |
@@ -648,7 +636,7 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) | |||
648 | 636 | ||
649 | /* Setup lport private data to point to fcoe softc */ | 637 | /* Setup lport private data to point to fcoe softc */ |
650 | port = lport_priv(lport); | 638 | port = lport_priv(lport); |
651 | fcoe = port->fcoe; | 639 | fcoe = port->priv; |
652 | 640 | ||
653 | /* | 641 | /* |
654 | * Determine max frame size based on underlying device and optional | 642 | * Determine max frame size based on underlying device and optional |
@@ -706,9 +694,9 @@ static int fcoe_shost_config(struct fc_lport *lport, struct device *dev) | |||
706 | lport->host->max_cmd_len = FCOE_MAX_CMD_LEN; | 694 | lport->host->max_cmd_len = FCOE_MAX_CMD_LEN; |
707 | 695 | ||
708 | if (lport->vport) | 696 | if (lport->vport) |
709 | lport->host->transportt = fcoe_vport_transport_template; | 697 | lport->host->transportt = fcoe_vport_scsi_transport; |
710 | else | 698 | else |
711 | lport->host->transportt = fcoe_transport_template; | 699 | lport->host->transportt = fcoe_nport_scsi_transport; |
712 | 700 | ||
713 | /* add the new host to the SCSI-ml */ | 701 | /* add the new host to the SCSI-ml */ |
714 | rc = scsi_add_host(lport->host, dev); | 702 | rc = scsi_add_host(lport->host, dev); |
@@ -758,7 +746,7 @@ bool fcoe_oem_match(struct fc_frame *fp) | |||
758 | static inline int fcoe_em_config(struct fc_lport *lport) | 746 | static inline int fcoe_em_config(struct fc_lport *lport) |
759 | { | 747 | { |
760 | struct fcoe_port *port = lport_priv(lport); | 748 | struct fcoe_port *port = lport_priv(lport); |
761 | struct fcoe_interface *fcoe = port->fcoe; | 749 | struct fcoe_interface *fcoe = port->priv; |
762 | struct fcoe_interface *oldfcoe = NULL; | 750 | struct fcoe_interface *oldfcoe = NULL; |
763 | struct net_device *old_real_dev, *cur_real_dev; | 751 | struct net_device *old_real_dev, *cur_real_dev; |
764 | u16 min_xid = FCOE_MIN_XID; | 752 | u16 min_xid = FCOE_MIN_XID; |
@@ -842,7 +830,7 @@ skip_oem: | |||
842 | static void fcoe_if_destroy(struct fc_lport *lport) | 830 | static void fcoe_if_destroy(struct fc_lport *lport) |
843 | { | 831 | { |
844 | struct fcoe_port *port = lport_priv(lport); | 832 | struct fcoe_port *port = lport_priv(lport); |
845 | struct fcoe_interface *fcoe = port->fcoe; | 833 | struct fcoe_interface *fcoe = port->priv; |
846 | struct net_device *netdev = fcoe->netdev; | 834 | struct net_device *netdev = fcoe->netdev; |
847 | 835 | ||
848 | FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); | 836 | FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); |
@@ -884,7 +872,6 @@ static void fcoe_if_destroy(struct fc_lport *lport) | |||
884 | 872 | ||
885 | /* Release the Scsi_Host */ | 873 | /* Release the Scsi_Host */ |
886 | scsi_host_put(lport->host); | 874 | scsi_host_put(lport->host); |
887 | module_put(THIS_MODULE); | ||
888 | } | 875 | } |
889 | 876 | ||
890 | /** | 877 | /** |
@@ -939,8 +926,9 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, | |||
939 | struct device *parent, int npiv) | 926 | struct device *parent, int npiv) |
940 | { | 927 | { |
941 | struct net_device *netdev = fcoe->netdev; | 928 | struct net_device *netdev = fcoe->netdev; |
942 | struct fc_lport *lport = NULL; | 929 | struct fc_lport *lport, *n_port; |
943 | struct fcoe_port *port; | 930 | struct fcoe_port *port; |
931 | struct Scsi_Host *shost; | ||
944 | int rc; | 932 | int rc; |
945 | /* | 933 | /* |
946 | * parent is only a vport if npiv is 1, | 934 | * parent is only a vport if npiv is 1, |
@@ -950,13 +938,11 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, | |||
950 | 938 | ||
951 | FCOE_NETDEV_DBG(netdev, "Create Interface\n"); | 939 | FCOE_NETDEV_DBG(netdev, "Create Interface\n"); |
952 | 940 | ||
953 | if (!npiv) { | 941 | if (!npiv) |
954 | lport = libfc_host_alloc(&fcoe_shost_template, | 942 | lport = libfc_host_alloc(&fcoe_shost_template, sizeof(*port)); |
955 | sizeof(struct fcoe_port)); | 943 | else |
956 | } else { | 944 | lport = libfc_vport_create(vport, sizeof(*port)); |
957 | lport = libfc_vport_create(vport, | 945 | |
958 | sizeof(struct fcoe_port)); | ||
959 | } | ||
960 | if (!lport) { | 946 | if (!lport) { |
961 | FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); | 947 | FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); |
962 | rc = -ENOMEM; | 948 | rc = -ENOMEM; |
@@ -964,7 +950,9 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, | |||
964 | } | 950 | } |
965 | port = lport_priv(lport); | 951 | port = lport_priv(lport); |
966 | port->lport = lport; | 952 | port->lport = lport; |
967 | port->fcoe = fcoe; | 953 | port->priv = fcoe; |
954 | port->max_queue_depth = FCOE_MAX_QUEUE_DEPTH; | ||
955 | port->min_queue_depth = FCOE_MIN_QUEUE_DEPTH; | ||
968 | INIT_WORK(&port->destroy_work, fcoe_destroy_work); | 956 | INIT_WORK(&port->destroy_work, fcoe_destroy_work); |
969 | 957 | ||
970 | /* configure a fc_lport including the exchange manager */ | 958 | /* configure a fc_lport including the exchange manager */ |
@@ -1007,24 +995,27 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, | |||
1007 | goto out_lp_destroy; | 995 | goto out_lp_destroy; |
1008 | } | 996 | } |
1009 | 997 | ||
1010 | if (!npiv) { | 998 | /* |
1011 | /* | 999 | * fcoe_em_alloc() and fcoe_hostlist_add() both |
1012 | * fcoe_em_alloc() and fcoe_hostlist_add() both | 1000 | * need to be atomic with respect to other changes to the |
1013 | * need to be atomic with respect to other changes to the | 1001 | * hostlist since fcoe_em_alloc() looks for an existing EM |
1014 | * hostlist since fcoe_em_alloc() looks for an existing EM | 1002 | * instance on host list updated by fcoe_hostlist_add(). |
1015 | * instance on host list updated by fcoe_hostlist_add(). | 1003 | * |
1016 | * | 1004 | * This is currently handled through the fcoe_config_mutex |
1017 | * This is currently handled through the fcoe_config_mutex | 1005 | * begin held. |
1018 | * begin held. | 1006 | */ |
1019 | */ | 1007 | if (!npiv) |
1020 | |||
1021 | /* lport exch manager allocation */ | 1008 | /* lport exch manager allocation */ |
1022 | rc = fcoe_em_config(lport); | 1009 | rc = fcoe_em_config(lport); |
1023 | if (rc) { | 1010 | else { |
1024 | FCOE_NETDEV_DBG(netdev, "Could not configure the EM " | 1011 | shost = vport_to_shost(vport); |
1025 | "for the interface\n"); | 1012 | n_port = shost_priv(shost); |
1026 | goto out_lp_destroy; | 1013 | rc = fc_exch_mgr_list_clone(n_port, lport); |
1027 | } | 1014 | } |
1015 | |||
1016 | if (rc) { | ||
1017 | FCOE_NETDEV_DBG(netdev, "Could not configure the EM\n"); | ||
1018 | goto out_lp_destroy; | ||
1028 | } | 1019 | } |
1029 | 1020 | ||
1030 | fcoe_interface_get(fcoe); | 1021 | fcoe_interface_get(fcoe); |
@@ -1048,11 +1039,12 @@ out: | |||
1048 | static int __init fcoe_if_init(void) | 1039 | static int __init fcoe_if_init(void) |
1049 | { | 1040 | { |
1050 | /* attach to scsi transport */ | 1041 | /* attach to scsi transport */ |
1051 | fcoe_transport_template = fc_attach_transport(&fcoe_transport_function); | 1042 | fcoe_nport_scsi_transport = |
1052 | fcoe_vport_transport_template = | 1043 | fc_attach_transport(&fcoe_nport_fc_functions); |
1053 | fc_attach_transport(&fcoe_vport_transport_function); | 1044 | fcoe_vport_scsi_transport = |
1045 | fc_attach_transport(&fcoe_vport_fc_functions); | ||
1054 | 1046 | ||
1055 | if (!fcoe_transport_template) { | 1047 | if (!fcoe_nport_scsi_transport) { |
1056 | printk(KERN_ERR "fcoe: Failed to attach to the FC transport\n"); | 1048 | printk(KERN_ERR "fcoe: Failed to attach to the FC transport\n"); |
1057 | return -ENODEV; | 1049 | return -ENODEV; |
1058 | } | 1050 | } |
@@ -1069,10 +1061,10 @@ static int __init fcoe_if_init(void) | |||
1069 | */ | 1061 | */ |
1070 | int __exit fcoe_if_exit(void) | 1062 | int __exit fcoe_if_exit(void) |
1071 | { | 1063 | { |
1072 | fc_release_transport(fcoe_transport_template); | 1064 | fc_release_transport(fcoe_nport_scsi_transport); |
1073 | fc_release_transport(fcoe_vport_transport_template); | 1065 | fc_release_transport(fcoe_vport_scsi_transport); |
1074 | fcoe_transport_template = NULL; | 1066 | fcoe_nport_scsi_transport = NULL; |
1075 | fcoe_vport_transport_template = NULL; | 1067 | fcoe_vport_scsi_transport = NULL; |
1076 | return 0; | 1068 | return 0; |
1077 | } | 1069 | } |
1078 | 1070 | ||
@@ -1359,108 +1351,22 @@ err2: | |||
1359 | } | 1351 | } |
1360 | 1352 | ||
1361 | /** | 1353 | /** |
1362 | * fcoe_start_io() - Start FCoE I/O | 1354 | * fcoe_alloc_paged_crc_eof() - Allocate a page to be used for the trailer CRC |
1363 | * @skb: The packet to be transmitted | ||
1364 | * | ||
1365 | * This routine is called from the net device to start transmitting | ||
1366 | * FCoE packets. | ||
1367 | * | ||
1368 | * Returns: 0 for success | ||
1369 | */ | ||
1370 | static inline int fcoe_start_io(struct sk_buff *skb) | ||
1371 | { | ||
1372 | struct sk_buff *nskb; | ||
1373 | int rc; | ||
1374 | |||
1375 | nskb = skb_clone(skb, GFP_ATOMIC); | ||
1376 | rc = dev_queue_xmit(nskb); | ||
1377 | if (rc != 0) | ||
1378 | return rc; | ||
1379 | kfree_skb(skb); | ||
1380 | return 0; | ||
1381 | } | ||
1382 | |||
1383 | /** | ||
1384 | * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC | ||
1385 | * @skb: The packet to be transmitted | 1355 | * @skb: The packet to be transmitted |
1386 | * @tlen: The total length of the trailer | 1356 | * @tlen: The total length of the trailer |
1387 | * | 1357 | * |
1388 | * This routine allocates a page for frame trailers. The page is re-used if | ||
1389 | * there is enough room left on it for the current trailer. If there isn't | ||
1390 | * enough buffer left a new page is allocated for the trailer. Reference to | ||
1391 | * the page from this function as well as the skbs using the page fragments | ||
1392 | * ensure that the page is freed at the appropriate time. | ||
1393 | * | ||
1394 | * Returns: 0 for success | 1358 | * Returns: 0 for success |
1395 | */ | 1359 | */ |
1396 | static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) | 1360 | static int fcoe_alloc_paged_crc_eof(struct sk_buff *skb, int tlen) |
1397 | { | 1361 | { |
1398 | struct fcoe_percpu_s *fps; | 1362 | struct fcoe_percpu_s *fps; |
1399 | struct page *page; | 1363 | int rc; |
1400 | 1364 | ||
1401 | fps = &get_cpu_var(fcoe_percpu); | 1365 | fps = &get_cpu_var(fcoe_percpu); |
1402 | page = fps->crc_eof_page; | 1366 | rc = fcoe_get_paged_crc_eof(skb, tlen, fps); |
1403 | if (!page) { | ||
1404 | page = alloc_page(GFP_ATOMIC); | ||
1405 | if (!page) { | ||
1406 | put_cpu_var(fcoe_percpu); | ||
1407 | return -ENOMEM; | ||
1408 | } | ||
1409 | fps->crc_eof_page = page; | ||
1410 | fps->crc_eof_offset = 0; | ||
1411 | } | ||
1412 | |||
1413 | get_page(page); | ||
1414 | skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page, | ||
1415 | fps->crc_eof_offset, tlen); | ||
1416 | skb->len += tlen; | ||
1417 | skb->data_len += tlen; | ||
1418 | skb->truesize += tlen; | ||
1419 | fps->crc_eof_offset += sizeof(struct fcoe_crc_eof); | ||
1420 | |||
1421 | if (fps->crc_eof_offset >= PAGE_SIZE) { | ||
1422 | fps->crc_eof_page = NULL; | ||
1423 | fps->crc_eof_offset = 0; | ||
1424 | put_page(page); | ||
1425 | } | ||
1426 | put_cpu_var(fcoe_percpu); | 1367 | put_cpu_var(fcoe_percpu); |
1427 | return 0; | ||
1428 | } | ||
1429 | 1368 | ||
1430 | /** | 1369 | return rc; |
1431 | * fcoe_fc_crc() - Calculates the CRC for a given frame | ||
1432 | * @fp: The frame to be checksumed | ||
1433 | * | ||
1434 | * This uses crc32() routine to calculate the CRC for a frame | ||
1435 | * | ||
1436 | * Return: The 32 bit CRC value | ||
1437 | */ | ||
1438 | u32 fcoe_fc_crc(struct fc_frame *fp) | ||
1439 | { | ||
1440 | struct sk_buff *skb = fp_skb(fp); | ||
1441 | struct skb_frag_struct *frag; | ||
1442 | unsigned char *data; | ||
1443 | unsigned long off, len, clen; | ||
1444 | u32 crc; | ||
1445 | unsigned i; | ||
1446 | |||
1447 | crc = crc32(~0, skb->data, skb_headlen(skb)); | ||
1448 | |||
1449 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | ||
1450 | frag = &skb_shinfo(skb)->frags[i]; | ||
1451 | off = frag->page_offset; | ||
1452 | len = frag->size; | ||
1453 | while (len > 0) { | ||
1454 | clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK)); | ||
1455 | data = kmap_atomic(frag->page + (off >> PAGE_SHIFT), | ||
1456 | KM_SKB_DATA_SOFTIRQ); | ||
1457 | crc = crc32(crc, data + (off & ~PAGE_MASK), clen); | ||
1458 | kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ); | ||
1459 | off += clen; | ||
1460 | len -= clen; | ||
1461 | } | ||
1462 | } | ||
1463 | return crc; | ||
1464 | } | 1370 | } |
1465 | 1371 | ||
1466 | /** | 1372 | /** |
@@ -1483,7 +1389,7 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
1483 | unsigned int tlen; /* trailer length */ | 1389 | unsigned int tlen; /* trailer length */ |
1484 | unsigned int elen; /* eth header, may include vlan */ | 1390 | unsigned int elen; /* eth header, may include vlan */ |
1485 | struct fcoe_port *port = lport_priv(lport); | 1391 | struct fcoe_port *port = lport_priv(lport); |
1486 | struct fcoe_interface *fcoe = port->fcoe; | 1392 | struct fcoe_interface *fcoe = port->priv; |
1487 | u8 sof, eof; | 1393 | u8 sof, eof; |
1488 | struct fcoe_hdr *hp; | 1394 | struct fcoe_hdr *hp; |
1489 | 1395 | ||
@@ -1524,7 +1430,7 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
1524 | /* copy port crc and eof to the skb buff */ | 1430 | /* copy port crc and eof to the skb buff */ |
1525 | if (skb_is_nonlinear(skb)) { | 1431 | if (skb_is_nonlinear(skb)) { |
1526 | skb_frag_t *frag; | 1432 | skb_frag_t *frag; |
1527 | if (fcoe_get_paged_crc_eof(skb, tlen)) { | 1433 | if (fcoe_alloc_paged_crc_eof(skb, tlen)) { |
1528 | kfree_skb(skb); | 1434 | kfree_skb(skb); |
1529 | return -ENOMEM; | 1435 | return -ENOMEM; |
1530 | } | 1436 | } |
@@ -1604,6 +1510,56 @@ static void fcoe_percpu_flush_done(struct sk_buff *skb) | |||
1604 | } | 1510 | } |
1605 | 1511 | ||
1606 | /** | 1512 | /** |
1513 | * fcoe_filter_frames() - filter out bad fcoe frames, i.e. bad CRC | ||
1514 | * @lport: The local port the frame was received on | ||
1515 | * @fp: The received frame | ||
1516 | * | ||
1517 | * Return: 0 on passing filtering checks | ||
1518 | */ | ||
1519 | static inline int fcoe_filter_frames(struct fc_lport *lport, | ||
1520 | struct fc_frame *fp) | ||
1521 | { | ||
1522 | struct fcoe_interface *fcoe; | ||
1523 | struct fc_frame_header *fh; | ||
1524 | struct sk_buff *skb = (struct sk_buff *)fp; | ||
1525 | struct fcoe_dev_stats *stats; | ||
1526 | |||
1527 | /* | ||
1528 | * We only check CRC if no offload is available and if it is | ||
1529 | * it's solicited data, in which case, the FCP layer would | ||
1530 | * check it during the copy. | ||
1531 | */ | ||
1532 | if (lport->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY) | ||
1533 | fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; | ||
1534 | else | ||
1535 | fr_flags(fp) |= FCPHF_CRC_UNCHECKED; | ||
1536 | |||
1537 | fh = (struct fc_frame_header *) skb_transport_header(skb); | ||
1538 | fh = fc_frame_header_get(fp); | ||
1539 | if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && fh->fh_type == FC_TYPE_FCP) | ||
1540 | return 0; | ||
1541 | |||
1542 | fcoe = ((struct fcoe_port *)lport_priv(lport))->priv; | ||
1543 | if (is_fip_mode(&fcoe->ctlr) && fc_frame_payload_op(fp) == ELS_LOGO && | ||
1544 | ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { | ||
1545 | FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n"); | ||
1546 | return -EINVAL; | ||
1547 | } | ||
1548 | |||
1549 | if (!(fr_flags(fp) & FCPHF_CRC_UNCHECKED) || | ||
1550 | le32_to_cpu(fr_crc(fp)) == ~crc32(~0, skb->data, skb->len)) { | ||
1551 | fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; | ||
1552 | return 0; | ||
1553 | } | ||
1554 | |||
1555 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); | ||
1556 | stats->InvalidCRCCount++; | ||
1557 | if (stats->InvalidCRCCount < 5) | ||
1558 | printk(KERN_WARNING "fcoe: dropping frame with CRC error\n"); | ||
1559 | return -EINVAL; | ||
1560 | } | ||
1561 | |||
1562 | /** | ||
1607 | * fcoe_recv_frame() - process a single received frame | 1563 | * fcoe_recv_frame() - process a single received frame |
1608 | * @skb: frame to process | 1564 | * @skb: frame to process |
1609 | */ | 1565 | */ |
@@ -1613,7 +1569,6 @@ static void fcoe_recv_frame(struct sk_buff *skb) | |||
1613 | struct fc_lport *lport; | 1569 | struct fc_lport *lport; |
1614 | struct fcoe_rcv_info *fr; | 1570 | struct fcoe_rcv_info *fr; |
1615 | struct fcoe_dev_stats *stats; | 1571 | struct fcoe_dev_stats *stats; |
1616 | struct fc_frame_header *fh; | ||
1617 | struct fcoe_crc_eof crc_eof; | 1572 | struct fcoe_crc_eof crc_eof; |
1618 | struct fc_frame *fp; | 1573 | struct fc_frame *fp; |
1619 | struct fcoe_port *port; | 1574 | struct fcoe_port *port; |
@@ -1644,7 +1599,6 @@ static void fcoe_recv_frame(struct sk_buff *skb) | |||
1644 | * was done in fcoe_rcv already. | 1599 | * was done in fcoe_rcv already. |
1645 | */ | 1600 | */ |
1646 | hp = (struct fcoe_hdr *) skb_network_header(skb); | 1601 | hp = (struct fcoe_hdr *) skb_network_header(skb); |
1647 | fh = (struct fc_frame_header *) skb_transport_header(skb); | ||
1648 | 1602 | ||
1649 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); | 1603 | stats = per_cpu_ptr(lport->dev_stats, get_cpu()); |
1650 | if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { | 1604 | if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { |
@@ -1677,35 +1631,11 @@ static void fcoe_recv_frame(struct sk_buff *skb) | |||
1677 | if (pskb_trim(skb, fr_len)) | 1631 | if (pskb_trim(skb, fr_len)) |
1678 | goto drop; | 1632 | goto drop; |
1679 | 1633 | ||
1680 | /* | 1634 | if (!fcoe_filter_frames(lport, fp)) { |
1681 | * We only check CRC if no offload is available and if it is | 1635 | put_cpu(); |
1682 | * it's solicited data, in which case, the FCP layer would | 1636 | fc_exch_recv(lport, fp); |
1683 | * check it during the copy. | 1637 | return; |
1684 | */ | ||
1685 | if (lport->crc_offload && | ||
1686 | skb->ip_summed == CHECKSUM_UNNECESSARY) | ||
1687 | fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; | ||
1688 | else | ||
1689 | fr_flags(fp) |= FCPHF_CRC_UNCHECKED; | ||
1690 | |||
1691 | fh = fc_frame_header_get(fp); | ||
1692 | if ((fh->fh_r_ctl != FC_RCTL_DD_SOL_DATA || | ||
1693 | fh->fh_type != FC_TYPE_FCP) && | ||
1694 | (fr_flags(fp) & FCPHF_CRC_UNCHECKED)) { | ||
1695 | if (le32_to_cpu(fr_crc(fp)) != | ||
1696 | ~crc32(~0, skb->data, fr_len)) { | ||
1697 | if (stats->InvalidCRCCount < 5) | ||
1698 | printk(KERN_WARNING "fcoe: dropping " | ||
1699 | "frame with CRC error\n"); | ||
1700 | stats->InvalidCRCCount++; | ||
1701 | goto drop; | ||
1702 | } | ||
1703 | fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; | ||
1704 | } | 1638 | } |
1705 | put_cpu(); | ||
1706 | fc_exch_recv(lport, fp); | ||
1707 | return; | ||
1708 | |||
1709 | drop: | 1639 | drop: |
1710 | stats->ErrorFrames++; | 1640 | stats->ErrorFrames++; |
1711 | put_cpu(); | 1641 | put_cpu(); |
@@ -1744,64 +1674,6 @@ int fcoe_percpu_receive_thread(void *arg) | |||
1744 | } | 1674 | } |
1745 | 1675 | ||
1746 | /** | 1676 | /** |
1747 | * fcoe_check_wait_queue() - Attempt to clear the transmit backlog | ||
1748 | * @lport: The local port whose backlog is to be cleared | ||
1749 | * | ||
1750 | * This empties the wait_queue, dequeues the head of the wait_queue queue | ||
1751 | * and calls fcoe_start_io() for each packet. If all skb have been | ||
1752 | * transmitted it returns the qlen. If an error occurs it restores | ||
1753 | * wait_queue (to try again later) and returns -1. | ||
1754 | * | ||
1755 | * The wait_queue is used when the skb transmit fails. The failed skb | ||
1756 | * will go in the wait_queue which will be emptied by the timer function or | ||
1757 | * by the next skb transmit. | ||
1758 | */ | ||
1759 | static void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb) | ||
1760 | { | ||
1761 | struct fcoe_port *port = lport_priv(lport); | ||
1762 | int rc; | ||
1763 | |||
1764 | spin_lock_bh(&port->fcoe_pending_queue.lock); | ||
1765 | |||
1766 | if (skb) | ||
1767 | __skb_queue_tail(&port->fcoe_pending_queue, skb); | ||
1768 | |||
1769 | if (port->fcoe_pending_queue_active) | ||
1770 | goto out; | ||
1771 | port->fcoe_pending_queue_active = 1; | ||
1772 | |||
1773 | while (port->fcoe_pending_queue.qlen) { | ||
1774 | /* keep qlen > 0 until fcoe_start_io succeeds */ | ||
1775 | port->fcoe_pending_queue.qlen++; | ||
1776 | skb = __skb_dequeue(&port->fcoe_pending_queue); | ||
1777 | |||
1778 | spin_unlock_bh(&port->fcoe_pending_queue.lock); | ||
1779 | rc = fcoe_start_io(skb); | ||
1780 | spin_lock_bh(&port->fcoe_pending_queue.lock); | ||
1781 | |||
1782 | if (rc) { | ||
1783 | __skb_queue_head(&port->fcoe_pending_queue, skb); | ||
1784 | /* undo temporary increment above */ | ||
1785 | port->fcoe_pending_queue.qlen--; | ||
1786 | break; | ||
1787 | } | ||
1788 | /* undo temporary increment above */ | ||
1789 | port->fcoe_pending_queue.qlen--; | ||
1790 | } | ||
1791 | |||
1792 | if (port->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) | ||
1793 | lport->qfull = 0; | ||
1794 | if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer)) | ||
1795 | mod_timer(&port->timer, jiffies + 2); | ||
1796 | port->fcoe_pending_queue_active = 0; | ||
1797 | out: | ||
1798 | if (port->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) | ||
1799 | lport->qfull = 1; | ||
1800 | spin_unlock_bh(&port->fcoe_pending_queue.lock); | ||
1801 | return; | ||
1802 | } | ||
1803 | |||
1804 | /** | ||
1805 | * fcoe_dev_setup() - Setup the link change notification interface | 1677 | * fcoe_dev_setup() - Setup the link change notification interface |
1806 | */ | 1678 | */ |
1807 | static void fcoe_dev_setup(void) | 1679 | static void fcoe_dev_setup(void) |
@@ -1872,7 +1744,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
1872 | list_del(&fcoe->list); | 1744 | list_del(&fcoe->list); |
1873 | port = lport_priv(fcoe->ctlr.lp); | 1745 | port = lport_priv(fcoe->ctlr.lp); |
1874 | fcoe_interface_cleanup(fcoe); | 1746 | fcoe_interface_cleanup(fcoe); |
1875 | schedule_work(&port->destroy_work); | 1747 | queue_work(fcoe_wq, &port->destroy_work); |
1876 | goto out; | 1748 | goto out; |
1877 | break; | 1749 | break; |
1878 | case NETDEV_FEAT_CHANGE: | 1750 | case NETDEV_FEAT_CHANGE: |
@@ -1898,39 +1770,16 @@ out: | |||
1898 | } | 1770 | } |
1899 | 1771 | ||
1900 | /** | 1772 | /** |
1901 | * fcoe_if_to_netdev() - Parse a name buffer to get a net device | ||
1902 | * @buffer: The name of the net device | ||
1903 | * | ||
1904 | * Returns: NULL or a ptr to net_device | ||
1905 | */ | ||
1906 | static struct net_device *fcoe_if_to_netdev(const char *buffer) | ||
1907 | { | ||
1908 | char *cp; | ||
1909 | char ifname[IFNAMSIZ + 2]; | ||
1910 | |||
1911 | if (buffer) { | ||
1912 | strlcpy(ifname, buffer, IFNAMSIZ); | ||
1913 | cp = ifname + strlen(ifname); | ||
1914 | while (--cp >= ifname && *cp == '\n') | ||
1915 | *cp = '\0'; | ||
1916 | return dev_get_by_name(&init_net, ifname); | ||
1917 | } | ||
1918 | return NULL; | ||
1919 | } | ||
1920 | |||
1921 | /** | ||
1922 | * fcoe_disable() - Disables a FCoE interface | 1773 | * fcoe_disable() - Disables a FCoE interface |
1923 | * @buffer: The name of the Ethernet interface to be disabled | 1774 | * @netdev : The net_device object the Ethernet interface to create on |
1924 | * @kp: The associated kernel parameter | ||
1925 | * | 1775 | * |
1926 | * Called from sysfs. | 1776 | * Called from fcoe transport. |
1927 | * | 1777 | * |
1928 | * Returns: 0 for success | 1778 | * Returns: 0 for success |
1929 | */ | 1779 | */ |
1930 | static int fcoe_disable(const char *buffer, struct kernel_param *kp) | 1780 | static int fcoe_disable(struct net_device *netdev) |
1931 | { | 1781 | { |
1932 | struct fcoe_interface *fcoe; | 1782 | struct fcoe_interface *fcoe; |
1933 | struct net_device *netdev; | ||
1934 | int rc = 0; | 1783 | int rc = 0; |
1935 | 1784 | ||
1936 | mutex_lock(&fcoe_config_mutex); | 1785 | mutex_lock(&fcoe_config_mutex); |
@@ -1946,16 +1795,9 @@ static int fcoe_disable(const char *buffer, struct kernel_param *kp) | |||
1946 | } | 1795 | } |
1947 | #endif | 1796 | #endif |
1948 | 1797 | ||
1949 | netdev = fcoe_if_to_netdev(buffer); | ||
1950 | if (!netdev) { | ||
1951 | rc = -ENODEV; | ||
1952 | goto out_nodev; | ||
1953 | } | ||
1954 | |||
1955 | if (!rtnl_trylock()) { | 1798 | if (!rtnl_trylock()) { |
1956 | dev_put(netdev); | ||
1957 | mutex_unlock(&fcoe_config_mutex); | 1799 | mutex_unlock(&fcoe_config_mutex); |
1958 | return restart_syscall(); | 1800 | return -ERESTARTSYS; |
1959 | } | 1801 | } |
1960 | 1802 | ||
1961 | fcoe = fcoe_hostlist_lookup_port(netdev); | 1803 | fcoe = fcoe_hostlist_lookup_port(netdev); |
@@ -1967,7 +1809,6 @@ static int fcoe_disable(const char *buffer, struct kernel_param *kp) | |||
1967 | } else | 1809 | } else |
1968 | rc = -ENODEV; | 1810 | rc = -ENODEV; |
1969 | 1811 | ||
1970 | dev_put(netdev); | ||
1971 | out_nodev: | 1812 | out_nodev: |
1972 | mutex_unlock(&fcoe_config_mutex); | 1813 | mutex_unlock(&fcoe_config_mutex); |
1973 | return rc; | 1814 | return rc; |
@@ -1975,17 +1816,15 @@ out_nodev: | |||
1975 | 1816 | ||
1976 | /** | 1817 | /** |
1977 | * fcoe_enable() - Enables a FCoE interface | 1818 | * fcoe_enable() - Enables a FCoE interface |
1978 | * @buffer: The name of the Ethernet interface to be enabled | 1819 | * @netdev : The net_device object the Ethernet interface to create on |
1979 | * @kp: The associated kernel parameter | ||
1980 | * | 1820 | * |
1981 | * Called from sysfs. | 1821 | * Called from fcoe transport. |
1982 | * | 1822 | * |
1983 | * Returns: 0 for success | 1823 | * Returns: 0 for success |
1984 | */ | 1824 | */ |
1985 | static int fcoe_enable(const char *buffer, struct kernel_param *kp) | 1825 | static int fcoe_enable(struct net_device *netdev) |
1986 | { | 1826 | { |
1987 | struct fcoe_interface *fcoe; | 1827 | struct fcoe_interface *fcoe; |
1988 | struct net_device *netdev; | ||
1989 | int rc = 0; | 1828 | int rc = 0; |
1990 | 1829 | ||
1991 | mutex_lock(&fcoe_config_mutex); | 1830 | mutex_lock(&fcoe_config_mutex); |
@@ -2000,17 +1839,9 @@ static int fcoe_enable(const char *buffer, struct kernel_param *kp) | |||
2000 | goto out_nodev; | 1839 | goto out_nodev; |
2001 | } | 1840 | } |
2002 | #endif | 1841 | #endif |
2003 | |||
2004 | netdev = fcoe_if_to_netdev(buffer); | ||
2005 | if (!netdev) { | ||
2006 | rc = -ENODEV; | ||
2007 | goto out_nodev; | ||
2008 | } | ||
2009 | |||
2010 | if (!rtnl_trylock()) { | 1842 | if (!rtnl_trylock()) { |
2011 | dev_put(netdev); | ||
2012 | mutex_unlock(&fcoe_config_mutex); | 1843 | mutex_unlock(&fcoe_config_mutex); |
2013 | return restart_syscall(); | 1844 | return -ERESTARTSYS; |
2014 | } | 1845 | } |
2015 | 1846 | ||
2016 | fcoe = fcoe_hostlist_lookup_port(netdev); | 1847 | fcoe = fcoe_hostlist_lookup_port(netdev); |
@@ -2021,7 +1852,6 @@ static int fcoe_enable(const char *buffer, struct kernel_param *kp) | |||
2021 | else if (!fcoe_link_ok(fcoe->ctlr.lp)) | 1852 | else if (!fcoe_link_ok(fcoe->ctlr.lp)) |
2022 | fcoe_ctlr_link_up(&fcoe->ctlr); | 1853 | fcoe_ctlr_link_up(&fcoe->ctlr); |
2023 | 1854 | ||
2024 | dev_put(netdev); | ||
2025 | out_nodev: | 1855 | out_nodev: |
2026 | mutex_unlock(&fcoe_config_mutex); | 1856 | mutex_unlock(&fcoe_config_mutex); |
2027 | return rc; | 1857 | return rc; |
@@ -2029,17 +1859,15 @@ out_nodev: | |||
2029 | 1859 | ||
2030 | /** | 1860 | /** |
2031 | * fcoe_destroy() - Destroy a FCoE interface | 1861 | * fcoe_destroy() - Destroy a FCoE interface |
2032 | * @buffer: The name of the Ethernet interface to be destroyed | 1862 | * @netdev : The net_device object the Ethernet interface to create on |
2033 | * @kp: The associated kernel parameter | ||
2034 | * | 1863 | * |
2035 | * Called from sysfs. | 1864 | * Called from fcoe transport |
2036 | * | 1865 | * |
2037 | * Returns: 0 for success | 1866 | * Returns: 0 for success |
2038 | */ | 1867 | */ |
2039 | static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | 1868 | static int fcoe_destroy(struct net_device *netdev) |
2040 | { | 1869 | { |
2041 | struct fcoe_interface *fcoe; | 1870 | struct fcoe_interface *fcoe; |
2042 | struct net_device *netdev; | ||
2043 | int rc = 0; | 1871 | int rc = 0; |
2044 | 1872 | ||
2045 | mutex_lock(&fcoe_config_mutex); | 1873 | mutex_lock(&fcoe_config_mutex); |
@@ -2054,32 +1882,21 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | |||
2054 | goto out_nodev; | 1882 | goto out_nodev; |
2055 | } | 1883 | } |
2056 | #endif | 1884 | #endif |
2057 | |||
2058 | netdev = fcoe_if_to_netdev(buffer); | ||
2059 | if (!netdev) { | ||
2060 | rc = -ENODEV; | ||
2061 | goto out_nodev; | ||
2062 | } | ||
2063 | |||
2064 | if (!rtnl_trylock()) { | 1885 | if (!rtnl_trylock()) { |
2065 | dev_put(netdev); | ||
2066 | mutex_unlock(&fcoe_config_mutex); | 1886 | mutex_unlock(&fcoe_config_mutex); |
2067 | return restart_syscall(); | 1887 | return -ERESTARTSYS; |
2068 | } | 1888 | } |
2069 | 1889 | ||
2070 | fcoe = fcoe_hostlist_lookup_port(netdev); | 1890 | fcoe = fcoe_hostlist_lookup_port(netdev); |
2071 | if (!fcoe) { | 1891 | if (!fcoe) { |
2072 | rtnl_unlock(); | 1892 | rtnl_unlock(); |
2073 | rc = -ENODEV; | 1893 | rc = -ENODEV; |
2074 | goto out_putdev; | 1894 | goto out_nodev; |
2075 | } | 1895 | } |
2076 | fcoe_interface_cleanup(fcoe); | 1896 | fcoe_interface_cleanup(fcoe); |
2077 | list_del(&fcoe->list); | 1897 | list_del(&fcoe->list); |
2078 | /* RTNL mutex is dropped by fcoe_if_destroy */ | 1898 | /* RTNL mutex is dropped by fcoe_if_destroy */ |
2079 | fcoe_if_destroy(fcoe->ctlr.lp); | 1899 | fcoe_if_destroy(fcoe->ctlr.lp); |
2080 | |||
2081 | out_putdev: | ||
2082 | dev_put(netdev); | ||
2083 | out_nodev: | 1900 | out_nodev: |
2084 | mutex_unlock(&fcoe_config_mutex); | 1901 | mutex_unlock(&fcoe_config_mutex); |
2085 | return rc; | 1902 | return rc; |
@@ -2102,27 +1919,39 @@ static void fcoe_destroy_work(struct work_struct *work) | |||
2102 | } | 1919 | } |
2103 | 1920 | ||
2104 | /** | 1921 | /** |
1922 | * fcoe_match() - Check if the FCoE is supported on the given netdevice | ||
1923 | * @netdev : The net_device object the Ethernet interface to create on | ||
1924 | * | ||
1925 | * Called from fcoe transport. | ||
1926 | * | ||
1927 | * Returns: always returns true as this is the default FCoE transport, | ||
1928 | * i.e., support all netdevs. | ||
1929 | */ | ||
1930 | static bool fcoe_match(struct net_device *netdev) | ||
1931 | { | ||
1932 | return true; | ||
1933 | } | ||
1934 | |||
1935 | /** | ||
2105 | * fcoe_create() - Create a fcoe interface | 1936 | * fcoe_create() - Create a fcoe interface |
2106 | * @buffer: The name of the Ethernet interface to create on | 1937 | * @netdev : The net_device object the Ethernet interface to create on |
2107 | * @kp: The associated kernel param | 1938 | * @fip_mode: The FIP mode for this creation |
2108 | * | 1939 | * |
2109 | * Called from sysfs. | 1940 | * Called from fcoe transport |
2110 | * | 1941 | * |
2111 | * Returns: 0 for success | 1942 | * Returns: 0 for success |
2112 | */ | 1943 | */ |
2113 | static int fcoe_create(const char *buffer, struct kernel_param *kp) | 1944 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) |
2114 | { | 1945 | { |
2115 | enum fip_state fip_mode = (enum fip_state)(long)kp->arg; | ||
2116 | int rc; | 1946 | int rc; |
2117 | struct fcoe_interface *fcoe; | 1947 | struct fcoe_interface *fcoe; |
2118 | struct fc_lport *lport; | 1948 | struct fc_lport *lport; |
2119 | struct net_device *netdev; | ||
2120 | 1949 | ||
2121 | mutex_lock(&fcoe_config_mutex); | 1950 | mutex_lock(&fcoe_config_mutex); |
2122 | 1951 | ||
2123 | if (!rtnl_trylock()) { | 1952 | if (!rtnl_trylock()) { |
2124 | mutex_unlock(&fcoe_config_mutex); | 1953 | mutex_unlock(&fcoe_config_mutex); |
2125 | return restart_syscall(); | 1954 | return -ERESTARTSYS; |
2126 | } | 1955 | } |
2127 | 1956 | ||
2128 | #ifdef CONFIG_FCOE_MODULE | 1957 | #ifdef CONFIG_FCOE_MODULE |
@@ -2133,31 +1962,20 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
2133 | */ | 1962 | */ |
2134 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { | 1963 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { |
2135 | rc = -ENODEV; | 1964 | rc = -ENODEV; |
2136 | goto out_nomod; | ||
2137 | } | ||
2138 | #endif | ||
2139 | |||
2140 | if (!try_module_get(THIS_MODULE)) { | ||
2141 | rc = -EINVAL; | ||
2142 | goto out_nomod; | ||
2143 | } | ||
2144 | |||
2145 | netdev = fcoe_if_to_netdev(buffer); | ||
2146 | if (!netdev) { | ||
2147 | rc = -ENODEV; | ||
2148 | goto out_nodev; | 1965 | goto out_nodev; |
2149 | } | 1966 | } |
1967 | #endif | ||
2150 | 1968 | ||
2151 | /* look for existing lport */ | 1969 | /* look for existing lport */ |
2152 | if (fcoe_hostlist_lookup(netdev)) { | 1970 | if (fcoe_hostlist_lookup(netdev)) { |
2153 | rc = -EEXIST; | 1971 | rc = -EEXIST; |
2154 | goto out_putdev; | 1972 | goto out_nodev; |
2155 | } | 1973 | } |
2156 | 1974 | ||
2157 | fcoe = fcoe_interface_create(netdev, fip_mode); | 1975 | fcoe = fcoe_interface_create(netdev, fip_mode); |
2158 | if (!fcoe) { | 1976 | if (IS_ERR(fcoe)) { |
2159 | rc = -ENOMEM; | 1977 | rc = PTR_ERR(fcoe); |
2160 | goto out_putdev; | 1978 | goto out_nodev; |
2161 | } | 1979 | } |
2162 | 1980 | ||
2163 | lport = fcoe_if_create(fcoe, &netdev->dev, 0); | 1981 | lport = fcoe_if_create(fcoe, &netdev->dev, 0); |
@@ -2186,18 +2004,13 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
2186 | * should be holding a reference taken in fcoe_if_create(). | 2004 | * should be holding a reference taken in fcoe_if_create(). |
2187 | */ | 2005 | */ |
2188 | fcoe_interface_put(fcoe); | 2006 | fcoe_interface_put(fcoe); |
2189 | dev_put(netdev); | ||
2190 | rtnl_unlock(); | 2007 | rtnl_unlock(); |
2191 | mutex_unlock(&fcoe_config_mutex); | 2008 | mutex_unlock(&fcoe_config_mutex); |
2192 | 2009 | ||
2193 | return 0; | 2010 | return 0; |
2194 | out_free: | 2011 | out_free: |
2195 | fcoe_interface_put(fcoe); | 2012 | fcoe_interface_put(fcoe); |
2196 | out_putdev: | ||
2197 | dev_put(netdev); | ||
2198 | out_nodev: | 2013 | out_nodev: |
2199 | module_put(THIS_MODULE); | ||
2200 | out_nomod: | ||
2201 | rtnl_unlock(); | 2014 | rtnl_unlock(); |
2202 | mutex_unlock(&fcoe_config_mutex); | 2015 | mutex_unlock(&fcoe_config_mutex); |
2203 | return rc; | 2016 | return rc; |
@@ -2212,8 +2025,7 @@ out_nomod: | |||
2212 | */ | 2025 | */ |
2213 | int fcoe_link_speed_update(struct fc_lport *lport) | 2026 | int fcoe_link_speed_update(struct fc_lport *lport) |
2214 | { | 2027 | { |
2215 | struct fcoe_port *port = lport_priv(lport); | 2028 | struct net_device *netdev = fcoe_netdev(lport); |
2216 | struct net_device *netdev = port->fcoe->netdev; | ||
2217 | struct ethtool_cmd ecmd = { ETHTOOL_GSET }; | 2029 | struct ethtool_cmd ecmd = { ETHTOOL_GSET }; |
2218 | 2030 | ||
2219 | if (!dev_ethtool_get_settings(netdev, &ecmd)) { | 2031 | if (!dev_ethtool_get_settings(netdev, &ecmd)) { |
@@ -2244,8 +2056,7 @@ int fcoe_link_speed_update(struct fc_lport *lport) | |||
2244 | */ | 2056 | */ |
2245 | int fcoe_link_ok(struct fc_lport *lport) | 2057 | int fcoe_link_ok(struct fc_lport *lport) |
2246 | { | 2058 | { |
2247 | struct fcoe_port *port = lport_priv(lport); | 2059 | struct net_device *netdev = fcoe_netdev(lport); |
2248 | struct net_device *netdev = port->fcoe->netdev; | ||
2249 | 2060 | ||
2250 | if (netif_oper_up(netdev)) | 2061 | if (netif_oper_up(netdev)) |
2251 | return 0; | 2062 | return 0; |
@@ -2309,24 +2120,6 @@ void fcoe_percpu_clean(struct fc_lport *lport) | |||
2309 | } | 2120 | } |
2310 | 2121 | ||
2311 | /** | 2122 | /** |
2312 | * fcoe_clean_pending_queue() - Dequeue a skb and free it | ||
2313 | * @lport: The local port to dequeue a skb on | ||
2314 | */ | ||
2315 | void fcoe_clean_pending_queue(struct fc_lport *lport) | ||
2316 | { | ||
2317 | struct fcoe_port *port = lport_priv(lport); | ||
2318 | struct sk_buff *skb; | ||
2319 | |||
2320 | spin_lock_bh(&port->fcoe_pending_queue.lock); | ||
2321 | while ((skb = __skb_dequeue(&port->fcoe_pending_queue)) != NULL) { | ||
2322 | spin_unlock_bh(&port->fcoe_pending_queue.lock); | ||
2323 | kfree_skb(skb); | ||
2324 | spin_lock_bh(&port->fcoe_pending_queue.lock); | ||
2325 | } | ||
2326 | spin_unlock_bh(&port->fcoe_pending_queue.lock); | ||
2327 | } | ||
2328 | |||
2329 | /** | ||
2330 | * fcoe_reset() - Reset a local port | 2123 | * fcoe_reset() - Reset a local port |
2331 | * @shost: The SCSI host associated with the local port to be reset | 2124 | * @shost: The SCSI host associated with the local port to be reset |
2332 | * | 2125 | * |
@@ -2335,7 +2128,13 @@ void fcoe_clean_pending_queue(struct fc_lport *lport) | |||
2335 | int fcoe_reset(struct Scsi_Host *shost) | 2128 | int fcoe_reset(struct Scsi_Host *shost) |
2336 | { | 2129 | { |
2337 | struct fc_lport *lport = shost_priv(shost); | 2130 | struct fc_lport *lport = shost_priv(shost); |
2338 | fc_lport_reset(lport); | 2131 | struct fcoe_port *port = lport_priv(lport); |
2132 | struct fcoe_interface *fcoe = port->priv; | ||
2133 | |||
2134 | fcoe_ctlr_link_down(&fcoe->ctlr); | ||
2135 | fcoe_clean_pending_queue(fcoe->ctlr.lp); | ||
2136 | if (!fcoe_link_ok(fcoe->ctlr.lp)) | ||
2137 | fcoe_ctlr_link_up(&fcoe->ctlr); | ||
2339 | return 0; | 2138 | return 0; |
2340 | } | 2139 | } |
2341 | 2140 | ||
@@ -2393,12 +2192,24 @@ static int fcoe_hostlist_add(const struct fc_lport *lport) | |||
2393 | fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); | 2192 | fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); |
2394 | if (!fcoe) { | 2193 | if (!fcoe) { |
2395 | port = lport_priv(lport); | 2194 | port = lport_priv(lport); |
2396 | fcoe = port->fcoe; | 2195 | fcoe = port->priv; |
2397 | list_add_tail(&fcoe->list, &fcoe_hostlist); | 2196 | list_add_tail(&fcoe->list, &fcoe_hostlist); |
2398 | } | 2197 | } |
2399 | return 0; | 2198 | return 0; |
2400 | } | 2199 | } |
2401 | 2200 | ||
2201 | |||
2202 | static struct fcoe_transport fcoe_sw_transport = { | ||
2203 | .name = {FCOE_TRANSPORT_DEFAULT}, | ||
2204 | .attached = false, | ||
2205 | .list = LIST_HEAD_INIT(fcoe_sw_transport.list), | ||
2206 | .match = fcoe_match, | ||
2207 | .create = fcoe_create, | ||
2208 | .destroy = fcoe_destroy, | ||
2209 | .enable = fcoe_enable, | ||
2210 | .disable = fcoe_disable, | ||
2211 | }; | ||
2212 | |||
2402 | /** | 2213 | /** |
2403 | * fcoe_init() - Initialize fcoe.ko | 2214 | * fcoe_init() - Initialize fcoe.ko |
2404 | * | 2215 | * |
@@ -2410,6 +2221,18 @@ static int __init fcoe_init(void) | |||
2410 | unsigned int cpu; | 2221 | unsigned int cpu; |
2411 | int rc = 0; | 2222 | int rc = 0; |
2412 | 2223 | ||
2224 | fcoe_wq = alloc_workqueue("fcoe", 0, 0); | ||
2225 | if (!fcoe_wq) | ||
2226 | return -ENOMEM; | ||
2227 | |||
2228 | /* register as a fcoe transport */ | ||
2229 | rc = fcoe_transport_attach(&fcoe_sw_transport); | ||
2230 | if (rc) { | ||
2231 | printk(KERN_ERR "failed to register an fcoe transport, check " | ||
2232 | "if libfcoe is loaded\n"); | ||
2233 | return rc; | ||
2234 | } | ||
2235 | |||
2413 | mutex_lock(&fcoe_config_mutex); | 2236 | mutex_lock(&fcoe_config_mutex); |
2414 | 2237 | ||
2415 | for_each_possible_cpu(cpu) { | 2238 | for_each_possible_cpu(cpu) { |
@@ -2440,6 +2263,7 @@ out_free: | |||
2440 | fcoe_percpu_thread_destroy(cpu); | 2263 | fcoe_percpu_thread_destroy(cpu); |
2441 | } | 2264 | } |
2442 | mutex_unlock(&fcoe_config_mutex); | 2265 | mutex_unlock(&fcoe_config_mutex); |
2266 | destroy_workqueue(fcoe_wq); | ||
2443 | return rc; | 2267 | return rc; |
2444 | } | 2268 | } |
2445 | module_init(fcoe_init); | 2269 | module_init(fcoe_init); |
@@ -2465,7 +2289,7 @@ static void __exit fcoe_exit(void) | |||
2465 | list_del(&fcoe->list); | 2289 | list_del(&fcoe->list); |
2466 | port = lport_priv(fcoe->ctlr.lp); | 2290 | port = lport_priv(fcoe->ctlr.lp); |
2467 | fcoe_interface_cleanup(fcoe); | 2291 | fcoe_interface_cleanup(fcoe); |
2468 | schedule_work(&port->destroy_work); | 2292 | queue_work(fcoe_wq, &port->destroy_work); |
2469 | } | 2293 | } |
2470 | rtnl_unlock(); | 2294 | rtnl_unlock(); |
2471 | 2295 | ||
@@ -2476,16 +2300,21 @@ static void __exit fcoe_exit(void) | |||
2476 | 2300 | ||
2477 | mutex_unlock(&fcoe_config_mutex); | 2301 | mutex_unlock(&fcoe_config_mutex); |
2478 | 2302 | ||
2479 | /* flush any asyncronous interface destroys, | 2303 | /* |
2480 | * this should happen after the netdev notifier is unregistered */ | 2304 | * destroy_work's may be chained but destroy_workqueue() |
2481 | flush_scheduled_work(); | 2305 | * can take care of them. Just kill the fcoe_wq. |
2482 | /* That will flush out all the N_Ports on the hostlist, but now we | 2306 | */ |
2483 | * may have NPIV VN_Ports scheduled for destruction */ | 2307 | destroy_workqueue(fcoe_wq); |
2484 | flush_scheduled_work(); | ||
2485 | 2308 | ||
2486 | /* detach from scsi transport | 2309 | /* |
2487 | * must happen after all destroys are done, therefor after the flush */ | 2310 | * Detaching from the scsi transport must happen after all |
2311 | * destroys are done on the fcoe_wq. destroy_workqueue will | ||
2312 | * enusre the fcoe_wq is flushed. | ||
2313 | */ | ||
2488 | fcoe_if_exit(); | 2314 | fcoe_if_exit(); |
2315 | |||
2316 | /* detach from fcoe transport */ | ||
2317 | fcoe_transport_detach(&fcoe_sw_transport); | ||
2489 | } | 2318 | } |
2490 | module_exit(fcoe_exit); | 2319 | module_exit(fcoe_exit); |
2491 | 2320 | ||
@@ -2557,7 +2386,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did, | |||
2557 | void *arg, u32 timeout) | 2386 | void *arg, u32 timeout) |
2558 | { | 2387 | { |
2559 | struct fcoe_port *port = lport_priv(lport); | 2388 | struct fcoe_port *port = lport_priv(lport); |
2560 | struct fcoe_interface *fcoe = port->fcoe; | 2389 | struct fcoe_interface *fcoe = port->priv; |
2561 | struct fcoe_ctlr *fip = &fcoe->ctlr; | 2390 | struct fcoe_ctlr *fip = &fcoe->ctlr; |
2562 | struct fc_frame_header *fh = fc_frame_header_get(fp); | 2391 | struct fc_frame_header *fh = fc_frame_header_get(fp); |
2563 | 2392 | ||
@@ -2590,7 +2419,7 @@ static int fcoe_vport_create(struct fc_vport *vport, bool disabled) | |||
2590 | struct Scsi_Host *shost = vport_to_shost(vport); | 2419 | struct Scsi_Host *shost = vport_to_shost(vport); |
2591 | struct fc_lport *n_port = shost_priv(shost); | 2420 | struct fc_lport *n_port = shost_priv(shost); |
2592 | struct fcoe_port *port = lport_priv(n_port); | 2421 | struct fcoe_port *port = lport_priv(n_port); |
2593 | struct fcoe_interface *fcoe = port->fcoe; | 2422 | struct fcoe_interface *fcoe = port->priv; |
2594 | struct net_device *netdev = fcoe->netdev; | 2423 | struct net_device *netdev = fcoe->netdev; |
2595 | struct fc_lport *vn_port; | 2424 | struct fc_lport *vn_port; |
2596 | 2425 | ||
@@ -2630,7 +2459,7 @@ static int fcoe_vport_destroy(struct fc_vport *vport) | |||
2630 | mutex_lock(&n_port->lp_mutex); | 2459 | mutex_lock(&n_port->lp_mutex); |
2631 | list_del(&vn_port->list); | 2460 | list_del(&vn_port->list); |
2632 | mutex_unlock(&n_port->lp_mutex); | 2461 | mutex_unlock(&n_port->lp_mutex); |
2633 | schedule_work(&port->destroy_work); | 2462 | queue_work(fcoe_wq, &port->destroy_work); |
2634 | return 0; | 2463 | return 0; |
2635 | } | 2464 | } |
2636 | 2465 | ||
@@ -2734,7 +2563,7 @@ static void fcoe_set_port_id(struct fc_lport *lport, | |||
2734 | u32 port_id, struct fc_frame *fp) | 2563 | u32 port_id, struct fc_frame *fp) |
2735 | { | 2564 | { |
2736 | struct fcoe_port *port = lport_priv(lport); | 2565 | struct fcoe_port *port = lport_priv(lport); |
2737 | struct fcoe_interface *fcoe = port->fcoe; | 2566 | struct fcoe_interface *fcoe = port->priv; |
2738 | 2567 | ||
2739 | if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) | 2568 | if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) |
2740 | fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); | 2569 | fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); |