linux/drivers/scsi/fcoe/fcoe.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
 *
 * Maintained at www.Open-FCoE.org
 */

#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/fs.h>
#include <linux/sysfs.h>
#include <linux/ctype.h>
#include <linux/workqueue.h>
#include <net/dcbnl.h>
#include <net/dcbevent.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>
#include <net/rtnetlink.h>

#include <scsi/fc/fc_encaps.h>
#include <scsi/fc/fc_fip.h>
#include <scsi/fc/fc_fcoe.h>

#include <scsi/libfc.h>
#include <scsi/fc_frame.h>
#include <scsi/libfcoe.h>

#include "fcoe.h"

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

/* Performance tuning parameters for fcoe */
static unsigned int fcoe_ddp_min =;
module_param_named(ddp_min, fcoe_ddp_min, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC();

unsigned int fcoe_debug_logging;
module_param_named(debug_logging, fcoe_debug_logging, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC();

static unsigned int fcoe_e_d_tov =;
module_param_named(e_d_tov, fcoe_e_d_tov, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC();

static unsigned int fcoe_r_a_tov =;
module_param_named(r_a_tov, fcoe_r_a_tov, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC();

static DEFINE_MUTEX(fcoe_config_mutex);

static struct workqueue_struct *fcoe_wq;

/* fcoe host list */
/* must only by accessed under the RTNL mutex */
static LIST_HEAD(fcoe_hostlist);
static DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);

/* Function Prototypes */
static int fcoe_reset(struct Scsi_Host *);
static int fcoe_xmit(struct fc_lport *, struct fc_frame *);
static int fcoe_rcv(struct sk_buff *, struct net_device *,
		    struct packet_type *, struct net_device *);
static void fcoe_percpu_clean(struct fc_lport *);
static int fcoe_link_ok(struct fc_lport *);

static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
static int fcoe_hostlist_add(const struct fc_lport *);
static void fcoe_hostlist_del(const struct fc_lport *);

static int fcoe_device_notification(struct notifier_block *, ulong, void *);
static void fcoe_dev_setup(void);
static void fcoe_dev_cleanup(void);
static struct fcoe_interface
*fcoe_hostlist_lookup_port(const struct net_device *);

static int fcoe_fip_recv(struct sk_buff *, struct net_device *,
			 struct packet_type *, struct net_device *);
static int fcoe_fip_vlan_recv(struct sk_buff *, struct net_device *,
			      struct packet_type *, struct net_device *);

static void fcoe_fip_send(struct fcoe_ctlr *, struct sk_buff *);
static void fcoe_update_src_mac(struct fc_lport *, u8 *);
static u8 *fcoe_get_src_mac(struct fc_lport *);
static void fcoe_destroy_work(struct work_struct *);

static int fcoe_ddp_setup(struct fc_lport *, u16, struct scatterlist *,
			  unsigned int);
static int fcoe_ddp_done(struct fc_lport *, u16);
static int fcoe_ddp_target(struct fc_lport *, u16, struct scatterlist *,
			   unsigned int);
static int fcoe_dcb_app_notification(struct notifier_block *notifier,
				     ulong event, void *ptr);

static bool fcoe_match(struct net_device *netdev);
static int fcoe_create(struct net_device *netdev, enum fip_mode fip_mode);
static int fcoe_destroy(struct net_device *netdev);
static int fcoe_enable(struct net_device *netdev);
static int fcoe_disable(struct net_device *netdev);

/* fcoe_syfs control interface handlers */
static int fcoe_ctlr_alloc(struct net_device *netdev);
static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev);
static void fcoe_ctlr_mode(struct fcoe_ctlr_device *ctlr_dev);

static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
				      u32 did, struct fc_frame *,
				      unsigned int op,
				      void (*resp)(struct fc_seq *,
						   struct fc_frame *,
						   void *),
				      void *, u32 timeout);
static void fcoe_recv_frame(struct sk_buff *skb);

/* notification function for packets from net device */
static struct notifier_block fcoe_notifier =;

/* notification function for DCB events */
static struct notifier_block dcb_notifier =;

static struct scsi_transport_template *fcoe_nport_scsi_transport;
static struct scsi_transport_template *fcoe_vport_scsi_transport;

static int fcoe_vport_destroy(struct fc_vport *);
static int fcoe_vport_create(struct fc_vport *, bool disabled);
static int fcoe_vport_disable(struct fc_vport *, bool disable);
static void fcoe_set_vport_symbolic_name(struct fc_vport *);
static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);
static void fcoe_vport_remove(struct fc_lport *);

