/*
 * Copyright (c) 2008-2009 Cisco Systems, Inc.  All rights reserved.
 * Copyright (c) 2009 Intel Corporation.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Maintained at www.Open-FCoE.org
 */

#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/timer.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/errno.h>
#include <linux/bitops.h>
#include <net/rtnetlink.h>

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

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

MODULE_AUTHOR("Open-FCoE.org");
MODULE_DESCRIPTION("FIP discovery protocol support for FCoE HBAs");
MODULE_LICENSE("GPL v2");

#define	FCOE_CTLR_MIN_FKA	500		/* min keep alive (mS) */
#define	FCOE_CTLR_DEF_FKA	FIP_DEF_FKA	/* default keep alive (mS) */

static void fcoe_ctlr_timeout(unsigned long);
static void fcoe_ctlr_link_work(struct work_struct *);
static void fcoe_ctlr_recv_work(struct work_struct *);

static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS;

unsigned int libfcoe_debug_logging;
module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");

#define LIBFCOE_LOGGING     0x01 /* General logging, not categorized */
#define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */

#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD)				\
do {                                                            	\
	if (unlikely(libfcoe_debug_logging & LEVEL))			\
		do {							\
			CMD;						\
		} while (0);						\
} while (0)

#define LIBFCOE_DBG(fmt, args...)					\
	LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING,				\
			      printk(KERN_INFO "libfcoe: " fmt, ##args);)

#define LIBFCOE_FIP_DBG(fmt, args...)					\
	LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING,			\
			      printk(KERN_INFO "fip: " fmt, ##args);)

/*
 * Return non-zero if FCF fcoe_size has been validated.
 */
static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf)
{
	return (fcf->flags & FIP_FL_SOL) != 0;
}

/*
 * Return non-zero if the FCF is usable.
 */
static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf)
{
	u16 flags = FIP_FL_SOL | FIP_FL_AVAIL;

	return (fcf->flags & flags) == flags;
}

/**
 * fcoe_ctlr_init() - Initialize the FCoE Controller instance.
 * @fip:	FCoE controller.
 */
void fcoe_ctlr_init(struct fcoe_ctlr *fip)
{
	fip->state = FIP_ST_LINK_WAIT;
	INIT_LIST_HEAD(&fip->fcfs);
	spin_lock_init(&fip->lock);
	fip->flogi_oxid = FC_XID_UNKNOWN;
	setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip);
	INIT_WORK(&fip->link_work, fcoe_ctlr_link_work);
	INIT_WORK(&fip->recv_work, fcoe_ctlr_recv_work);
	skb_queue_head_init(&fip->fip_recv_list);
}
EXPORT_SYMBOL(fcoe_ctlr_init);

/**
 * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller.
 * @fip:	FCoE controller.
 *
 * Called with &fcoe_ctlr lock held.
 */
static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip)
{
	struct fcoe_fcf *fcf;
	struct fcoe_fcf *next;

	fip->sel_fcf = NULL;
	list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
		list_del(&fcf->list);
		kfree(fcf);
	}
	fip->fcf_count = 0;
	fip->sel_time = 0;
}

/**
 * fcoe_ctlr_destroy() - Disable and tear-down the FCoE controller.
 * @fip:	FCoE controller.
 *
 * This is called by FCoE drivers before freeing the &fcoe_ctlr.
 *
 * The receive handler will have been deleted before this to guarantee
 * that no more recv_work will be scheduled.
 *
 * The timer routine will simply return once we set FIP_ST_DISABLED.
 * This guarantees that no further timeouts or work will be scheduled.
 */
void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
{
	cancel_work_sync(&fip->recv_work);
	spin_lock_bh(&fip->fip_recv_list.lock);
	__skb_queue_purge(&fip->fip_recv_list);
	spin_unlock_bh(&fip->fip_recv_list.lock);

	spin_lock_bh(&fip->lock);
	fip->state = FIP_ST_DISABLED;
	fcoe_ctlr_reset_fcfs(fip);
	spin_unlock_bh(&fip->lock);
	del_timer_sync(&fip->timer);
	cancel_work_sync(&fip->link_work);
}
EXPORT_SYMBOL(fcoe_ctlr_destroy);

/**
 * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port.
 * @fip:	FCoE controller.
 *
 * Returns the maximum packet size including the FCoE header and trailer,
 * but not including any Ethernet or VLAN headers.
 */
static inline u32 fcoe_ctlr_fcoe_size(struct fcoe_ctlr *fip)
{
	/*
	 * Determine the max FCoE frame size allowed, including
	 * FCoE header and trailer.
	 * Note:  lp->mfs is currently the payload size, not the frame size.
	 */
	return fip->lp->mfs + sizeof(struct fc_frame_header) +
		sizeof(struct fcoe_hdr) + sizeof(struct fcoe_crc_eof);
}

/**
 * fcoe_ctlr_solicit() - Send a solicitation.
 * @fip:	FCoE controller.
 * @fcf:	Destination FCF.  If NULL, a multicast solicitation is sent.
 */
