/*
 * Copyright 2008 Cisco Systems, Inc.  All rights reserved.
 * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
 *
 * This program is free software; you may redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/workqueue.h>
#include <scsi/fc/fc_fip.h>
#include <scsi/fc/fc_els.h>
#include <scsi/fc/fc_fcoe.h>
#include <scsi/fc_frame.h>
#include <scsi/libfc.h>
#include "fnic_io.h"
#include "fnic.h"
#include "fnic_fip.h"
#include "cq_enet_desc.h"
#include "cq_exch_desc.h"

static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS;
struct workqueue_struct *fnic_fip_queue;
struct workqueue_struct *fnic_event_queue;

static void fnic_set_eth_mode(struct fnic *);
static void fnic_fcoe_send_vlan_req(struct fnic *fnic);
static void fnic_fcoe_start_fcf_disc(struct fnic *fnic);
static void fnic_fcoe_process_vlan_resp(struct fnic *fnic, struct sk_buff *);
static int fnic_fcoe_vlan_check(struct fnic *fnic, u16 flag);
static int fnic_fcoe_handle_fip_frame(struct fnic *fnic, struct sk_buff *skb);

void fnic_handle_link(struct work_struct *work)
{
	struct fnic *fnic = container_of(work, struct fnic, link_work);
	unsigned long flags;
	int old_link_status;
	u32 old_link_down_cnt;
	u64 old_port_speed, new_port_speed;

	spin_lock_irqsave(&fnic->fnic_lock, flags);

	fnic->link_events = 1;      /* less work to just set everytime*/

	if (fnic->stop_rx_link_events) {
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
		return;
	}

	old_link_down_cnt = fnic->link_down_cnt;
	old_link_status = fnic->link_status;
	old_port_speed = atomic64_read(
			&fnic->fnic_stats.misc_stats.current_port_speed);

	fnic->link_status = vnic_dev_link_status(fnic->vdev);
	fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev);

	new_port_speed = vnic_dev_port_speed(fnic->vdev);
	atomic64_set(&fnic->fnic_stats.misc_stats.current_port_speed,
			new_port_speed);
	if (old_port_speed != new_port_speed)
		FNIC_MAIN_DBG(KERN_INFO, fnic->lport->host,
				"Current vnic speed set to :  %llu\n",
				new_port_speed);

	switch (vnic_dev_port_speed(fnic->vdev)) {
	case DCEM_PORTSPEED_10G:
		fc_host_speed(fnic->lport->host)   = FC_PORTSPEED_10GBIT;
		fnic->lport->link_supported_speeds = FC_PORTSPEED_10GBIT;
		break;
	case DCEM_PORTSPEED_20G:
		fc_host_speed(fnic->lport->host)   = FC_PORTSPEED_20GBIT;
		fnic->lport->link_supported_speeds = FC_PORTSPEED_20GBIT;
		break;
	case DCEM_PORTSPEED_25G:
		fc_host_speed(fnic->lport->host)   = FC_PORTSPEED_25GBIT;
		fnic->lport->link_supported_speeds = FC_PORTSPEED_25GBIT;
		break;
	case DCEM_PORTSPEED_40G:
	case DCEM_PORTSPEED_4x10G:
		fc_host_speed(fnic->lport->host)   = FC_PORTSPEED_40GBIT;
		fnic->lport->link_supported_speeds = FC_PORTSPEED_40GBIT;
		break;
	case DCEM_PORTSPEED_100G:
		fc_host_speed(fnic->lport->host)   = FC_PORTSPEED_100GBIT;
		fnic->lport->link_supported_speeds = FC_PORTSPEED_100GBIT;
		break;
	default:
		fc_host_speed(fnic->lport->host)   = FC_PORTSPEED_UNKNOWN;
		fnic->lport->link_supported_speeds = FC_PORTSPEED_UNKNOWN;
		break;
	}

	if (old_link_status == fnic->link_status) {
		if (!fnic->link_status) {
			/* DOWN -> DOWN */
			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
			fnic_fc_trace_set_data(fnic->lport->host->host_no,
				FNIC_FC_LE, "Link Status: DOWN->DOWN",
				strlen("Link Status: DOWN->DOWN"));
		} else {
			if (old_link_down_cnt != fnic->link_down_cnt) {
				/* UP -> DOWN -> UP */
				fnic->lport->host_stats.link_failure_count++;
				spin_unlock_irqrestore(&fnic->fnic_lock, flags);
				fnic_fc_trace_set_data(
					fnic->lport->host->host_no,
					FNIC_FC_LE,
					"Link Status:UP_DOWN_UP",
					strlen("Link_Status:UP_DOWN_UP")
					);
				FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
					     "link down\n");
				fcoe_ctlr_link_down(&fnic->ctlr);
				if (fnic->config.flags & VFCF_FIP_CAPABLE) {
					/* start FCoE VLAN discovery */
					fnic_fc_trace_set_data(
						fnic->lport->host->host_no,
						FNIC_FC_LE,
						"Link Status: UP_DOWN_UP_VLAN",
						strlen(
						"Link Status: UP_DOWN_UP_VLAN")
						);
					fnic_fcoe_send_vlan_req(fnic);
					return;
				}
				FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
					     "link up\n");
				fcoe_ctlr_link_up(&fnic->ctlr);
			} else {
				/* UP -> UP */
				spin_unlock_irqrestore(&fnic->fnic_lock, flags);
				fnic_fc_trace_set_data(
					fnic->lport->host->host_no, FNIC_FC_LE,
					"Link Status: UP_UP",
					strlen("Link Status: UP_UP"));
			}
		}
	} else if (fnic->link_status) {
		/* DOWN -> UP */
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
		if (fnic->config.flags & VFCF_FIP_CAPABLE) {
			/* start FCoE VLAN discovery */
				fnic_fc_trace_set_data(
				fnic->lport->host->host_no,
				FNIC_FC_LE, "Link Status: DOWN_UP_VLAN",
				strlen("Link Status: DOWN_UP_VLAN"));
			fnic_fcoe_send_vlan_req(fnic);
			return;
		}
		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
		fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_LE,
			"Link Status: DOWN_UP", strlen("Link Status: DOWN_UP"));
		fcoe_ctlr_link_up(&fnic->ctlr);
	} else {
		/* UP -> DOWN */
		fnic->lport->host_stats.link_failure_count++;
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n");
		fnic_fc_trace_set_data(
			fnic->lport->host->host_no, FNIC_FC_LE,
			"Link Status: UP_DOWN",
			strlen("Link Status: UP_DOWN"));
		if (fnic->config.flags & VFCF_FIP_CAPABLE) {
			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
				"deleting fip-timer during link-down\n");
			del_timer_sync(&fnic->fip_timer);
		}
		fcoe_ctlr_link_down(&fnic->ctlr);
	}

}