static struct fcoe_sysfs_function_template fcoe_sysfs_templ =;

static struct libfc_function_template fcoe_libfc_fcn_templ =;

static struct fc_function_template fcoe_nport_fc_functions =;

static struct fc_function_template fcoe_vport_fc_functions =;

static const struct scsi_host_template fcoe_shost_template =;

/**
 * fcoe_interface_setup() - Setup a FCoE interface
 * @fcoe:   The new FCoE interface
 * @netdev: The net device that the fcoe interface is on
 *
 * Returns : 0 for success
 * Locking: must be called with the RTNL mutex held
 */
static int fcoe_interface_setup(struct fcoe_interface *fcoe,
				struct net_device *netdev)
{}

/**
 * fcoe_interface_create() - Create a FCoE interface on a net device
 * @netdev: The net device to create the FCoE interface on
 * @fip_mode: The mode to use for FIP
 *
 * Returns: pointer to a struct fcoe_interface or NULL on error
 */
static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
						    enum fip_mode fip_mode)
{}

/**
 * fcoe_interface_remove() - remove FCoE interface from netdev
 * @fcoe: The FCoE interface to be cleaned up
 *
 * Caller must be holding the RTNL mutex
 */
static void fcoe_interface_remove(struct fcoe_interface *fcoe)
{}


/**
 * fcoe_interface_cleanup() - Clean up a FCoE interface
 * @fcoe: The FCoE interface to be cleaned up
 */
static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
{}

/**
 * fcoe_fip_recv() - Handler for received FIP frames
 * @skb:      The receive skb
 * @netdev:   The associated net device
 * @ptype:    The packet_type structure which was used to register this handler
 * @orig_dev: The original net_device the skb was received on.
 *	      (in case dev is a bond)
 *
 * Returns: 0 for success
 */
static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev,
			 struct packet_type *ptype,
			 struct net_device *orig_dev)
{}

/**
 * fcoe_fip_vlan_recv() - Handler for received FIP VLAN discovery frames
 * @skb:      The receive skb
 * @netdev:   The associated net device
 * @ptype:    The packet_type structure which was used to register this handler
 * @orig_dev: The original net_device the skb was received on.
 *	      (in case dev is a bond)
 *
 * Returns: 0 for success
 */
static int fcoe_fip_vlan_recv(struct sk_buff *skb, struct net_device *netdev,
			      struct packet_type *ptype,
			      struct net_device *orig_dev)
{}

/**
 * fcoe_port_send() - Send an Ethernet-encapsulated FIP/FCoE frame
 * @port: The FCoE port
 * @skb: The FIP/FCoE packet to be sent
 */
static void fcoe_port_send(struct fcoe_port *port, struct sk_buff *skb)
{}

/**
 * fcoe_fip_send() - Send an Ethernet-encapsulated FIP frame
 * @fip: The FCoE controller
 * @skb: The FIP packet to be sent
 */
static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
{}

/**
 * fcoe_update_src_mac() - Update the Ethernet MAC filters
 * @lport: The local port to update the source MAC on
 * @addr:  Unicast MAC address to add
 *
 * Remove any previously-set unicast MAC filter.
 * Add secondary FCoE MAC address filter for our OUI.
 */
static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr)
{}

/**
 * fcoe_get_src_mac() - return the Ethernet source address for an lport
 * @lport: libfc lport
 */
static u8 *fcoe_get_src_mac(struct fc_lport *lport)
{}

/**
 * fcoe_lport_config() - Set up a local port
 * @lport: The local port to be setup
 *
 * Returns: 0 for success
 */
static int fcoe_lport_config(struct fc_lport *lport)
{}

/*
 * fcoe_netdev_features_change - Updates the lport's offload flags based
 * on the LLD netdev's FCoE feature flags
 */
static void fcoe_netdev_features_change(struct fc_lport *lport,
					struct net_device *netdev)
{}

/**
 * fcoe_netdev_config() - Set up net devive for SW FCoE
 * @lport:  The local port that is associated with the net device
 * @netdev: The associated net device
 *
 * Must be called after fcoe_lport_config() as it will use local port mutex
 *
 * Returns: 0 for success
 */