static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf)
{
	struct sk_buff *skb;
	struct fip_sol {
		struct ethhdr eth;
		struct fip_header fip;
		struct {
			struct fip_mac_desc mac;
			struct fip_wwn_desc wwnn;
			struct fip_size_desc size;
		} __attribute__((packed)) desc;
	}  __attribute__((packed)) *sol;
	u32 fcoe_size;

	skb = dev_alloc_skb(sizeof(*sol));
	if (!skb)
		return;

	sol = (struct fip_sol *)skb->data;

	memset(sol, 0, sizeof(*sol));
	memcpy(sol->eth.h_dest, fcf ? fcf->fcf_mac : fcoe_all_fcfs, ETH_ALEN);
	memcpy(sol->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
	sol->eth.h_proto = htons(ETH_P_FIP);

	sol->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
	sol->fip.fip_op = htons(FIP_OP_DISC);
	sol->fip.fip_subcode = FIP_SC_SOL;
	sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW);
	sol->fip.fip_flags = htons(FIP_FL_FPMA);
	if (fip->spma)
		sol->fip.fip_flags |= htons(FIP_FL_SPMA);

	sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
	sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW;
	memcpy(sol->desc.mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);

	sol->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME;
	sol->desc.wwnn.fd_desc.fip_dlen = sizeof(sol->desc.wwnn) / FIP_BPW;
	put_unaligned_be64(fip->lp->wwnn, &sol->desc.wwnn.fd_wwn);

	fcoe_size = fcoe_ctlr_fcoe_size(fip);
	sol->desc.size.fd_desc.fip_dtype = FIP_DT_FCOE_SIZE;
	sol->desc.size.fd_desc.fip_dlen = sizeof(sol->desc.size) / FIP_BPW;
	sol->desc.size.fd_size = htons(fcoe_size);

	skb_put(skb, sizeof(*sol));
	skb->protocol = htons(ETH_P_FIP);
	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);
	fip->send(fip, skb);

	if (!fcf)
		fip->sol_time = jiffies;
}

/**
 * fcoe_ctlr_link_up() - Start FCoE controller.
 * @fip:	FCoE controller.
 *
 * Called from the LLD when the network link is ready.
 */
void fcoe_ctlr_link_up(struct fcoe_ctlr *fip)
{
	spin_lock_bh(&fip->lock);
	if (fip->state == FIP_ST_NON_FIP || fip->state == FIP_ST_AUTO) {
		fip->last_link = 1;
		fip->link = 1;
		spin_unlock_bh(&fip->lock);
		fc_linkup(fip->lp);
	} else if (fip->state == FIP_ST_LINK_WAIT) {
		fip->state = FIP_ST_AUTO;
		fip->last_link = 1;
		fip->link = 1;
		spin_unlock_bh(&fip->lock);
		LIBFCOE_FIP_DBG("%s", "setting AUTO mode.\n");
		fc_linkup(fip->lp);
		fcoe_ctlr_solicit(fip, NULL);
	} else
		spin_unlock_bh(&fip->lock);
}
EXPORT_SYMBOL(fcoe_ctlr_link_up);

/**
 * fcoe_ctlr_reset() - Reset FIP.
 * @fip:	FCoE controller.
 * @new_state:	FIP state to be entered.
 *
 * Returns non-zero if the link was up and now isn't.
 */
static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state)
{
	struct fc_lport *lp = fip->lp;
	int link_dropped;

	spin_lock_bh(&fip->lock);
	fcoe_ctlr_reset_fcfs(fip);
	del_timer(&fip->timer);
	fip->state = new_state;
	fip->ctlr_ka_time = 0;
	fip->port_ka_time = 0;
	fip->sol_time = 0;
	fip->flogi_oxid = FC_XID_UNKNOWN;
	fip->map_dest = 0;
	fip->last_link = 0;
	link_dropped = fip->link;
	fip->link = 0;
	spin_unlock_bh(&fip->lock);

	if (link_dropped)
		fc_linkdown(lp);

	if (new_state == FIP_ST_ENABLED) {
		fcoe_ctlr_solicit(fip, NULL);
		fc_linkup(lp);
		link_dropped = 0;
	}
	return link_dropped;
}

/**
 * fcoe_ctlr_link_down() - Stop FCoE controller.
 * @fip:	FCoE controller.
 *
 * Returns non-zero if the link was up and now isn't.
 *
 * Called from the LLD when the network link is not ready.
 * There may be multiple calls while the link is down.
 */
int fcoe_ctlr_link_down(struct fcoe_ctlr *fip)
{
	return fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
}
EXPORT_SYMBOL(fcoe_ctlr_link_down);

/**
 * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF.
 * @fip:	FCoE controller.
 * @ports:	0 for controller keep-alive, 1 for port keep-alive.
 * @sa:		source MAC address.
 *
 * A controller keep-alive is sent every fka_period (typically 8 seconds).
 * The source MAC is the native MAC address.
 *
 * A port keep-alive is sent every 90 seconds while logged in.
 * The source MAC is the assigned mapped source address.
 * The destination is the FCF's F-port.
 */
static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
{
	struct sk_buff *skb;
	struct fip_kal {
		struct ethhdr eth;
		struct fip_header fip;
		struct fip_mac_desc mac;
	} __attribute__((packed)) *kal;
	struct fip_vn_desc *vn;
	u32 len;
	struct fc_lport *lp;
	struct fcoe_fcf *fcf;

	fcf = fip->sel_fcf;
	lp = fip->lp;
	if (!fcf || !fc_host_port_id(lp->host))
		return;

	len = fcoe_ctlr_fcoe_size(fip) + sizeof(struct ethhdr);
	BUG_ON(len < sizeof(*kal) + sizeof(*vn));
	skb = dev_alloc_skb(len);
	if (!skb)
		return;

	kal = (struct fip_kal *)skb->data;
	memset(kal, 0, len);
	memcpy(kal->eth.h_dest, fcf->fcf_mac, ETH_ALEN);
	memcpy(kal->eth.h_source, sa, ETH_ALEN);
	kal->eth.h_proto = htons(ETH_P_FIP);

	kal->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
	kal->fip.fip_op = htons(FIP_OP_CTRL);
	kal->fip.fip_subcode = FIP_SC_KEEP_ALIVE;
	kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
				    ports * sizeof(*vn)) / FIP_BPW);
	kal->fip.fip_flags = htons(FIP_FL_FPMA);
	if (fip->spma)
		kal->fip.fip_flags |= htons(FIP_FL_SPMA);

	kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
	kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
	memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);

	if (ports) {
		vn = (struct fip_vn_desc *)(kal + 1);
		vn->fd_desc.fip_dtype = FIP_DT_VN_ID;
		vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW;
		memcpy(vn->fd_mac, fip->data_src_addr, ETH_ALEN);
		hton24(vn->fd_fc_id, fc_host_port_id(lp->host));
		put_unaligned_be64(lp->wwpn, &vn->fd_wwpn);
	}

	skb_put(skb, len);
	skb->protocol = htons(ETH_P_FIP);
	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);
	fip->send(fip, skb);
}