/*
 * This function passes incoming fabric frames to libFC
 */
void fnic_handle_frame(struct work_struct *work)
{
	struct fnic *fnic = container_of(work, struct fnic, frame_work);
	struct fc_lport *lp = fnic->lport;
	unsigned long flags;
	struct sk_buff *skb;
	struct fc_frame *fp;

	while ((skb = skb_dequeue(&fnic->frame_queue))) {

		spin_lock_irqsave(&fnic->fnic_lock, flags);
		if (fnic->stop_rx_link_events) {
			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
			dev_kfree_skb(skb);
			return;
		}
		fp = (struct fc_frame *)skb;

		/*
		 * If we're in a transitional state, just re-queue and return.
		 * The queue will be serviced when we get to a stable state.
		 */
		if (fnic->state != FNIC_IN_FC_MODE &&
		    fnic->state != FNIC_IN_ETH_MODE) {
			skb_queue_head(&fnic->frame_queue, skb);
			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
			return;
		}
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);

		fc_exch_recv(lp, fp);
	}
}

void fnic_fcoe_evlist_free(struct fnic *fnic)
{
	struct fnic_event *fevt = NULL;
	struct fnic_event *next = NULL;
	unsigned long flags;

	spin_lock_irqsave(&fnic->fnic_lock, flags);
	if (list_empty(&fnic->evlist)) {
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
		return;
	}

	list_for_each_entry_safe(fevt, next, &fnic->evlist, list) {
		list_del(&fevt->list);
		kfree(fevt);
	}
	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
}

void fnic_handle_event(struct work_struct *work)
{
	struct fnic *fnic = container_of(work, struct fnic, event_work);
	struct fnic_event *fevt = NULL;
	struct fnic_event *next = NULL;
	unsigned long flags;

	spin_lock_irqsave(&fnic->fnic_lock, flags);
	if (list_empty(&fnic->evlist)) {
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
		return;
	}

	list_for_each_entry_safe(fevt, next, &fnic->evlist, list) {
		if (fnic->stop_rx_link_events) {
			list_del(&fevt->list);
			kfree(fevt);
			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
			return;
		}
		/*
		 * If we're in a transitional state, just re-queue and return.
		 * The queue will be serviced when we get to a stable state.
		 */
		if (fnic->state != FNIC_IN_FC_MODE &&
		    fnic->state != FNIC_IN_ETH_MODE) {
			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
			return;
		}

		list_del(&fevt->list);
		switch (fevt->event) {
		case FNIC_EVT_START_VLAN_DISC:
			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
			fnic_fcoe_send_vlan_req(fnic);
			spin_lock_irqsave(&fnic->fnic_lock, flags);
			break;
		case FNIC_EVT_START_FCF_DISC:
			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
				  "Start FCF Discovery\n");
			fnic_fcoe_start_fcf_disc(fnic);
			break;
		default:
			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
				  "Unknown event 0x%x\n", fevt->event);
			break;
		}
		kfree(fevt);
	}
	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
}

/**
 * Check if the Received FIP FLOGI frame is rejected
 * @fip: The FCoE controller that received the frame
 * @skb: The received FIP frame
 *
 * Returns non-zero if the frame is rejected with unsupported cmd with
 * insufficient resource els explanation.
 */
static inline int is_fnic_fip_flogi_reject(struct fcoe_ctlr *fip,
					 struct sk_buff *skb)
{
	struct fc_lport *lport = fip->lp;
	struct fip_header *fiph;
	struct fc_frame_header *fh = NULL;
	struct fip_desc *desc;
	struct fip_encaps *els;
	u16 op;
	u8 els_op;
	u8 sub;

	size_t rlen;
	size_t dlen = 0;

	if (skb_linearize(skb))
		return 0;

	if (skb->len < sizeof(*fiph))
		return 0;

	fiph = (struct fip_header *)skb->data;
	op = ntohs(fiph->fip_op);
	sub = fiph->fip_subcode;

	if (op != FIP_OP_LS)
		return 0;

	if (sub != FIP_SC_REP)
		return 0;

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

	desc = (struct fip_desc *)(fiph + 1);
	dlen = desc->fip_dlen * FIP_BPW;

	if (desc->fip_dtype == FIP_DT_FLOGI) {

		if (dlen < sizeof(*els) + sizeof(*fh) + 1)
			return 0;

		els = (struct fip_encaps *)desc;
		fh = (struct fc_frame_header *)(els + 1);

		if (!fh)
			return 0;

		/*
		 * ELS command code, reason and explanation should be = Reject,
		 * unsupported command and insufficient resource
		 */
		els_op = *(u8 *)(fh + 1);
		if (els_op == ELS_LS_RJT) {
			shost_printk(KERN_INFO, lport->host,
				  "Flogi Request Rejected by Switch\n");
			return 1;
		}
		shost_printk(KERN_INFO, lport->host,
				"Flogi Request Accepted by Switch\n");
	}
	return 0;
}