static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
{}

/**
 * fcoe_shost_config() - Set up the SCSI host associated with a local port
 * @lport: The local port
 * @dev:   The device associated with the SCSI host
 *
 * Must be called after fcoe_lport_config() and fcoe_netdev_config()
 *
 * Returns: 0 for success
 */
static int fcoe_shost_config(struct fc_lport *lport, struct device *dev)
{}


/**
 * fcoe_fdmi_info() - Get FDMI related info from net devive for SW FCoE
 * @lport:  The local port that is associated with the net device
 * @netdev: The associated net device
 *
 * Must be called after fcoe_shost_config() as it will use local port mutex
 *
 */
static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
{}

/**
 * fcoe_oem_match() - The match routine for the offloaded exchange manager
 * @fp: The I/O frame
 *
 * This routine will be associated with an exchange manager (EM). When
 * the libfc exchange handling code is looking for an EM to use it will
 * call this routine and pass it the frame that it wishes to send. This
 * routine will return True if the associated EM is to be used and False
 * if the echange code should continue looking for an EM.
 *
 * The offload EM that this routine is associated with will handle any
 * packets that are for SCSI read requests.
 *
 * This has been enhanced to work when FCoE stack is operating in target
 * mode.
 *
 * Returns: True for read types I/O, otherwise returns false.
 */
static bool fcoe_oem_match(struct fc_frame *fp)
{}

/**
 * fcoe_em_config() - Allocate and configure an exchange manager
 * @lport: The local port that the new EM will be associated with
 *
 * Returns: 0 on success
 */
static inline int fcoe_em_config(struct fc_lport *lport)
{}

/**
 * fcoe_if_destroy() - Tear down a SW FCoE instance
 * @lport: The local port to be destroyed
 *
 * Locking: Must be called with the RTNL mutex held.
 *
 */
static void fcoe_if_destroy(struct fc_lport *lport)
{}

/**
 * fcoe_ddp_setup() - Call a LLD's ddp_setup through the net device
 * @lport: The local port to setup DDP for
 * @xid:   The exchange ID for this DDP transfer
 * @sgl:   The scatterlist describing this transfer
 * @sgc:   The number of sg items
 *
 * Returns: 0 if the DDP context was not configured
 */
static int fcoe_ddp_setup(struct fc_lport *lport, u16 xid,
			  struct scatterlist *sgl, unsigned int sgc)
{}

/**
 * fcoe_ddp_target() - Call a LLD's ddp_target through the net device
 * @lport: The local port to setup DDP for
 * @xid:   The exchange ID for this DDP transfer
 * @sgl:   The scatterlist describing this transfer
 * @sgc:   The number of sg items
 *
 * Returns: 0 if the DDP context was not configured
 */
static int fcoe_ddp_target(struct fc_lport *lport, u16 xid,
			   struct scatterlist *sgl, unsigned int sgc)
{}


/**
 * fcoe_ddp_done() - Call a LLD's ddp_done through the net device
 * @lport: The local port to complete DDP on
 * @xid:   The exchange ID for this DDP transfer
 *
 * Returns: the length of data that have been completed by DDP
 */
static int fcoe_ddp_done(struct fc_lport *lport, u16 xid)
{}

/**
 * fcoe_if_create() - Create a FCoE instance on an interface
 * @fcoe:   The FCoE interface to create a local port on
 * @parent: The device pointer to be the parent in sysfs for the SCSI host
 * @npiv:   Indicates if the port is a vport or not
 *
 * Creates a fc_lport instance and a Scsi_Host instance and configure them.
 *
 * Returns: The allocated fc_lport or an error pointer
 */
static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
				       struct device *parent, int npiv)
{}

/**
 * fcoe_if_init() - Initialization routine for fcoe.ko
 *
 * Attaches the SW FCoE transport to the FC transport
 *
 * Returns: 0 on success
 */
static int __init fcoe_if_init(void)
{}

/**
 * fcoe_if_exit() - Tear down fcoe.ko
 *
 * Detaches the SW FCoE transport from the FC transport
 *
 * Returns: 0 on success
 */
static int __exit fcoe_if_exit(void)
{}

static void fcoe_thread_cleanup_local(unsigned int cpu)
{}