/**
 * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it.
 * @fip:	FCoE controller.
 * @dtype:	FIP descriptor type for the frame.
 * @skb:	FCoE ELS frame including FC header but no FCoE headers.
 *
 * Returns non-zero error code on failure.
 *
 * The caller must check that the length is a multiple of 4.
 *
 * The @skb must have enough headroom (28 bytes) and tailroom (8 bytes).
 * Headroom includes the FIP encapsulation description, FIP header, and
 * Ethernet header.  The tailroom is for the FIP MAC descriptor.
 */
static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
			    u8 dtype, struct sk_buff *skb)
{
	struct fip_encaps_head {
		struct ethhdr eth;
		struct fip_header fip;
		struct fip_encaps encaps;
	} __attribute__((packed)) *cap;
	struct fip_mac_desc *mac;
	struct fcoe_fcf *fcf;
	size_t dlen;
	u16 fip_flags;

	fcf = fip->sel_fcf;
	if (!fcf)
		return -ENODEV;

	/* set flags according to both FCF and lport's capability on SPMA */
	fip_flags = fcf->flags;
	fip_flags &= fip->spma ? FIP_FL_SPMA | FIP_FL_FPMA : FIP_FL_FPMA;
	if (!fip_flags)
		return -ENODEV;

	dlen = sizeof(struct fip_encaps) + skb->len;	/* len before push */
	cap = (struct fip_encaps_head *)skb_push(skb, sizeof(*cap));

	memset(cap, 0, sizeof(*cap));
	memcpy(cap->eth.h_dest, fcf->fcf_mac, ETH_ALEN);
	memcpy(cap->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
	cap->eth.h_proto = htons(ETH_P_FIP);

	cap->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
	cap->fip.fip_op = htons(FIP_OP_LS);
	cap->fip.fip_subcode = FIP_SC_REQ;
	cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW);
	cap->fip.fip_flags = htons(fip_flags);

	cap->encaps.fd_desc.fip_dtype = dtype;
	cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;

	mac = (struct fip_mac_desc *)skb_put(skb, sizeof(*mac));
	memset(mac, 0, sizeof(mac));
	mac->fd_desc.fip_dtype = FIP_DT_MAC;
	mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
	if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC)
		memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
	else if (fip->spma)
		memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);

	skb->protocol = htons(ETH_P_FIP);
	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);
	return 0;
}

/**
 * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate.
 * @fip:	FCoE controller.
 * @skb:	FCoE ELS frame including FC header but no FCoE headers.
 *
 * Returns a non-zero error code if the frame should not be sent.
 * Returns zero if the caller should send the frame with FCoE encapsulation.
 *
 * The caller must check that the length is a multiple of 4.
 * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
 */
int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
	struct fc_frame_header *fh;
	u16 old_xid;
	u8 op;

	fh = (struct fc_frame_header *)skb->data;
	op = *(u8 *)(fh + 1);

	if (op == ELS_FLOGI) {
		old_xid = fip->flogi_oxid;
		fip->flogi_oxid = ntohs(fh->fh_ox_id);
		if (fip->state == FIP_ST_AUTO) {
			if (old_xid == FC_XID_UNKNOWN)
				fip->flogi_count = 0;
			fip->flogi_count++;
			if (fip->flogi_count < 3)
				goto drop;
			fip->map_dest = 1;
			return 0;
		}
		if (fip->state == FIP_ST_NON_FIP)
			fip->map_dest = 1;
	}

	if (fip->state == FIP_ST_NON_FIP)
		return 0;

	switch (op) {
	case ELS_FLOGI:
		op = FIP_DT_FLOGI;
		break;
	case ELS_FDISC:
		if (ntoh24(fh->fh_s_id))
			return 0;
		op = FIP_DT_FDISC;
		break;
	case ELS_LOGO:
		if (fip->state != FIP_ST_ENABLED)
			return 0;
		if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
			return 0;
		op = FIP_DT_LOGO;
		break;
	case ELS_LS_ACC:
		if (fip->flogi_oxid == FC_XID_UNKNOWN)
			return 0;
		if (!ntoh24(fh->fh_s_id))
			return 0;
		if (fip->state == FIP_ST_AUTO)
			return 0;
		/*
		 * Here we must've gotten an SID by accepting an FLOGI
		 * from a point-to-point connection.  Switch to using
		 * the source mac based on the SID.  The destination
		 * MAC in this case would have been set by receving the
		 * FLOGI.
		 */
		fip->flogi_oxid = FC_XID_UNKNOWN;
		fc_fcoe_set_mac(fip->data_src_addr, fh->fh_s_id);
		return 0;
	default:
		if (fip->state != FIP_ST_ENABLED)
			goto drop;
		return 0;
	}
	if (fcoe_ctlr_encaps(fip, op, skb))
		goto drop;
	fip->send(fip, skb);
	return -EINPROGRESS;