static void fnic_fcoe_send_vlan_req(struct fnic *fnic)
{
	struct fcoe_ctlr *fip = &fnic->ctlr;
	struct fnic_stats *fnic_stats = &fnic->fnic_stats;
	struct sk_buff *skb;
	char *eth_fr;
	struct fip_vlan *vlan;
	u64 vlan_tov;

	fnic_fcoe_reset_vlans(fnic);
	fnic->set_vlan(fnic, 0);

	if (printk_ratelimit())
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host,
			  "Sending VLAN request...\n");

	skb = dev_alloc_skb(sizeof(struct fip_vlan));
	if (!skb)
		return;

	eth_fr = (char *)skb->data;
	vlan = (struct fip_vlan *)eth_fr;

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

	vlan->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
	vlan->fip.fip_op = htons(FIP_OP_VLAN);
	vlan->fip.fip_subcode = FIP_SC_VL_REQ;
	vlan->fip.fip_dl_len = htons(sizeof(vlan->desc) / FIP_BPW);

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

	vlan->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME;
	vlan->desc.wwnn.fd_desc.fip_dlen = sizeof(vlan->desc.wwnn) / FIP_BPW;
	put_unaligned_be64(fip->lp->wwnn, &vlan->desc.wwnn.fd_wwn);
	atomic64_inc(&fnic_stats->vlan_stats.vlan_disc_reqs);

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

	/* set a timer so that we can retry if there no response */
	vlan_tov = jiffies + msecs_to_jiffies(FCOE_CTLR_FIPVLAN_TOV);
	mod_timer(&fnic->fip_timer, round_jiffies(vlan_tov));
}

static void fnic_fcoe_process_vlan_resp(struct fnic *fnic, struct sk_buff *skb)
{
	struct fcoe_ctlr *fip = &fnic->ctlr;
	struct fip_header *fiph;
	struct fip_desc *desc;
	struct fnic_stats *fnic_stats = &fnic->fnic_stats;
	u16 vid;
	size_t rlen;
	size_t dlen;
	struct fcoe_vlan *vlan;
	u64 sol_time;
	unsigned long flags;

	FNIC_FCS_DBG(KERN_INFO, fnic->lport->host,
		  "Received VLAN response...\n");

	fiph = (struct fip_header *) skb->data;

	FNIC_FCS_DBG(KERN_INFO, fnic->lport->host,
		  "Received VLAN response... OP 0x%x SUB_OP 0x%x\n",
		  ntohs(fiph->fip_op), fiph->fip_subcode);

	rlen = ntohs(fiph->fip_dl_len) * 4;
	fnic_fcoe_reset_vlans(fnic);
	spin_lock_irqsave(&fnic->vlans_lock, flags);
	desc = (struct fip_desc *)(fiph + 1);
	while (rlen > 0) {
		dlen = desc->fip_dlen * FIP_BPW;
		switch (desc->fip_dtype) {
		case FIP_DT_VLAN:
			vid = ntohs(((struct fip_vlan_desc *)desc)->fd_vlan);
			shost_printk(KERN_INFO, fnic->lport->host,
				  "process_vlan_resp: FIP VLAN %d\n", vid);
			vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
			if (!vlan) {
				/* retry from timer */
				spin_unlock_irqrestore(&fnic->vlans_lock,
							flags);
				goto out;
			}
			vlan->vid = vid & 0x0fff;
			vlan->state = FIP_VLAN_AVAIL;
			list_add_tail(&vlan->list, &fnic->vlans);
			break;
		}
		desc = (struct fip_desc *)((char *)desc + dlen);
		rlen -= dlen;
	}

	/* any VLAN descriptors present ? */
	if (list_empty(&fnic->vlans)) {
		/* retry from timer */
		atomic64_inc(&fnic_stats->vlan_stats.resp_withno_vlanID);
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host,
			  "No VLAN descriptors in FIP VLAN response\n");
		spin_unlock_irqrestore(&fnic->vlans_lock, flags);
		goto out;
	}

	vlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, list);
	fnic->set_vlan(fnic, vlan->vid);
	vlan->state = FIP_VLAN_SENT; /* sent now */
	vlan->sol_count++;
	spin_unlock_irqrestore(&fnic->vlans_lock, flags);

	/* start the solicitation */
	fcoe_ctlr_link_up(fip);

	sol_time = jiffies + msecs_to_jiffies(FCOE_CTLR_START_DELAY);
	mod_timer(&fnic->fip_timer, round_jiffies(sol_time));
out:
	return;
}

static void fnic_fcoe_start_fcf_disc(struct fnic *fnic)
{
	unsigned long flags;
	struct fcoe_vlan *vlan;
	u64 sol_time;

	spin_lock_irqsave(&fnic->vlans_lock, flags);
	vlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, list);
	fnic->set_vlan(fnic, vlan->vid);
	vlan->state = FIP_VLAN_SENT; /* sent now */
	vlan->sol_count = 1;
	spin_unlock_irqrestore(&fnic->vlans_lock, flags);

	/* start the solicitation */
	fcoe_ctlr_link_up(&fnic->ctlr);

	sol_time = jiffies + msecs_to_jiffies(FCOE_CTLR_START_DELAY);
	mod_timer(&fnic->fip_timer, round_jiffies(sol_time));
}

static int fnic_fcoe_vlan_check(struct fnic *fnic, u16 flag)
{
	unsigned long flags;
	struct fcoe_vlan *fvlan;

	spin_lock_irqsave(&fnic->vlans_lock, flags);
	if (list_empty(&fnic->vlans)) {
		spin_unlock_irqrestore(&fnic->vlans_lock, flags);
		return -EINVAL;
	}

	fvlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, list);
	if (fvlan->state == FIP_VLAN_USED) {
		spin_unlock_irqrestore(&fnic->vlans_lock, flags);
		return 0;
	}

	if (fvlan->state == FIP_VLAN_SENT) {
		fvlan->state = FIP_VLAN_USED;
		spin_unlock_irqrestore(&fnic->vlans_lock, flags);
		return 0;
	}
	spin_unlock_irqrestore(&fnic->vlans_lock, flags);
	return -EINVAL;
}

static void fnic_event_enq(struct fnic *fnic, enum fnic_evt ev)
{
	struct fnic_event *fevt;
	unsigned long flags;

	fevt = kmalloc(sizeof(*fevt), GFP_ATOMIC);
	if (!fevt)
		return;

	fevt->fnic = fnic;
	fevt->event = ev;

	spin_lock_irqsave(&fnic->fnic_lock, flags);
	list_add_tail(&fevt->list, &fnic->evlist);
	spin_unlock_irqrestore(&fnic->fnic_lock, flags);

	schedule_work(&fnic->event_work);
}