/**
 * fcoe_select_cpu() - Selects CPU to handle post-processing of incoming
 *			command.
 *
 * This routine selects next CPU based on cpumask to distribute
 * incoming requests in round robin.
 *
 * Returns: int CPU number
 */
static inline unsigned int fcoe_select_cpu(void)
{}

/**
 * fcoe_rcv() - Receive packets from a net device
 * @skb:    The received packet
 * @netdev: The net device that the packet was received on
 * @ptype:  The packet type context
 * @olddev: The last device net device
 *
 * This routine is called by NET_RX_SOFTIRQ. It receives a packet, builds a
 * FC frame and passes the frame to libfc.
 *
 * Returns: 0 for success
 */
static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
	     struct packet_type *ptype, struct net_device *olddev)
{}

/**
 * fcoe_alloc_paged_crc_eof() - Allocate a page to be used for the trailer CRC
 * @skb:  The packet to be transmitted
 * @tlen: The total length of the trailer
 *
 * Returns: 0 for success
 */
static int fcoe_alloc_paged_crc_eof(struct sk_buff *skb, int tlen)
{}

/**
 * fcoe_xmit() - Transmit a FCoE frame
 * @lport: The local port that the frame is to be transmitted for
 * @fp:	   The frame to be transmitted
 *
 * Return: 0 for success
 */
static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
{}

/**
 * fcoe_filter_frames() - filter out bad fcoe frames, i.e. bad CRC
 * @lport: The local port the frame was received on
 * @fp:	   The received frame
 *
 * Return: 0 on passing filtering checks
 */
static inline int fcoe_filter_frames(struct fc_lport *lport,
				     struct fc_frame *fp)
{}

/**
 * fcoe_recv_frame() - process a single received frame
 * @skb: frame to process
 */
static void fcoe_recv_frame(struct sk_buff *skb)
{}

/**
 * fcoe_receive_work() - The per-CPU worker
 * @work: The work struct
 *
 */
static void fcoe_receive_work(struct work_struct *work)
{}

/**
 * fcoe_dev_setup() - Setup the link change notification interface
 */
static void fcoe_dev_setup(void)
{}

/**
 * fcoe_dev_cleanup() - Cleanup the link change notification interface
 */
static void fcoe_dev_cleanup(void)
{}

static struct fcoe_interface *
fcoe_hostlist_lookup_realdev_port(struct net_device *netdev)
{}

static int fcoe_dcb_app_notification(struct notifier_block *notifier,
				     ulong event, void *ptr)
{}

/**
 * fcoe_device_notification() - Handler for net device events
 * @notifier: The context of the notification
 * @event:    The type of event
 * @ptr:      The net device that the event was on
 *
 * This function is called by the Ethernet driver in case of link change event.
 *
 * Returns: 0 for success
 */
static int fcoe_device_notification(struct notifier_block *notifier,
				    ulong event, void *ptr)
{}

/**
 * fcoe_disable() - Disables a FCoE interface
 * @netdev  : The net_device object the Ethernet interface to create on
 *
 * Called from fcoe transport.
 *
 * Returns: 0 for success
 *
 * Deprecated: use fcoe_ctlr_enabled()
 */
static int fcoe_disable(struct net_device *netdev)
{}

/**
 * fcoe_enable() - Enables a FCoE interface
 * @netdev  : The net_device object the Ethernet interface to create on
 *
 * Called from fcoe transport.
 *
 * Returns: 0 for success
 */
static int fcoe_enable(struct net_device *netdev)
{}

/**
 * fcoe_ctlr_enabled() - Enable or disable an FCoE Controller
 * @cdev: The FCoE Controller that is being enabled or disabled
 *
 * fcoe_sysfs will ensure that the state of 'enabled' has
 * changed, so no checking is necessary here. This routine simply
 * calls fcoe_enable or fcoe_disable, both of which are deprecated.
 * When those routines are removed the functionality can be merged
 * here.
 */
static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev)
{}

/**
 * fcoe_ctlr_mode() - Switch FIP mode
 * @ctlr_dev: The FCoE Controller that is being modified
 *
 * When the FIP mode has been changed we need to update
 * the multicast addresses to ensure we get the correct
 * frames.
 */
static void fcoe_ctlr_mode(struct fcoe_ctlr_device *ctlr_dev)
{}