drop:
	kfree_skb(skb);
	return -EINVAL;
}
EXPORT_SYMBOL(fcoe_ctlr_els_send);

/*
 * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller.
 * @fip:	FCoE controller.
 *
 * Called with lock held.
 *
 * An FCF is considered old if we have missed three advertisements.
 * That is, there have been no valid advertisement from it for three
 * times its keep-alive period including fuzz.
 *
 * In addition, determine the time when an FCF selection can occur.
 */
static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
{
	struct fcoe_fcf *fcf;
	struct fcoe_fcf *next;
	unsigned long sel_time = 0;

	list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
		if (time_after(jiffies, fcf->time + fcf->fka_period * 3 +
			       msecs_to_jiffies(FIP_FCF_FUZZ * 3))) {
			if (fip->sel_fcf == fcf)
				fip->sel_fcf = NULL;
			list_del(&fcf->list);
			WARN_ON(!fip->fcf_count);
			fip->fcf_count--;
			kfree(fcf);
		} else if (fcoe_ctlr_mtu_valid(fcf) &&
			   (!sel_time || time_before(sel_time, fcf->time))) {
			sel_time = fcf->time;
		}
	}
	if (sel_time) {
		sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY);
		fip->sel_time = sel_time;
		if (time_before(sel_time, fip->timer.expires))
			mod_timer(&fip->timer, sel_time);
	} else {
		fip->sel_time = 0;
	}
}

/**
 * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry.
 * @skb:	received FIP advertisement frame
 * @fcf:	resulting FCF entry.
 *
 * Returns zero on a valid parsed advertisement,
 * otherwise returns non zero value.
 */
static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf)
{
	struct fip_header *fiph;
	struct fip_desc *desc = NULL;
	struct fip_wwn_desc *wwn;
	struct fip_fab_desc *fab;
	struct fip_fka_desc *fka;
	unsigned long t;
	size_t rlen;
	size_t dlen;

	memset(fcf, 0, sizeof(*fcf));
	fcf->fka_period = msecs_to_jiffies(FCOE_CTLR_DEF_FKA);

	fiph = (struct fip_header *)skb->data;
	fcf->flags = ntohs(fiph->fip_flags);

	rlen = ntohs(fiph->fip_dl_len) * 4;
	if (rlen + sizeof(*fiph) > skb->len)
		return -EINVAL;

	desc = (struct fip_desc *)(fiph + 1);
	while (rlen > 0) {
		dlen = desc->fip_dlen * FIP_BPW;
		if (dlen < sizeof(*desc) || dlen > rlen)
			return -EINVAL;
		switch (desc->fip_dtype) {
		case FIP_DT_PRI:
			if (dlen != sizeof(struct fip_pri_desc))
				goto len_err;
			fcf->pri = ((struct fip_pri_desc *)desc)->fd_pri;
			break;
		case FIP_DT_MAC:
			if (dlen != sizeof(struct fip_mac_desc))
				goto len_err;
			memcpy(fcf->fcf_mac,
			       ((struct fip_mac_desc *)desc)->fd_mac,
			       ETH_ALEN);
			if (!is_valid_ether_addr(fcf->fcf_mac)) {
				LIBFCOE_FIP_DBG("Invalid MAC address "
						"in FIP adv\n");
				return -EINVAL;
			}
			break;
		case FIP_DT_NAME:
			if (dlen != sizeof(struct fip_wwn_desc))
				goto len_err;
			wwn = (struct fip_wwn_desc *)desc;
			fcf->switch_name = get_unaligned_be64(&wwn->fd_wwn);
			break;
		case FIP_DT_FAB:
			if (dlen != sizeof(struct fip_fab_desc))
				goto len_err;
			fab = (struct fip_fab_desc *)desc;
			fcf->fabric_name = get_unaligned_be64(&fab->fd_wwn);
			fcf->vfid = ntohs(fab->fd_vfid);
			fcf->fc_map = ntoh24(fab->fd_map);
			break;
		case FIP_DT_FKA:
			if (dlen != sizeof(struct fip_fka_desc))
				goto len_err;
			fka = (struct fip_fka_desc *)desc;
			t = ntohl(fka->fd_fka_period);
			if (t >= FCOE_CTLR_MIN_FKA)
				fcf->fka_period = msecs_to_jiffies(t);
			break;
		case FIP_DT_MAP_OUI:
		case FIP_DT_FCOE_SIZE:
		case FIP_DT_FLOGI:
		case FIP_DT_FDISC:
		case FIP_DT_LOGO:
		case FIP_DT_ELP:
		default:
			LIBFCOE_FIP_DBG("unexpected descriptor type %x "
					"in FIP adv\n", desc->fip_dtype);
			/* standard says ignore unknown descriptors >= 128 */
			if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
				return -EINVAL;
			continue;
		}
		desc = (struct fip_desc *)((char *)desc + dlen);
		rlen -= dlen;
	}
	if (!fcf->fc_map || (fcf->fc_map & 0x10000))
		return -EINVAL;
	if (!fcf->switch_name || !fcf->fabric_name)
		return -EINVAL;
	return 0;

len_err:
	LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n",
			desc->fip_dtype, dlen);
	return -EINVAL;
}

/**
 * fcoe_ctlr_recv_adv() - Handle an incoming advertisement.
 * @fip:	FCoE controller.
 * @skb:	Received FIP packet.
 */