static int fnic_fcoe_handle_fip_frame(struct fnic *fnic, struct sk_buff *skb)
{
	struct fip_header *fiph;
	int ret = 1;
	u16 op;
	u8 sub;

	if (!skb || !(skb->data))
		return -1;

	if (skb_linearize(skb))
		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;

	if (op == FIP_OP_DISC && sub == FIP_SC_ADV) {
		if (fnic_fcoe_vlan_check(fnic, ntohs(fiph->fip_flags)))
			goto drop;
		/* pass it on to fcoe */
		ret = 1;
	} else if (op == FIP_OP_VLAN && sub == FIP_SC_VL_NOTE) {
		/* set the vlan as used */
		fnic_fcoe_process_vlan_resp(fnic, skb);
		ret = 0;
	} else if (op == FIP_OP_CTRL && sub == FIP_SC_CLR_VLINK) {
		/* received CVL request, restart vlan disc */
		fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC);
		/* pass it on to fcoe */
		ret = 1;
	}
drop:
	return ret;
}

void fnic_handle_fip_frame(struct work_struct *work)
{
	struct fnic *fnic = container_of(work, struct fnic, fip_frame_work);
	struct fnic_stats *fnic_stats = &fnic->fnic_stats;
	unsigned long flags;
	struct sk_buff *skb;
	struct ethhdr *eh;

	while ((skb = skb_dequeue(&fnic->fip_frame_queue))) {
		spin_lock_irqsave(&fnic->fnic_lock, flags);
		if (fnic->stop_rx_link_events) {
			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
			dev_kfree_skb(skb);
			return;
		}
		/*
		 * If we're in a transitional state, just re-queue and return.
		 * The queue will be serviced when we get to a stable state.
		 */
		if (fnic->state != FNIC_IN_FC_MODE &&
		    fnic->state != FNIC_IN_ETH_MODE) {
			skb_queue_head(&fnic->fip_frame_queue, skb);
			spin_unlock_irqrestore(&fnic->fnic_lock, flags);
			return;
		}
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
		eh = (struct ethhdr *)skb->data;
		if (eh->h_proto == htons(ETH_P_FIP)) {
			skb_pull(skb, sizeof(*eh));
			if (fnic_fcoe_handle_fip_frame(fnic, skb) <= 0) {
				dev_kfree_skb(skb);
				continue;
			}
			/*
			 * If there's FLOGI rejects - clear all
			 * fcf's & restart from scratch
			 */
			if (is_fnic_fip_flogi_reject(&fnic->ctlr, skb)) {
				atomic64_inc(
					&fnic_stats->vlan_stats.flogi_rejects);
				shost_printk(KERN_INFO, fnic->lport->host,
					  "Trigger a Link down - VLAN Disc\n");
				fcoe_ctlr_link_down(&fnic->ctlr);
				/* start FCoE VLAN discovery */
				fnic_fcoe_send_vlan_req(fnic);
				dev_kfree_skb(skb);
				continue;
			}
			fcoe_ctlr_recv(&fnic->ctlr, skb);
			continue;
		}
	}
}

/**
 * fnic_import_rq_eth_pkt() - handle received FCoE or FIP frame.
 * @fnic:	fnic instance.
 * @skb:	Ethernet Frame.
 */
static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb)
{
	struct fc_frame *fp;
	struct ethhdr *eh;
	struct fcoe_hdr *fcoe_hdr;
	struct fcoe_crc_eof *ft;

	/*
	 * Undo VLAN encapsulation if present.
	 */
	eh = (struct ethhdr *)skb->data;
	if (eh->h_proto == htons(ETH_P_8021Q)) {
		memmove((u8 *)eh + VLAN_HLEN, eh, ETH_ALEN * 2);
		eh = skb_pull(skb, VLAN_HLEN);
		skb_reset_mac_header(skb);
	}
	if (eh->h_proto == htons(ETH_P_FIP)) {
		if (!(fnic->config.flags & VFCF_FIP_CAPABLE)) {
			printk(KERN_ERR "Dropped FIP frame, as firmware "
					"uses non-FIP mode, Enable FIP "
					"using UCSM\n");
			goto drop;
		}
		if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
			FNIC_FC_RECV|0x80, (char *)skb->data, skb->len)) != 0) {
			printk(KERN_ERR "fnic ctlr frame trace error!!!");
		}
		skb_queue_tail(&fnic->fip_frame_queue, skb);
		queue_work(fnic_fip_queue, &fnic->fip_frame_work);
		return 1;		/* let caller know packet was used */
	}
	if (eh->h_proto != htons(ETH_P_FCOE))
		goto drop;
	skb_set_network_header(skb, sizeof(*eh));
	skb_pull(skb, sizeof(*eh));

	fcoe_hdr = (struct fcoe_hdr *)skb->data;
	if (FC_FCOE_DECAPS_VER(fcoe_hdr) != FC_FCOE_VER)
		goto drop;

	fp = (struct fc_frame *)skb;
	fc_frame_init(fp);
	fr_sof(fp) = fcoe_hdr->fcoe_sof;
	skb_pull(skb, sizeof(struct fcoe_hdr));
	skb_reset_transport_header(skb);

	ft = (struct fcoe_crc_eof *)(skb->data + skb->len - sizeof(*ft));
	fr_eof(fp) = ft->fcoe_eof;
	skb_trim(skb, skb->len - sizeof(*ft));
	return 0;
drop:
	dev_kfree_skb_irq(skb);
	return -1;
}

/**
 * fnic_update_mac_locked() - set data MAC address and filters.
 * @fnic:	fnic instance.
 * @new:	newly-assigned FCoE MAC address.
 *
 * Called with the fnic lock held.
 */