/**
 * fcoe_destroy() - Destroy a FCoE interface
 * @netdev  : The net_device object the Ethernet interface to create on
 *
 * Called from fcoe transport
 *
 * Returns: 0 for success
 */
static int fcoe_destroy(struct net_device *netdev)
{}

/**
 * fcoe_destroy_work() - Destroy a FCoE port in a deferred work context
 * @work: Handle to the FCoE port to be destroyed
 */
static void fcoe_destroy_work(struct work_struct *work)
{}

/**
 * fcoe_match() - Check if the FCoE is supported on the given netdevice
 * @netdev  : The net_device object the Ethernet interface to create on
 *
 * Called from fcoe transport.
 *
 * Returns: always returns true as this is the default FCoE transport,
 * i.e., support all netdevs.
 */
static bool fcoe_match(struct net_device *netdev)
{}

/**
 * fcoe_dcb_create() - Initialize DCB attributes and hooks
 * @fcoe:   The new FCoE interface
 */
static void fcoe_dcb_create(struct fcoe_interface *fcoe)
{}

enum fcoe_create_link_state {};

/**
 * _fcoe_create() - (internal) Create a fcoe interface
 * @netdev  :   The net_device object the Ethernet interface to create on
 * @fip_mode:   The FIP mode for this creation
 * @link_state: The ctlr link state on creation
 *
 * Called from either the libfcoe 'create' module parameter
 * via fcoe_create or from fcoe_syfs's ctlr_create file.
 *
 * libfcoe's 'create' module parameter is deprecated so some
 * consolidation of code can be done when that interface is
 * removed.
 */
static int _fcoe_create(struct net_device *netdev, enum fip_mode fip_mode,
			enum fcoe_create_link_state link_state)
{}

/**
 * fcoe_create() - Create a fcoe interface
 * @netdev  : The net_device object the Ethernet interface to create on
 * @fip_mode: The FIP mode for this creation
 *
 * Called from fcoe transport
 *
 * Returns: 0 for success
 */
static int fcoe_create(struct net_device *netdev, enum fip_mode fip_mode)
{}

/**
 * fcoe_ctlr_alloc() - Allocate a fcoe interface from fcoe_sysfs
 * @netdev: The net_device to be used by the allocated FCoE Controller
 *
 * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr
 * in a link_down state. The allows the user an opportunity to configure
 * the FCoE Controller from sysfs before enabling the FCoE Controller.
 *
 * Creating in with this routine starts the FCoE Controller in Fabric
 * mode. The user can change to VN2VN or another mode before enabling.
 */
static int fcoe_ctlr_alloc(struct net_device *netdev)
{}

/**
 * fcoe_link_ok() - Check if the link is OK for a local port
 * @lport: The local port to check link on
 *
 * Returns: 0 if link is UP and OK, -1 if not
 *
 */
static int fcoe_link_ok(struct fc_lport *lport)
{}

/**
 * fcoe_percpu_clean() - Clear all pending skbs for an local port
 * @lport: The local port whose skbs are to be cleared
 *
 * Must be called with fcoe_create_mutex held to single-thread completion.
 *
 * This flushes the pending skbs by flush the work item for each CPU. The work
 * item on each possible CPU is flushed because we may have used the per-CPU
 * struct of an offline CPU.
 */
static void fcoe_percpu_clean(struct fc_lport *lport)
{}

/**
 * fcoe_reset() - Reset a local port
 * @shost: The SCSI host associated with the local port to be reset
 *
 * Returns: Always 0 (return value required by FC transport template)
 */
static int fcoe_reset(struct Scsi_Host *shost)
{}

/**
 * fcoe_hostlist_lookup_port() - Find the FCoE interface associated with a net device
 * @netdev: The net device used as a key
 *
 * Locking: Must be called with the RNL mutex held.
 *
 * Returns: NULL or the FCoE interface
 */
static struct fcoe_interface *
fcoe_hostlist_lookup_port(const struct net_device *netdev)
{}

/**
 * fcoe_hostlist_lookup() - Find the local port associated with a
 *			    given net device
 * @netdev: The netdevice used as a key
 *
 * Locking: Must be called with the RTNL mutex held
 *
 * Returns: NULL or the local port
 */
static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
{}

/**
 * fcoe_hostlist_add() - Add the FCoE interface identified by a local
 *			 port to the hostlist
 * @lport: The local port that identifies the FCoE interface to be added
 *
 * Locking: must be called with the RTNL mutex held
 *
 * Returns: 0 for success
 */