static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
	struct fcoe_fcf *fcf;
	struct fcoe_fcf new;
	struct fcoe_fcf *found;
	unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV);
	int first = 0;
	int mtu_valid;

	if (fcoe_ctlr_parse_adv(skb, &new))
		return;

	spin_lock_bh(&fip->lock);
	first = list_empty(&fip->fcfs);
	found = NULL;
	list_for_each_entry(fcf, &fip->fcfs, list) {
		if (fcf->switch_name == new.switch_name &&
		    fcf->fabric_name == new.fabric_name &&
		    fcf->fc_map == new.fc_map &&
		    compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) {
			found = fcf;
			break;
		}
	}
	if (!found) {
		if (fip->fcf_count >= FCOE_CTLR_FCF_LIMIT)
			goto out;

		fcf = kmalloc(sizeof(*fcf), GFP_ATOMIC);
		if (!fcf)
			goto out;

		fip->fcf_count++;
		memcpy(fcf, &new, sizeof(new));
		list_add(&fcf->list, &fip->fcfs);
	} else {
		/*
		 * Flags in advertisements are ignored once the FCF is
		 * selected.  Flags in unsolicited advertisements are
		 * ignored after a usable solicited advertisement
		 * has been received.
		 */
		if (fcf == fip->sel_fcf) {
			fip->ctlr_ka_time -= fcf->fka_period;
			fip->ctlr_ka_time += new.fka_period;
			if (time_before(fip->ctlr_ka_time, fip->timer.expires))
				mod_timer(&fip->timer, fip->ctlr_ka_time);
		} else if (!fcoe_ctlr_fcf_usable(fcf))
			fcf->flags = new.flags;
		fcf->fka_period = new.fka_period;
		memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN);
	}
	mtu_valid = fcoe_ctlr_mtu_valid(fcf);
	fcf->time = jiffies;
	if (!found) {
		LIBFCOE_FIP_DBG("New FCF for fab %llx map %x val %d\n",
				fcf->fabric_name, fcf->fc_map, mtu_valid);
	}

	/*
	 * If this advertisement is not solicited and our max receive size
	 * hasn't been verified, send a solicited advertisement.
	 */
	if (!mtu_valid)
		fcoe_ctlr_solicit(fip, fcf);

	/*
	 * If its been a while since we did a solicit, and this is
	 * the first advertisement we've received, do a multicast
	 * solicitation to gather as many advertisements as we can
	 * before selection occurs.
	 */
	if (first && time_after(jiffies, fip->sol_time + sol_tov))
		fcoe_ctlr_solicit(fip, NULL);

	/*
	 * If this is the first validated FCF, note the time and
	 * set a timer to trigger selection.
	 */
	if (mtu_valid && !fip->sel_time && fcoe_ctlr_fcf_usable(fcf)) {
		fip->sel_time = jiffies +
				msecs_to_jiffies(FCOE_CTLR_START_DELAY);
		if (!timer_pending(&fip->timer) ||
		    time_before(fip->sel_time, fip->timer.expires))
			mod_timer(&fip->timer, fip->sel_time);
	}
out:
	spin_unlock_bh(&fip->lock);
}

/**
 * fcoe_ctlr_recv_els() - Handle an incoming FIP-encapsulated ELS frame.
 * @fip:	FCoE controller.
 * @skb:	Received FIP packet.
 */
static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
	struct fc_lport *lp = fip->lp;
	struct fip_header *fiph;
	struct fc_frame *fp;
	struct fc_frame_header *fh = NULL;
	struct fip_desc *desc;
	struct fip_encaps *els;
	struct fcoe_dev_stats *stats;
	enum fip_desc_type els_dtype = 0;
	u8 els_op;
	u8 sub;
	u8 granted_mac[ETH_ALEN] = { 0 };
	size_t els_len = 0;
	size_t rlen;
	size_t dlen;

	fiph = (struct fip_header *)skb->data;
	sub = fiph->fip_subcode;
	if (sub != FIP_SC_REQ && sub != FIP_SC_REP)
		goto drop;

	rlen = ntohs(fiph->fip_dl_len) * 4;
	if (rlen + sizeof(*fiph) > skb->len)
		goto drop;

	desc = (struct fip_desc *)(fiph + 1);
	while (rlen > 0) {
		dlen = desc->fip_dlen * FIP_BPW;
		if (dlen < sizeof(*desc) || dlen > rlen)
			goto drop;
		switch (desc->fip_dtype) {
		case FIP_DT_MAC:
			if (dlen != sizeof(struct fip_mac_desc))
				goto len_err;
			memcpy(granted_mac,
			       ((struct fip_mac_desc *)desc)->fd_mac,
			       ETH_ALEN);
			if (!is_valid_ether_addr(granted_mac)) {
				LIBFCOE_FIP_DBG("Invalid MAC address "
						"in FIP ELS\n");
				goto drop;
			}
			break;
		case FIP_DT_FLOGI:
		case FIP_DT_FDISC:
		case FIP_DT_LOGO:
		case FIP_DT_ELP:
			if (fh)
				goto drop;
			if (dlen < sizeof(*els) + sizeof(*fh) + 1)
				goto len_err;
			els_len = dlen - sizeof(*els);
			els = (struct fip_encaps *)desc;
			fh = (struct fc_frame_header *)(els + 1);
			els_dtype = desc->fip_dtype;
			break;
		default:
			LIBFCOE_FIP_DBG("unexpected descriptor type %x "
					"in FIP adv\n", desc->fip_dtype);
			/* standard says ignore unknown descriptors >= 128 */
			if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
				goto drop;
			continue;
		}
		desc = (struct fip_desc *)((char *)desc + dlen);
		rlen -= dlen;
	}

	if (!fh)
		goto drop;
	els_op = *(u8 *)(fh + 1);

	if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) &&
	    sub == FIP_SC_REP && fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
	    els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) {
		fip->flogi_oxid = FC_XID_UNKNOWN;
		fip->update_mac(fip, fip->data_src_addr, granted_mac);
		memcpy(fip->data_src_addr, granted_mac, ETH_ALEN);
	}

	/*
	 * Convert skb into an fc_frame containing only the ELS.
	 */
	skb_pull(skb, (u8 *)fh - skb->data);
	skb_trim(skb, els_len);
	fp = (struct fc_frame *)skb;
	fc_frame_init(fp);
	fr_sof(fp) = FC_SOF_I3;
	fr_eof(fp) = FC_EOF_T;
	fr_dev(fp) = lp;

	stats = fc_lport_get_stats(lp);
	stats->RxFrames++;
	stats->RxWords += skb->len / FIP_BPW;

	fc_exch_recv(lp, fp);
	return;