void fnic_update_mac_locked(struct fnic *fnic, u8 *new)
{
	u8 *ctl = fnic->ctlr.ctl_src_addr;
	u8 *data = fnic->data_src_addr;

	if (is_zero_ether_addr(new))
		new = ctl;
	if (ether_addr_equal(data, new))
		return;
	FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "update_mac %pM\n", new);
	if (!is_zero_ether_addr(data) && !ether_addr_equal(data, ctl))
		vnic_dev_del_addr(fnic->vdev, data);
	memcpy(data, new, ETH_ALEN);
	if (!ether_addr_equal(new, ctl))
		vnic_dev_add_addr(fnic->vdev, new);
}

/**
 * fnic_update_mac() - set data MAC address and filters.
 * @lport:	local port.
 * @new:	newly-assigned FCoE MAC address.
 */
void fnic_update_mac(struct fc_lport *lport, u8 *new)
{
	struct fnic *fnic = lport_priv(lport);

	spin_lock_irq(&fnic->fnic_lock);
	fnic_update_mac_locked(fnic, new);
	spin_unlock_irq(&fnic->fnic_lock);
}

/**
 * fnic_set_port_id() - set the port_ID after successful FLOGI.
 * @lport:	local port.
 * @port_id:	assigned FC_ID.
 * @fp:		received frame containing the FLOGI accept or NULL.
 *
 * This is called from libfc when a new FC_ID has been assigned.
 * This causes us to reset the firmware to FC_MODE and setup the new MAC
 * address and FC_ID.
 *
 * It is also called with FC_ID 0 when we're logged off.
 *
 * If the FC_ID is due to point-to-point, fp may be NULL.
 */
void fnic_set_port_id(struct fc_lport *lport, u32 port_id, struct fc_frame *fp)
{
	struct fnic *fnic = lport_priv(lport);
	u8 *mac;
	int ret;

	FNIC_FCS_DBG(KERN_DEBUG, lport->host, "set port_id %x fp %p\n",
		     port_id, fp);

	/*
	 * If we're clearing the FC_ID, change to use the ctl_src_addr.
	 * Set ethernet mode to send FLOGI.
	 */
	if (!port_id) {
		fnic_update_mac(lport, fnic->ctlr.ctl_src_addr);
		fnic_set_eth_mode(fnic);
		return;
	}

	if (fp) {
		mac = fr_cb(fp)->granted_mac;
		if (is_zero_ether_addr(mac)) {
			/* non-FIP - FLOGI already accepted - ignore return */
			fcoe_ctlr_recv_flogi(&fnic->ctlr, lport, fp);
		}
		fnic_update_mac(lport, mac);
	}

	/* Change state to reflect transition to FC mode */
	spin_lock_irq(&fnic->fnic_lock);
	if (fnic->state == FNIC_IN_ETH_MODE || fnic->state == FNIC_IN_FC_MODE)
		fnic->state = FNIC_IN_ETH_TRANS_FC_MODE;
	else {
		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
			     "Unexpected fnic state %s while"
			     " processing flogi resp\n",
			     fnic_state_to_str(fnic->state));
		spin_unlock_irq(&fnic->fnic_lock);
		return;
	}
	spin_unlock_irq(&fnic->fnic_lock);

	/*
	 * Send FLOGI registration to firmware to set up FC mode.
	 * The new address will be set up when registration completes.
	 */
	ret = fnic_flogi_reg_handler(fnic, port_id);

	if (ret < 0) {
		spin_lock_irq(&fnic->fnic_lock);
		if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE)
			fnic->state = FNIC_IN_ETH_MODE;
		spin_unlock_irq(&fnic->fnic_lock);
	}
}

static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
				    *cq_desc, struct vnic_rq_buf *buf,
				    int skipped __attribute__((unused)),
				    void *opaque)
{
	struct fnic *fnic = vnic_dev_priv(rq->vdev);
	struct sk_buff *skb;
	struct fc_frame *fp;
	struct fnic_stats *fnic_stats = &fnic->fnic_stats;
	u8 type, color, eop, sop, ingress_port, vlan_stripped;
	u8 fcoe = 0, fcoe_sof, fcoe_eof;
	u8 fcoe_fc_crc_ok = 1, fcoe_enc_error = 0;
	u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok;
	u8 ipv6, ipv4, ipv4_fragment, rss_type, csum_not_calc;
	u8 fcs_ok = 1, packet_error = 0;
	u16 q_number, completed_index, bytes_written = 0, vlan, checksum;
	u32 rss_hash;
	u16 exchange_id, tmpl;
	u8 sof = 0;
	u8 eof = 0;
	u32 fcp_bytes_written = 0;
	unsigned long flags;

	dma_unmap_single(&fnic->pdev->dev, buf->dma_addr, buf->len,
			 DMA_FROM_DEVICE);
	skb = buf->os_buf;
	fp = (struct fc_frame *)skb;
	buf->os_buf = NULL;

	cq_desc_dec(cq_desc, &type, &color, &q_number, &completed_index);
	if (type == CQ_DESC_TYPE_RQ_FCP) {
		cq_fcp_rq_desc_dec((struct cq_fcp_rq_desc *)cq_desc,
				   &type, &color, &q_number, &completed_index,
				   &eop, &sop, &fcoe_fc_crc_ok, &exchange_id,
				   &tmpl, &fcp_bytes_written, &sof, &eof,
				   &ingress_port, &packet_error,
				   &fcoe_enc_error, &fcs_ok, &vlan_stripped,
				   &vlan);
		skb_trim(skb, fcp_bytes_written);
		fr_sof(fp) = sof;
		fr_eof(fp) = eof;

	} else if (type == CQ_DESC_TYPE_RQ_ENET) {
		cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc,
				    &type, &color, &q_number, &completed_index,
				    &ingress_port, &fcoe, &eop, &sop,
				    &rss_type, &csum_not_calc, &rss_hash,
				    &bytes_written, &packet_error,
				    &vlan_stripped, &vlan, &checksum,
				    &fcoe_sof, &fcoe_fc_crc_ok,
				    &fcoe_enc_error, &fcoe_eof,
				    &tcp_udp_csum_ok, &udp, &tcp,
				    &ipv4_csum_ok, &ipv6, &ipv4,
				    &ipv4_fragment, &fcs_ok);
		skb_trim(skb, bytes_written);
		if (!fcs_ok) {
			atomic64_inc(&fnic_stats->misc_stats.frame_errors);
			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
				     "fcs error.  dropping packet.\n");
			goto drop;
		}
		if (fnic_import_rq_eth_pkt(fnic, skb))
			return;

	} else {
		/* wrong CQ type*/
		shost_printk(KERN_ERR, fnic->lport->host,
			     "fnic rq_cmpl wrong cq type x%x\n", type);
		goto drop;
	}

	if (!fcs_ok || packet_error || !fcoe_fc_crc_ok || fcoe_enc_error) {
		atomic64_inc(&fnic_stats->misc_stats.frame_errors);
		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
			     "fnic rq_cmpl fcoe x%x fcsok x%x"
			     " pkterr x%x fcoe_fc_crc_ok x%x, fcoe_enc_err"
			     " x%x\n",
			     fcoe, fcs_ok, packet_error,
			     fcoe_fc_crc_ok, fcoe_enc_error);
		goto drop;
	}

	spin_lock_irqsave(&fnic->fnic_lock, flags);
	if (fnic->stop_rx_link_events) {
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
		goto drop;
	}
	fr_dev(fp) = fnic->lport;
	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
	if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_RECV,
					(char *)skb->data, skb->len)) != 0) {
		printk(KERN_ERR "fnic ctlr frame trace error!!!");
	}

	skb_queue_tail(&fnic->frame_queue, skb);
	queue_work(fnic_event_queue, &fnic->frame_work);

	return;