static int fcoe_hostlist_add(const struct fc_lport *lport)
{}

/**
 * fcoe_hostlist_del() - Remove the FCoE interface identified by a local
 *			 port to the hostlist
 * @lport: The local port that identifies the FCoE interface to be added
 *
 * Locking: must be called with the RTNL mutex held
 *
 */
static void fcoe_hostlist_del(const struct fc_lport *lport)
{}

static struct fcoe_transport fcoe_sw_transport =;

/**
 * fcoe_init() - Initialize fcoe.ko
 *
 * Returns: 0 on success, or a negative value on failure
 */
static int __init fcoe_init(void)
{}
module_init();

/**
 * fcoe_exit() - Clean up fcoe.ko
 *
 * Returns: 0 on success or a  negative value on failure
 */
static void __exit fcoe_exit(void)
{}
module_exit(fcoe_exit);

/**
 * fcoe_flogi_resp() - FCoE specific FLOGI and FDISC response handler
 * @seq: active sequence in the FLOGI or FDISC exchange
 * @fp: response frame, or error encoded in a pointer (timeout)
 * @arg: pointer to the fcoe_ctlr structure
 *
 * This handles MAC address management for FCoE, then passes control on to
 * the libfc FLOGI response handler.
 */
static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
{}

/**
 * fcoe_logo_resp() - FCoE specific LOGO response handler
 * @seq: active sequence in the LOGO exchange
 * @fp: response frame, or error encoded in a pointer (timeout)
 * @arg: pointer to the fcoe_ctlr structure
 *
 * This handles MAC address management for FCoE, then passes control on to
 * the libfc LOGO response handler.
 */
static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
{}

/*
 * fcoe_elsct_send - FCoE specific ELS handler
 *
 * This does special case handling of FIP encapsualted ELS exchanges for FCoE,
 * using FCoE specific response handlers and passing the FIP controller as
 * the argument (the lport is still available from the exchange).
 *
 * Most of the work here is just handed off to the libfc routine.
 */
static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did,
				      struct fc_frame *fp, unsigned int op,
				      void (*resp)(struct fc_seq *,
						   struct fc_frame *,
						   void *),
				      void *arg, u32 timeout)
{}

/**
 * fcoe_vport_create() - create an fc_host/scsi_host for a vport
 * @vport: fc_vport object to create a new fc_host for
 * @disabled: start the new fc_host in a disabled state by default?
 *
 * Returns: 0 for success
 */
static int fcoe_vport_create(struct fc_vport *vport, bool disabled)
{}

/**
 * fcoe_vport_destroy() - destroy the fc_host/scsi_host for a vport
 * @vport: fc_vport object that is being destroyed
 *
 * Returns: 0 for success
 */
static int fcoe_vport_destroy(struct fc_vport *vport)
{}

/**
 * fcoe_vport_remove() - remove attached vports
 * @lport: lport for which the vports should be removed
 */
static void fcoe_vport_remove(struct fc_lport *lport)
{}

/**
 * fcoe_vport_disable() - change vport state
 * @vport: vport to bring online/offline
 * @disable: should the vport be disabled?
 */
static int fcoe_vport_disable(struct fc_vport *vport, bool disable)
{}

/**
 * fcoe_set_vport_symbolic_name() - append vport string to symbolic name
 * @vport: fc_vport with a new symbolic name string
 *
 * After generating a new symbolic name string, a new RSPN_ID request is
 * sent to the name server.  There is no response handler, so if it fails
 * for some reason it will not be retried.
 */
static void fcoe_set_vport_symbolic_name(struct fc_vport *vport)
{}

static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
{}

/**
 * fcoe_set_port_id() - Callback from libfc when Port_ID is set.
 * @lport: the local port
 * @port_id: the port ID
 * @fp: the received frame, if any, that caused the port_id to be set.
 *
 * This routine handles the case where we received a FLOGI and are
 * entering point-to-point mode.  We need to call fcoe_ctlr_recv_flogi()
 * so it can set the non-mapped mode and gateway address.
 *
 * The FLOGI LS_ACC is handled by fcoe_flogi_resp().
 */
static void fcoe_set_port_id(struct fc_lport *lport,
			     u32 port_id, struct fc_frame *fp)
{}