len_err:
	LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n",
			desc->fip_dtype, dlen);
drop:
	kfree_skb(skb);
}

/**
 * fcoe_ctlr_recv_els() - Handle an incoming link reset frame.
 * @fip:	FCoE controller.
 * @fh:		Received FIP header.
 *
 * There may be multiple VN_Port descriptors.
 * The overall length has already been checked.
 */
static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
				      struct fip_header *fh)
{
	struct fip_desc *desc;
	struct fip_mac_desc *mp;
	struct fip_wwn_desc *wp;
	struct fip_vn_desc *vp;
	size_t rlen;
	size_t dlen;
	struct fcoe_fcf *fcf = fip->sel_fcf;
	struct fc_lport *lp = fip->lp;
	u32	desc_mask;

	LIBFCOE_FIP_DBG("Clear Virtual Link received\n");
	if (!fcf)
		return;
	if (!fcf || !fc_host_port_id(lp->host))
		return;

	/*
	 * mask of required descriptors.  Validating each one clears its bit.
	 */
	desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME) | BIT(FIP_DT_VN_ID);

	rlen = ntohs(fh->fip_dl_len) * FIP_BPW;
	desc = (struct fip_desc *)(fh + 1);
	while (rlen >= sizeof(*desc)) {
		dlen = desc->fip_dlen * FIP_BPW;
		if (dlen > rlen)
			return;
		switch (desc->fip_dtype) {
		case FIP_DT_MAC:
			mp = (struct fip_mac_desc *)desc;
			if (dlen < sizeof(*mp))
				return;
			if (compare_ether_addr(mp->fd_mac, fcf->fcf_mac))
				return;
			desc_mask &= ~BIT(FIP_DT_MAC);
			break;
		case FIP_DT_NAME:
			wp = (struct fip_wwn_desc *)desc;
			if (dlen < sizeof(*wp))
				return;
			if (get_unaligned_be64(&wp->fd_wwn) != fcf->switch_name)
				return;
			desc_mask &= ~BIT(FIP_DT_NAME);
			break;
		case FIP_DT_VN_ID:
			vp = (struct fip_vn_desc *)desc;
			if (dlen < sizeof(*vp))
				return;
			if (compare_ether_addr(vp->fd_mac,
			    fip->data_src_addr) == 0 &&
			    get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn &&
			    ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host))
				desc_mask &= ~BIT(FIP_DT_VN_ID);
			break;
		default:
			/* standard says ignore unknown descriptors >= 128 */
			if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
				return;
			break;
		}
		desc = (struct fip_desc *)((char *)desc + dlen);
		rlen -= dlen;
	}

	/*
	 * reset only if all required descriptors were present and valid.
	 */
	if (desc_mask) {
		LIBFCOE_FIP_DBG("missing descriptors mask %x\n", desc_mask);
	} else {
		LIBFCOE_FIP_DBG("performing Clear Virtual Link\n");
		fcoe_ctlr_reset(fip, FIP_ST_ENABLED);
	}
}

/**
 * fcoe_ctlr_recv() - Receive a FIP frame.
 * @fip:	FCoE controller.
 * @skb:	Received FIP packet.
 *
 * This is called from NET_RX_SOFTIRQ.
 */
void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
	spin_lock_bh(&fip->fip_recv_list.lock);
	__skb_queue_tail(&fip->fip_recv_list, skb);
	spin_unlock_bh(&fip->fip_recv_list.lock);
	schedule_work(&fip->recv_work);
}
EXPORT_SYMBOL(fcoe_ctlr_recv);

/**
 * fcoe_ctlr_recv_handler() - Receive a FIP frame.
 * @fip:	FCoE controller.
 * @skb:	Received FIP packet.
 *
 * Returns non-zero if the frame is dropped.
 */
static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
	struct fip_header *fiph;
	struct ethhdr *eh;
	enum fip_state state;
	u16 op;
	u8 sub;

	if (skb_linearize(skb))
		goto drop;
	if (skb->len < sizeof(*fiph))
		goto drop;
	eh = eth_hdr(skb);
	if (compare_ether_addr(eh->h_dest, fip->ctl_src_addr) &&
	    compare_ether_addr(eh->h_dest, FIP_ALL_ENODE_MACS))
		goto drop;
	fiph = (struct fip_header *)skb->data;
	op = ntohs(fiph->fip_op);
	sub = fiph->fip_subcode;

	if (FIP_VER_DECAPS(fiph->fip_ver) != FIP_VER)
		goto drop;
	if (ntohs(fiph->fip_dl_len) * FIP_BPW + sizeof(*fiph) > skb->len)
		goto drop;

	spin_lock_bh(&fip->lock);
	state = fip->state;
	if (state == FIP_ST_AUTO) {
		fip->map_dest = 0;
		fip->state = FIP_ST_ENABLED;
		state = FIP_ST_ENABLED;
		LIBFCOE_FIP_DBG("Using FIP mode\n");
	}
	spin_unlock_bh(&fip->lock);
	if (state != FIP_ST_ENABLED)
		goto drop;

	if (op == FIP_OP_LS) {
		fcoe_ctlr_recv_els(fip, skb);	/* consumes skb */
		return 0;
	}
	if (op == FIP_OP_DISC && sub == FIP_SC_ADV)
		fcoe_ctlr_recv_adv(fip, skb);
	else if (op == FIP_OP_CTRL && sub == FIP_SC_CLR_VLINK)
		fcoe_ctlr_recv_clr_vlink(fip, fiph);
	kfree_skb(skb);
	return 0;