drop:
	dev_kfree_skb_irq(skb);
}

static int fnic_rq_cmpl_handler_cont(struct vnic_dev *vdev,
				     struct cq_desc *cq_desc, u8 type,
				     u16 q_number, u16 completed_index,
				     void *opaque)
{
	struct fnic *fnic = vnic_dev_priv(vdev);

	vnic_rq_service(&fnic->rq[q_number], cq_desc, completed_index,
			VNIC_RQ_RETURN_DESC, fnic_rq_cmpl_frame_recv,
			NULL);
	return 0;
}

int fnic_rq_cmpl_handler(struct fnic *fnic, int rq_work_to_do)
{
	unsigned int tot_rq_work_done = 0, cur_work_done;
	unsigned int i;
	int err;

	for (i = 0; i < fnic->rq_count; i++) {
		cur_work_done = vnic_cq_service(&fnic->cq[i], rq_work_to_do,
						fnic_rq_cmpl_handler_cont,
						NULL);
		if (cur_work_done) {
			err = vnic_rq_fill(&fnic->rq[i], fnic_alloc_rq_frame);
			if (err)
				shost_printk(KERN_ERR, fnic->lport->host,
					     "fnic_alloc_rq_frame can't alloc"
					     " frame\n");
		}
		tot_rq_work_done += cur_work_done;
	}

	return tot_rq_work_done;
}

/*
 * This function is called once at init time to allocate and fill RQ
 * buffers. Subsequently, it is called in the interrupt context after RQ
 * buffer processing to replenish the buffers in the RQ
 */
int fnic_alloc_rq_frame(struct vnic_rq *rq)
{
	struct fnic *fnic = vnic_dev_priv(rq->vdev);
	struct sk_buff *skb;
	u16 len;
	dma_addr_t pa;
	int r;

	len = FC_FRAME_HEADROOM + FC_MAX_FRAME + FC_FRAME_TAILROOM;
	skb = dev_alloc_skb(len);
	if (!skb) {
		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
			     "Unable to allocate RQ sk_buff\n");
		return -ENOMEM;
	}
	skb_reset_mac_header(skb);
	skb_reset_transport_header(skb);
	skb_reset_network_header(skb);
	skb_put(skb, len);
	pa = dma_map_single(&fnic->pdev->dev, skb->data, len, DMA_FROM_DEVICE);
	if (dma_mapping_error(&fnic->pdev->dev, pa)) {
		r = -ENOMEM;
		printk(KERN_ERR "PCI mapping failed with error %d\n", r);
		goto free_skb;
	}

	fnic_queue_rq_desc(rq, skb, pa, len);
	return 0;

free_skb:
	kfree_skb(skb);
	return r;
}

void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
{
	struct fc_frame *fp = buf->os_buf;
	struct fnic *fnic = vnic_dev_priv(rq->vdev);

	dma_unmap_single(&fnic->pdev->dev, buf->dma_addr, buf->len,
			 DMA_FROM_DEVICE);

	dev_kfree_skb(fp_skb(fp));
	buf->os_buf = NULL;
}

/**
 * fnic_eth_send() - Send Ethernet frame.
 * @fip:	fcoe_ctlr instance.
 * @skb:	Ethernet Frame, FIP, without VLAN encapsulation.
 */
void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
	struct fnic *fnic = fnic_from_ctlr(fip);
	struct vnic_wq *wq = &fnic->wq[0];
	dma_addr_t pa;
	struct ethhdr *eth_hdr;
	struct vlan_ethhdr *vlan_hdr;
	unsigned long flags;

	if (!fnic->vlan_hw_insert) {
		eth_hdr = (struct ethhdr *)skb_mac_header(skb);
		vlan_hdr = skb_push(skb, sizeof(*vlan_hdr) - sizeof(*eth_hdr));
		memcpy(vlan_hdr, eth_hdr, 2 * ETH_ALEN);
		vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
		vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
		vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
		if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
			FNIC_FC_SEND|0x80, (char *)eth_hdr, skb->len)) != 0) {
			printk(KERN_ERR "fnic ctlr frame trace error!!!");
		}
	} else {
		if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
			FNIC_FC_SEND|0x80, (char *)skb->data, skb->len)) != 0) {
			printk(KERN_ERR "fnic ctlr frame trace error!!!");
		}
	}

	pa = dma_map_single(&fnic->pdev->dev, skb->data, skb->len,
			DMA_TO_DEVICE);
	if (dma_mapping_error(&fnic->pdev->dev, pa)) {
		printk(KERN_ERR "DMA mapping failed\n");
		goto free_skb;
	}

	spin_lock_irqsave(&fnic->wq_lock[0], flags);
	if (!vnic_wq_desc_avail(wq))
		goto irq_restore;

	fnic_queue_wq_eth_desc(wq, skb, pa, skb->len,
			       0 /* hw inserts cos value */,
			       fnic->vlan_id, 1);
	spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
	return;

irq_restore:
	spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
	dma_unmap_single(&fnic->pdev->dev, pa, skb->len, DMA_TO_DEVICE);
free_skb:
	kfree_skb(skb);
}

/*
 * Send FC frame.
 */
static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
{
	struct vnic_wq *wq = &fnic->wq[0];
	struct sk_buff *skb;
	dma_addr_t pa;
	struct ethhdr *eth_hdr;
	struct vlan_ethhdr *vlan_hdr;
	struct fcoe_hdr *fcoe_hdr;
	struct fc_frame_header *fh;
	u32 tot_len, eth_hdr_len;
	int ret = 0;
	unsigned long flags;

	fh = fc_frame_header_get(fp);
	skb = fp_skb(fp);

	if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
	    fcoe_ctlr_els_send(&fnic->ctlr, fnic->lport, skb))
		return 0;

	if (!fnic->vlan_hw_insert) {
		eth_hdr_len = sizeof(*vlan_hdr) + sizeof(*fcoe_hdr);
		vlan_hdr = skb_push(skb, eth_hdr_len);
		eth_hdr = (struct ethhdr *)vlan_hdr;
		vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
		vlan_hdr->h_vlan_encapsulated_proto = htons(ETH_P_FCOE);
		vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
		fcoe_hdr = (struct fcoe_hdr *)(vlan_hdr + 1);
	} else {
		eth_hdr_len = sizeof(*eth_hdr) + sizeof(*fcoe_hdr);
		eth_hdr = skb_push(skb, eth_hdr_len);
		eth_hdr->h_proto = htons(ETH_P_FCOE);
		fcoe_hdr = (struct fcoe_hdr *)(eth_hdr + 1);
	}

	if (fnic->ctlr.map_dest)
		fc_fcoe_set_mac(eth_hdr->h_dest, fh->fh_d_id);
	else
		memcpy(eth_hdr->h_dest, fnic->ctlr.dest_addr, ETH_ALEN);
	memcpy(eth_hdr->h_source, fnic->data_src_addr, ETH_ALEN);

	tot_len = skb->len;
	BUG_ON(tot_len % 4);

	memset(fcoe_hdr, 0, sizeof(*fcoe_hdr));
	fcoe_hdr->fcoe_sof = fr_sof(fp);
	if (FC_FCOE_VER)
		FC_FCOE_ENCAPS_VER(fcoe_hdr, FC_FCOE_VER);

	pa = dma_map_single(&fnic->pdev->dev, eth_hdr, tot_len, DMA_TO_DEVICE);
	if (dma_mapping_error(&fnic->pdev->dev, pa)) {
		ret = -ENOMEM;
		printk(KERN_ERR "DMA map failed with error %d\n", ret);
		goto free_skb_on_err;
	}

	if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_SEND,
				(char *)eth_hdr, tot_len)) != 0) {
		printk(KERN_ERR "fnic ctlr frame trace error!!!");
	}

	spin_lock_irqsave(&fnic->wq_lock[0], flags);

	if (!vnic_wq_desc_avail(wq)) {
		dma_unmap_single(&fnic->pdev->dev, pa, tot_len, DMA_TO_DEVICE);
		ret = -1;
		goto irq_restore;
	}

	fnic_queue_wq_desc(wq, skb, pa, tot_len, fr_eof(fp),
			   0 /* hw inserts cos value */,
			   fnic->vlan_id, 1, 1, 1);

irq_restore:
	spin_unlock_irqrestore(&fnic->wq_lock[0], flags);

free_skb_on_err:
	if (ret)
		dev_kfree_skb_any(fp_skb(fp));

	return ret;
}

/*
 * fnic_send
 * Routine to send a raw frame
 */
int fnic_send(struct fc_lport *lp, struct fc_frame *fp)
{
	struct fnic *fnic = lport_priv(lp);
	unsigned long flags;

	if (fnic->in_remove) {
		dev_kfree_skb(fp_skb(fp));
		return -1;
	}

	/*
	 * Queue frame if in a transitional state.
	 * This occurs while registering the Port_ID / MAC address after FLOGI.
	 */
	spin_lock_irqsave(&fnic->fnic_lock, flags);
	if (fnic->state != FNIC_IN_FC_MODE && fnic->state != FNIC_IN_ETH_MODE) {
		skb_queue_tail(&fnic->tx_queue, fp_skb(fp));
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
		return 0;
	}
	spin_unlock_irqrestore(&fnic->fnic_lock, flags);

	return fnic_send_frame(fnic, fp);
}

/**
 * fnic_flush_tx() - send queued frames.
 * @fnic: fnic device
 *
 * Send frames that were waiting to go out in FC or Ethernet mode.
 * Whenever changing modes we purge queued frames, so these frames should
 * be queued for the stable mode that we're in, either FC or Ethernet.
 *
 * Called without fnic_lock held.
 */
void fnic_flush_tx(struct fnic *fnic)
{
	struct sk_buff *skb;
	struct fc_frame *fp;

	while ((skb = skb_dequeue(&fnic->tx_queue))) {
		fp = (struct fc_frame *)skb;
		fnic_send_frame(fnic, fp);
	}
}

/**
 * fnic_set_eth_mode() - put fnic into ethernet mode.
 * @fnic: fnic device
 *
 * Called without fnic lock held.
 */
static void fnic_set_eth_mode(struct fnic *fnic)
{
	unsigned long flags;
	enum fnic_state old_state;
	int ret;

	spin_lock_irqsave(&fnic->fnic_lock, flags);
again:
	old_state = fnic->state;
	switch (old_state) {
	case FNIC_IN_FC_MODE:
	case FNIC_IN_ETH_TRANS_FC_MODE:
	default:
		fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);

		ret = fnic_fw_reset_handler(fnic);

		spin_lock_irqsave(&fnic->fnic_lock, flags);
		if (fnic->state != FNIC_IN_FC_TRANS_ETH_MODE)
			goto again;
		if (ret)
			fnic->state = old_state;
		break;

	case FNIC_IN_FC_TRANS_ETH_MODE:
	case FNIC_IN_ETH_MODE:
		break;
	}
	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
}