drop:
	kfree_skb(skb);
	return -1;
}

/**
 * fcoe_ctlr_select() - Select the best FCF, if possible.
 * @fip:	FCoE controller.
 *
 * If there are conflicting advertisements, no FCF can be chosen.
 *
 * Called with lock held.
 */
static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
{
	struct fcoe_fcf *fcf;
	struct fcoe_fcf *best = NULL;

	list_for_each_entry(fcf, &fip->fcfs, list) {
		LIBFCOE_FIP_DBG("consider FCF for fab %llx VFID %d map %x "
				"val %d\n", fcf->fabric_name, fcf->vfid,
				fcf->fc_map, fcoe_ctlr_mtu_valid(fcf));
		if (!fcoe_ctlr_fcf_usable(fcf)) {
			LIBFCOE_FIP_DBG("FCF for fab %llx map %x %svalid "
					"%savailable\n", fcf->fabric_name,
					fcf->fc_map, (fcf->flags & FIP_FL_SOL)
					? "" : "in", (fcf->flags & FIP_FL_AVAIL)
					? "" : "un");
			continue;
		}
		if (!best) {
			best = fcf;
			continue;
		}
		if (fcf->fabric_name != best->fabric_name ||
		    fcf->vfid != best->vfid ||
		    fcf->fc_map != best->fc_map) {
			LIBFCOE_FIP_DBG("Conflicting fabric, VFID, "
					"or FC-MAP\n");
			return;
		}
		if (fcf->pri < best->pri)
			best = fcf;
	}
	fip->sel_fcf = best;
}

/**
 * fcoe_ctlr_timeout() - FIP timer function.
 * @arg:	&fcoe_ctlr pointer.
 *
 * Ages FCFs.  Triggers FCF selection if possible.  Sends keep-alives.
 */
static void fcoe_ctlr_timeout(unsigned long arg)
{
	struct fcoe_ctlr *fip = (struct fcoe_ctlr *)arg;
	struct fcoe_fcf *sel;
	struct fcoe_fcf *fcf;
	unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
	u8 send_ctlr_ka;
	u8 send_port_ka;

	spin_lock_bh(&fip->lock);
	if (fip->state == FIP_ST_DISABLED) {
		spin_unlock_bh(&fip->lock);
		return;
	}

	fcf = fip->sel_fcf;
	fcoe_ctlr_age_fcfs(fip);

	sel = fip->sel_fcf;
	if (!sel && fip->sel_time && time_after_eq(jiffies, fip->sel_time)) {
		fcoe_ctlr_select(fip);
		sel = fip->sel_fcf;
		fip->sel_time = 0;
	}

	if (sel != fcf) {
		fcf = sel;		/* the old FCF may have been freed */
		if (sel) {
			printk(KERN_INFO "libfcoe: host%d: FIP selected "
			       "Fibre-Channel Forwarder MAC %pM\n",
			       fip->lp->host->host_no, sel->fcf_mac);
			memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
			fip->port_ka_time = jiffies +
					    msecs_to_jiffies(FIP_VN_KA_PERIOD);
			fip->ctlr_ka_time = jiffies + sel->fka_period;
			fip->link = 1;
		} else {
			printk(KERN_NOTICE "libfcoe: host%d: "
			       "FIP Fibre-Channel Forwarder timed out.  "
			       "Starting FCF discovery.\n",
			       fip->lp->host->host_no);
			fip->link = 0;
		}
		schedule_work(&fip->link_work);
	}

	send_ctlr_ka = 0;
	send_port_ka = 0;
	if (sel) {
		if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
			fip->ctlr_ka_time = jiffies + sel->fka_period;
			send_ctlr_ka = 1;
		}
		if (time_after(next_timer, fip->ctlr_ka_time))
			next_timer = fip->ctlr_ka_time;

		if (time_after_eq(jiffies, fip->port_ka_time)) {
			fip->port_ka_time += jiffies +
					msecs_to_jiffies(FIP_VN_KA_PERIOD);
			send_port_ka = 1;
		}
		if (time_after(next_timer, fip->port_ka_time))
			next_timer = fip->port_ka_time;
		mod_timer(&fip->timer, next_timer);
	} else if (fip->sel_time) {
		next_timer = fip->sel_time +
				msecs_to_jiffies(FCOE_CTLR_START_DELAY);
		mod_timer(&fip->timer, next_timer);
	}
	spin_unlock_bh(&fip->lock);

	if (send_ctlr_ka)
		fcoe_ctlr_send_keep_alive(fip, 0, fip->ctl_src_addr);
	if (send_port_ka)
		fcoe_ctlr_send_keep_alive(fip, 1, fip->data_src_addr);
}

/**
 * fcoe_ctlr_link_work() - worker thread function for link changes.
 * @work:	pointer to link_work member inside &fcoe_ctlr.
 *
 * See if the link status has changed and if so, report it.
 *
 * This is here because fc_linkup() and fc_linkdown() must not
 * be called from the timer directly, since they use a mutex.
 */
static void fcoe_ctlr_link_work(struct work_struct *work)
{
	struct fcoe_ctlr *fip;
	int link;
	int last_link;

	fip = container_of(work, struct fcoe_ctlr, link_work);
	spin_lock_bh(&fip->lock);
	last_link = fip->last_link;
	link = fip->link;
	fip->last_link = link;
	spin_unlock_bh(&fip->lock);

	if (last_link != link) {
		if (link)
			fc_linkup(fip->lp);
		else
			fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
	}
}

/**
 * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames.
 * @recv_work:	pointer to recv_work member inside &fcoe_ctlr.
 */
static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
{
	struct fcoe_ctlr *fip;
	struct sk_buff *skb;

	fip = container_of(recv_work, struct fcoe_ctlr, recv_work);
	spin_lock_bh(&fip->fip_recv_list.lock);
	while ((skb = __skb_dequeue(&fip->fip_recv_list))) {
		spin_unlock_bh(&fip->fip_recv_list.lock);
		fcoe_ctlr_recv_handler(fip, skb);
		spin_lock_bh(&fip->fip_recv_list.lock);
	}
	spin_unlock_bh(&fip->fip_recv_list.lock);
}

/**
 * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request.
 * @fip:	FCoE controller.
 * @fp:		FC frame.
 * @sa:		Ethernet source MAC address from received FCoE frame.
 *
 * Snoop potential response to FLOGI or even incoming FLOGI.
 *
 * The caller has checked that we are waiting for login as indicated
 * by fip->flogi_oxid != FC_XID_UNKNOWN.
 *
 * The caller is responsible for freeing the frame.
 *
 * Return non-zero if the frame should not be delivered to libfc.
 */
int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa)
{
	struct fc_frame_header *fh;
	u8 op;
	u8 mac[ETH_ALEN];

	fh = fc_frame_header_get(fp);
	if (fh->fh_type != FC_TYPE_ELS)
		return 0;

	op = fc_frame_payload_op(fp);
	if (op == ELS_LS_ACC && fh->fh_r_ctl == FC_RCTL_ELS_REP &&
	    fip->flogi_oxid == ntohs(fh->fh_ox_id)) {

		spin_lock_bh(&fip->lock);
		if (fip->state != FIP_ST_AUTO && fip->state != FIP_ST_NON_FIP) {
			spin_unlock_bh(&fip->lock);
			return -EINVAL;
		}
		fip->state = FIP_ST_NON_FIP;
		LIBFCOE_FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n");

		/*
		 * FLOGI accepted.
		 * If the src mac addr is FC_OUI-based, then we mark the
		 * address_mode flag to use FC_OUI-based Ethernet DA.
		 * Otherwise we use the FCoE gateway addr
		 */
		if (!compare_ether_addr(sa, (u8[6])FC_FCOE_FLOGI_MAC)) {
			fip->map_dest = 1;
		} else {
			memcpy(fip->dest_addr, sa, ETH_ALEN);
			fip->map_dest = 0;
		}
		fip->flogi_oxid = FC_XID_UNKNOWN;
		memcpy(mac, fip->data_src_addr, ETH_ALEN);
		fc_fcoe_set_mac(fip->data_src_addr, fh->fh_d_id);
		spin_unlock_bh(&fip->lock);

		fip->update_mac(fip, mac, fip->data_src_addr);
	} else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
		/*
		 * Save source MAC for point-to-point responses.
		 */
		spin_lock_bh(&fip->lock);
		if (fip->state == FIP_ST_AUTO || fip->state == FIP_ST_NON_FIP) {
			memcpy(fip->dest_addr, sa, ETH_ALEN);
			fip->map_dest = 0;
			if (fip->state == FIP_ST_NON_FIP)
				LIBFCOE_FIP_DBG("received FLOGI REQ, "
						"using non-FIP mode\n");
			fip->state = FIP_ST_NON_FIP;
		}
		spin_unlock_bh(&fip->lock);
	}
	return 0;
}
EXPORT_SYMBOL(fcoe_ctlr_recv_flogi);

/**
 * fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN.
 * @mac: mac address
 * @scheme: check port
 * @port: port indicator for converting
 *
 * Returns: u64 fc world wide name
 */
u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
		      unsigned int scheme, unsigned int port)
{
	u64 wwn;
	u64 host_mac;

	/* The MAC is in NO, so flip only the low 48 bits */
	host_mac = ((u64) mac[0] << 40) |
		((u64) mac[1] << 32) |
		((u64) mac[2] << 24) |
		((u64) mac[3] << 16) |
		((u64) mac[4] << 8) |
		(u64) mac[5];

	WARN_ON(host_mac >= (1ULL << 48));
	wwn = host_mac | ((u64) scheme << 60);
	switch (scheme) {
	case 1:
		WARN_ON(port != 0);
		break;
	case 2:
		WARN_ON(port >= 0xfff);
		wwn |= (u64) port << 48;
		break;
	default:
		WARN_ON(1);
		break;
	}

	return wwn;
}
EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);

/**
 * fcoe_libfc_config() - sets up libfc related properties for lport
 * @lp: ptr to the fc_lport
 * @tt: libfc function template
 *
 * Returns : 0 for success
 */
int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt)
{
	/* Set the function pointers set by the LLDD */
	memcpy(&lp->tt, tt, sizeof(*tt));
	if (fc_fcp_init(lp))
		return -ENOMEM;
	fc_exch_init(lp);
	fc_elsct_init(lp);
	fc_lport_init(lp);
	fc_rport_init(lp);
	fc_disc_init(lp);

	return 0;
}
EXPORT_SYMBOL_GPL(fcoe_libfc_config);