static void fnic_wq_complete_frame_send(struct vnic_wq *wq,
					struct cq_desc *cq_desc,
					struct vnic_wq_buf *buf, void *opaque)
{
	struct sk_buff *skb = buf->os_buf;
	struct fc_frame *fp = (struct fc_frame *)skb;
	struct fnic *fnic = vnic_dev_priv(wq->vdev);

	dma_unmap_single(&fnic->pdev->dev, buf->dma_addr, buf->len,
			 DMA_TO_DEVICE);
	dev_kfree_skb_irq(fp_skb(fp));
	buf->os_buf = NULL;
}

static int fnic_wq_cmpl_handler_cont(struct vnic_dev *vdev,
				     struct cq_desc *cq_desc, u8 type,
				     u16 q_number, u16 completed_index,
				     void *opaque)
{
	struct fnic *fnic = vnic_dev_priv(vdev);
	unsigned long flags;

	spin_lock_irqsave(&fnic->wq_lock[q_number], flags);
	vnic_wq_service(&fnic->wq[q_number], cq_desc, completed_index,
			fnic_wq_complete_frame_send, NULL);
	spin_unlock_irqrestore(&fnic->wq_lock[q_number], flags);

	return 0;
}

int fnic_wq_cmpl_handler(struct fnic *fnic, int work_to_do)
{
	unsigned int wq_work_done = 0;
	unsigned int i;

	for (i = 0; i < fnic->raw_wq_count; i++) {
		wq_work_done  += vnic_cq_service(&fnic->cq[fnic->rq_count+i],
						 work_to_do,
						 fnic_wq_cmpl_handler_cont,
						 NULL);
	}

	return wq_work_done;
}


void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf)
{
	struct fc_frame *fp = buf->os_buf;
	struct fnic *fnic = vnic_dev_priv(wq->vdev);

	dma_unmap_single(&fnic->pdev->dev, buf->dma_addr, buf->len,
			 DMA_TO_DEVICE);

	dev_kfree_skb(fp_skb(fp));
	buf->os_buf = NULL;
}

void fnic_fcoe_reset_vlans(struct fnic *fnic)
{
	unsigned long flags;
	struct fcoe_vlan *vlan;
	struct fcoe_vlan *next;

	/*
	 * indicate a link down to fcoe so that all fcf's are free'd
	 * might not be required since we did this before sending vlan
	 * discovery request
	 */
	spin_lock_irqsave(&fnic->vlans_lock, flags);
	if (!list_empty(&fnic->vlans)) {
		list_for_each_entry_safe(vlan, next, &fnic->vlans, list) {
			list_del(&vlan->list);
			kfree(vlan);
		}
	}
	spin_unlock_irqrestore(&fnic->vlans_lock, flags);
}

void fnic_handle_fip_timer(struct fnic *fnic)
{
	unsigned long flags;
	struct fcoe_vlan *vlan;
	struct fnic_stats *fnic_stats = &fnic->fnic_stats;
	u64 sol_time;

	spin_lock_irqsave(&fnic->fnic_lock, flags);
	if (fnic->stop_rx_link_events) {
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
		return;
	}
	spin_unlock_irqrestore(&fnic->fnic_lock, flags);

	if (fnic->ctlr.mode == FIP_MODE_NON_FIP)
		return;

	spin_lock_irqsave(&fnic->vlans_lock, flags);
	if (list_empty(&fnic->vlans)) {
		spin_unlock_irqrestore(&fnic->vlans_lock, flags);
		/* no vlans available, try again */
		if (printk_ratelimit())
			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
				  "Start VLAN Discovery\n");
		fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC);
		return;
	}

	vlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, list);
	FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
		  "fip_timer: vlan %d state %d sol_count %d\n",
		  vlan->vid, vlan->state, vlan->sol_count);
	switch (vlan->state) {
	case FIP_VLAN_USED:
		FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
			  "FIP VLAN is selected for FC transaction\n");
		spin_unlock_irqrestore(&fnic->vlans_lock, flags);
		break;
	case FIP_VLAN_FAILED:
		spin_unlock_irqrestore(&fnic->vlans_lock, flags);
		/* if all vlans are in failed state, restart vlan disc */
		if (printk_ratelimit())
			FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
				  "Start VLAN Discovery\n");
		fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC);
		break;
	case FIP_VLAN_SENT:
		if (vlan->sol_count >= FCOE_CTLR_MAX_SOL) {
			/*
			 * no response on this vlan, remove  from the list.
			 * Try the next vlan
			 */
			FNIC_FCS_DBG(KERN_INFO, fnic->lport->host,
				  "Dequeue this VLAN ID %d from list\n",
				  vlan->vid);
			list_del(&vlan->list);
			kfree(vlan);
			vlan = NULL;
			if (list_empty(&fnic->vlans)) {
				/* we exhausted all vlans, restart vlan disc */
				spin_unlock_irqrestore(&fnic->vlans_lock,
							flags);
				FNIC_FCS_DBG(KERN_INFO, fnic->lport->host,
					  "fip_timer: vlan list empty, "
					  "trigger vlan disc\n");
				fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC);
				return;
			}
			/* check the next vlan */
			vlan = list_first_entry(&fnic->vlans, struct fcoe_vlan,
							list);
			fnic->set_vlan(fnic, vlan->vid);
			vlan->state = FIP_VLAN_SENT; /* sent now */
		}
		spin_unlock_irqrestore(&fnic->vlans_lock, flags);
		atomic64_inc(&fnic_stats->vlan_stats.sol_expiry_count);
		vlan->sol_count++;
		sol_time = jiffies + msecs_to_jiffies
					(FCOE_CTLR_START_DELAY);
		mod_timer(&fnic->fip_timer, round_jiffies(sol_time));
		break;
	}
}
