/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Driver
 * Copyright(c) 2013 - 2014 Intel Corporation.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * The full GNU General Public License is included in this distribution in
 * the file called "COPYING".
 *
 * Contact Information:
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 ******************************************************************************/


#include <linux/if_ether.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/fc/fc_fs.h>
#include <scsi/fc/fc_fip.h>
#include <scsi/fc/fc_fcoe.h>
#include <scsi/libfc.h>
#include <scsi/libfcoe.h>
#include <uapi/linux/dcbnl.h>

#include "i40e.h"
#include "i40e_fcoe.h"

/**
 * i40e_rx_is_fip - returns true if the rx packet type is FIP
 * @ptype: the packet type field from rx descriptor write-back
 **/
static inline bool i40e_rx_is_fip(u16 ptype)
{
	return ptype == I40E_RX_PTYPE_L2_FIP_PAY2;
}

/**
 * i40e_rx_is_fcoe - returns true if the rx packet type is FCoE
 * @ptype: the packet type field from rx descriptor write-back
 **/
static inline bool i40e_rx_is_fcoe(u16 ptype)
{
	return (ptype >= I40E_RX_PTYPE_L2_FCOE_PAY3) &&
	       (ptype <= I40E_RX_PTYPE_L2_FCOE_VFT_FCOTHER);
}

/**
 * i40e_fcoe_sof_is_class2 - returns true if this is a FC Class 2 SOF
 * @sof: the FCoE start of frame delimiter
 **/
static inline bool i40e_fcoe_sof_is_class2(u8 sof)
{
	return (sof == FC_SOF_I2) || (sof == FC_SOF_N2);
}

/**
 * i40e_fcoe_sof_is_class3 - returns true if this is a FC Class 3 SOF
 * @sof: the FCoE start of frame delimiter
 **/
static inline bool i40e_fcoe_sof_is_class3(u8 sof)
{
	return (sof == FC_SOF_I3) || (sof == FC_SOF_N3);
}

/**
 * i40e_fcoe_sof_is_supported - returns true if the FC SOF is supported by HW
 * @sof: the input SOF value from the frame
 **/
static inline bool i40e_fcoe_sof_is_supported(u8 sof)
{
	return i40e_fcoe_sof_is_class2(sof) ||
	       i40e_fcoe_sof_is_class3(sof);
}

/**
 * i40e_fcoe_fc_sof - pull the SOF from FCoE header in the frame
 * @skb: the frame whose EOF is to be pulled from
 **/
static inline int i40e_fcoe_fc_sof(struct sk_buff *skb, u8 *sof)
{
	*sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof;

	if (!i40e_fcoe_sof_is_supported(*sof))
		return -EINVAL;
	return 0;
}

/**
 * i40e_fcoe_eof_is_supported - returns true if the EOF is supported by HW
 * @eof:     the input EOF value from the frame
 **/
static inline bool i40e_fcoe_eof_is_supported(u8 eof)
{
	return (eof == FC_EOF_N) || (eof == FC_EOF_T) ||
	       (eof == FC_EOF_NI) || (eof == FC_EOF_A);
}

/**
 * i40e_fcoe_fc_eof - pull EOF from FCoE trailer in the frame
 * @skb: the frame whose EOF is to be pulled from
 **/
static inline int i40e_fcoe_fc_eof(struct sk_buff *skb, u8 *eof)
{
	/* the first byte of the last dword is EOF */
	skb_copy_bits(skb, skb->len - 4, eof, 1);

	if (!i40e_fcoe_eof_is_supported(*eof))
		return -EINVAL;
	return 0;
}

/**
 * i40e_fcoe_ctxt_eof - convert input FC EOF for descriptor programming
 * @eof: the input eof value from the frame
 *
 * The FC EOF is converted to the value understood by HW for descriptor
 * programming. Never call this w/o calling i40e_fcoe_eof_is_supported()
 * first.
 **/
static inline u32 i40e_fcoe_ctxt_eof(u8 eof)
{
	switch (eof) {
	case FC_EOF_N:
		return I40E_TX_DESC_CMD_L4T_EOFT_EOF_N;
	case FC_EOF_T:
		return I40E_TX_DESC_CMD_L4T_EOFT_EOF_T;
	case FC_EOF_NI:
		return I40E_TX_DESC_CMD_L4T_EOFT_EOF_NI;
	case FC_EOF_A:
		return I40E_TX_DESC_CMD_L4T_EOFT_EOF_A;
	default:
		/* FIXME: still returns 0 */
		pr_err("Unrecognized EOF %x\n", eof);
		return 0;
	}
}

/**
 * i40e_fcoe_xid_is_valid - returns true if the exchange id is valid
 * @xid: the exchange id
 **/
static inline bool i40e_fcoe_xid_is_valid(u16 xid)
{
	return (xid != FC_XID_UNKNOWN) && (xid < I40E_FCOE_DDP_MAX);
}

/**
 * i40e_fcoe_ddp_unmap - unmap the mapped sglist associated
 * @pf: pointer to pf
 * @ddp: sw DDP context
 *
 * Unmap the scatter-gather list associated with the given SW DDP context
 *
 * Returns: data length already ddp-ed in bytes
 *
 **/
static inline void i40e_fcoe_ddp_unmap(struct i40e_pf *pf,
				       struct i40e_fcoe_ddp *ddp)
{
	if (test_and_set_bit(__I40E_FCOE_DDP_UNMAPPED, &ddp->flags))
		return;

	if (ddp->sgl) {
		dma_unmap_sg(&pf->pdev->dev, ddp->sgl, ddp->sgc,
			     DMA_FROM_DEVICE);
		ddp->sgl = NULL;
		ddp->sgc = 0;
	}

	if (ddp->pool) {
		dma_pool_free(ddp->pool, ddp->udl, ddp->udp);
		ddp->pool = NULL;
	}
}

/**
 * i40e_fcoe_ddp_clear - clear the given SW DDP context
 * @ddp - SW DDP context
 **/
static inline void i40e_fcoe_ddp_clear(struct i40e_fcoe_ddp *ddp)
{
	memset(ddp, 0, sizeof(struct i40e_fcoe_ddp));
	ddp->xid = FC_XID_UNKNOWN;
	ddp->flags = __I40E_FCOE_DDP_NONE;
}

/**
 * i40e_fcoe_progid_is_fcoe - check if the prog_id is for FCoE
 * @id: the prog id for the programming status Rx descriptor write-back
 **/
static inline bool i40e_fcoe_progid_is_fcoe(u8 id)
{
	return (id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_PROG_STATUS) ||
	       (id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_INVL_STATUS);
}

/**
 * i40e_fcoe_fc_get_xid - get xid from the frame header
 * @fh: the fc frame header
 *
 * In case the incoming frame's exchange is originated from
 * the initiator, then received frame's exchange id is ANDed
 * with fc_cpu_mask bits to get the same cpu on which exchange
 * was originated, otherwise just use the current cpu.
 *
 * Returns ox_id if exchange originator, rx_id if responder
 **/
static inline u16 i40e_fcoe_fc_get_xid(struct fc_frame_header *fh)
{
	u32 f_ctl = ntoh24(fh->fh_f_ctl);

	return (f_ctl & FC_FC_EX_CTX) ?
		be16_to_cpu(fh->fh_ox_id) :
		be16_to_cpu(fh->fh_rx_id);
}

/**
 * i40e_fcoe_fc_frame_header - get fc frame header from skb
 * @skb: packet
 *
 * This checks if there is a VLAN header and returns the data
 * pointer to the start of the fc_frame_header.
 *
 * Returns pointer to the fc_frame_header
 **/
static inline struct fc_frame_header *i40e_fcoe_fc_frame_header(
	struct sk_buff *skb)
{
	void *fh = skb->data + sizeof(struct fcoe_hdr);

	if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q))
		fh += sizeof(struct vlan_hdr);

	return (struct fc_frame_header *)fh;
}

/**
 * i40e_fcoe_ddp_put - release the DDP context for a given exchange id
 * @netdev: the corresponding net_device
 * @xid: the exchange id that corresponding DDP context will be released
 *
 * This is the implementation of net_device_ops.ndo_fcoe_ddp_done
 * and it is expected to be called by ULD, i.e., FCP layer of libfc
 * to release the corresponding ddp context when the I/O is done.
 *
 * Returns : data length already ddp-ed in bytes
 **/
static int i40e_fcoe_ddp_put(struct net_device *netdev, u16 xid)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_pf *pf = np->vsi->back;
	struct i40e_fcoe *fcoe = &pf->fcoe;
	int len = 0;
	struct i40e_fcoe_ddp *ddp = &fcoe->ddp[xid];

	if (!fcoe || !ddp)
		goto out;

	if (test_bit(__I40E_FCOE_DDP_DONE, &ddp->flags))
		len = ddp->len;
	i40e_fcoe_ddp_unmap(pf, ddp);
out:
	return len;
}

/**
 * i40e_fcoe_sw_init - sets up the HW for FCoE
 * @pf: pointer to pf
 *
 * Returns 0 if FCoE is supported otherwise the error code
 **/
int i40e_init_pf_fcoe(struct i40e_pf *pf)
{
	struct i40e_hw *hw = &pf->hw;
	u32 val;

	pf->flags &= ~I40E_FLAG_FCOE_ENABLED;
	pf->num_fcoe_qps = 0;
	pf->fcoe_hmc_cntx_num = 0;
	pf->fcoe_hmc_filt_num = 0;

	if (!pf->hw.func_caps.fcoe) {
		dev_info(&pf->pdev->dev, "FCoE capability is disabled\n");
		return 0;
	}

	if (!pf->hw.func_caps.dcb) {
		dev_warn(&pf->pdev->dev,
			 "Hardware is not DCB capable not enabling FCoE.\n");
		return 0;
	}

	/* enable FCoE hash filter */
	val = rd32(hw, I40E_PFQF_HENA(1));
	val |= 1 << (I40E_FILTER_PCTYPE_FCOE_OX - 32);
	val |= 1 << (I40E_FILTER_PCTYPE_FCOE_RX - 32);
	val &= I40E_PFQF_HENA_PTYPE_ENA_MASK;
	wr32(hw, I40E_PFQF_HENA(1), val);

	/* enable flag */
	pf->flags |= I40E_FLAG_FCOE_ENABLED;
	pf->num_fcoe_qps = I40E_DEFAULT_FCOE;

	/* Reserve 4K DDP contexts and 20K filter size for FCoE */
	pf->fcoe_hmc_cntx_num = (1 << I40E_DMA_CNTX_SIZE_4K) *
				 I40E_DMA_CNTX_BASE_SIZE;
	pf->fcoe_hmc_filt_num = pf->fcoe_hmc_cntx_num +
				(1 << I40E_HASH_FILTER_SIZE_16K) *
				I40E_HASH_FILTER_BASE_SIZE;

	/* FCoE object: max 16K filter buckets and 4K DMA contexts */
	pf->filter_settings.fcoe_filt_num = I40E_HASH_FILTER_SIZE_16K;
	pf->filter_settings.fcoe_cntx_num = I40E_DMA_CNTX_SIZE_4K;

	/* Setup max frame with FCoE_MTU plus L2 overheads */
	val = rd32(hw, I40E_GLFCOE_RCTL);
	val &= ~I40E_GLFCOE_RCTL_MAX_SIZE_MASK;
	val |= ((FCOE_MTU + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
		 << I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT);
	wr32(hw, I40E_GLFCOE_RCTL, val);

	dev_info(&pf->pdev->dev, "FCoE is supported.\n");
	return 0;
}

/**
 * i40e_get_fcoe_tc_map - Return TC map for FCoE APP
 * @pf: pointer to pf
 *
 **/
u8 i40e_get_fcoe_tc_map(struct i40e_pf *pf)
{
	struct i40e_dcb_app_priority_table app;
	struct i40e_hw *hw = &pf->hw;
	u8 enabled_tc = 0;
	u8 tc, i;
	/* Get the FCoE APP TLV */
	struct i40e_dcbx_config *dcbcfg = &hw->local_dcbx_config;

	for (i = 0; i < dcbcfg->numapps; i++) {
		app = dcbcfg->app[i];
		if (app.selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
		    app.protocolid == ETH_P_FCOE) {
			tc = dcbcfg->etscfg.prioritytable[app.priority];
			enabled_tc |= (1 << tc);
			break;
		}
	}

	/* TC0 if there is no TC defined for FCoE APP TLV */
	enabled_tc = enabled_tc ? enabled_tc : 0x1;

	return enabled_tc;
}

/**
 * i40e_fcoe_vsi_init - prepares the VSI context for creating a FCoE VSI
 * @vsi: pointer to the associated VSI struct
 * @ctxt: pointer to the associated VSI context to be passed to HW
 *
 * Returns 0 on success or < 0 on error
 **/
int i40e_fcoe_vsi_init(struct i40e_vsi *vsi, struct i40e_vsi_context *ctxt)
{
	struct i40e_aqc_vsi_properties_data *info = &ctxt->info;
	struct i40e_pf *pf = vsi->back;
	struct i40e_hw *hw = &pf->hw;
	u8 enabled_tc = 0;

	if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) {
		dev_err(&pf->pdev->dev,
			"FCoE is not enabled for this device\n");
		return -EPERM;
	}

	/* initialize the hardware for FCoE */
	ctxt->pf_num = hw->pf_id;
	ctxt->vf_num = 0;
	ctxt->uplink_seid = vsi->uplink_seid;
	ctxt->connection_type = 0x1;
	ctxt->flags = I40E_AQ_VSI_TYPE_PF;

	/* FCoE VSI would need the following sections */
	info->valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID |
					    I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);

	/* FCoE VSI does not need these sections */
	info->valid_sections &= cpu_to_le16(~(I40E_AQ_VSI_PROP_SECURITY_VALID |
					    I40E_AQ_VSI_PROP_VLAN_VALID |
					    I40E_AQ_VSI_PROP_CAS_PV_VALID |
					    I40E_AQ_VSI_PROP_INGRESS_UP_VALID |
					    I40E_AQ_VSI_PROP_EGRESS_UP_VALID));

	enabled_tc = i40e_get_fcoe_tc_map(pf);
	i40e_vsi_setup_queue_map(vsi, ctxt, enabled_tc, true);

	/* set up queue option section: only enable FCoE */
	info->queueing_opt_flags = I40E_AQ_VSI_QUE_OPT_FCOE_ENA;

	return 0;
}

/**
 * i40e_fcoe_enable - this is the implementation of ndo_fcoe_enable,
 * indicating the upper FCoE protocol stack is ready to use FCoE
 * offload features.
 *
 * @netdev: pointer to the netdev that FCoE is created on
 *
 * Returns 0 on success
 *
 * in RTNL
 *
 **/
int i40e_fcoe_enable(struct net_device *netdev)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_pf *pf = vsi->back;
	struct i40e_fcoe *fcoe = &pf->fcoe;

	if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) {
		netdev_err(netdev, "HW does not support FCoE.\n");
		return -ENODEV;
	}

	if (vsi->type != I40E_VSI_FCOE) {
		netdev_err(netdev, "interface does not support FCoE.\n");
		return -EBUSY;
	}

	atomic_inc(&fcoe->refcnt);

	return 0;
}

/**
 * i40e_fcoe_disable- disables FCoE for upper FCoE protocol stack.
 * @dev: pointer to the netdev that FCoE is created on
 *
 * Returns 0 on success
 *
 **/
int i40e_fcoe_disable(struct net_device *netdev)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_pf *pf = vsi->back;
	struct i40e_fcoe *fcoe = &pf->fcoe;

	if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) {
		netdev_err(netdev, "device does not support FCoE\n");
		return -ENODEV;
	}
	if (vsi->type != I40E_VSI_FCOE)
		return -EBUSY;

	if (!atomic_dec_and_test(&fcoe->refcnt))
		return -EINVAL;

	netdev_info(netdev, "FCoE disabled\n");

	return 0;
}

/**
 * i40e_fcoe_dma_pool_free - free the per cpu pool for FCoE DDP
 * @fcoe: the FCoE sw object
 * @dev: the device that the pool is associated with
 * @cpu: the cpu for this pool
 *
 **/
static void i40e_fcoe_dma_pool_free(struct i40e_fcoe *fcoe,
				    struct device *dev,
				    unsigned int cpu)
{
	struct i40e_fcoe_ddp_pool *ddp_pool;

	ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu);
	if (!ddp_pool->pool) {
		dev_warn(dev, "DDP pool already freed for cpu %d\n", cpu);
		return;
	}
	dma_pool_destroy(ddp_pool->pool);
	ddp_pool->pool = NULL;
}

/**
 * i40e_fcoe_dma_pool_create - per cpu pool for FCoE DDP
 * @fcoe: the FCoE sw object
 * @dev: the device that the pool is associated with
 * @cpu: the cpu for this pool
 *
 * Returns 0 on successful or non zero on failure
 *
 **/
static int i40e_fcoe_dma_pool_create(struct i40e_fcoe *fcoe,
				     struct device *dev,
				     unsigned int cpu)
{
	struct i40e_fcoe_ddp_pool *ddp_pool;
	struct dma_pool *pool;
	char pool_name[32];

	ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu);
	if (ddp_pool && ddp_pool->pool) {
		dev_warn(dev, "DDP pool already allocated for cpu %d\n", cpu);
		return 0;
	}
	snprintf(pool_name, sizeof(pool_name), "i40e_fcoe_ddp_%d", cpu);
	pool = dma_pool_create(pool_name, dev, I40E_FCOE_DDP_PTR_MAX,
			       I40E_FCOE_DDP_PTR_ALIGN, PAGE_SIZE);
	if (!pool) {
		dev_err(dev, "dma_pool_create %s failed\n", pool_name);
		return -ENOMEM;
	}
	ddp_pool->pool = pool;
	return 0;
}

/**
 * i40e_fcoe_free_ddp_resources - release FCoE DDP resources
 * @vsi: the vsi FCoE is associated with
 *
 **/
void i40e_fcoe_free_ddp_resources(struct i40e_vsi *vsi)
{
	struct i40e_pf *pf = vsi->back;
	struct i40e_fcoe *fcoe = &pf->fcoe;
	int cpu, i;

	/* do nothing if not FCoE VSI */
	if (vsi->type != I40E_VSI_FCOE)
		return;

	/* do nothing if no DDP pools were allocated */
	if (!fcoe->ddp_pool)
		return;

	for (i = 0; i < I40E_FCOE_DDP_MAX; i++)
		i40e_fcoe_ddp_put(vsi->netdev, i);

	for_each_possible_cpu(cpu)
		i40e_fcoe_dma_pool_free(fcoe, &pf->pdev->dev, cpu);

	free_percpu(fcoe->ddp_pool);
	fcoe->ddp_pool = NULL;

	netdev_info(vsi->netdev, "VSI %d,%d FCoE DDP resources released\n",
		    vsi->id, vsi->seid);
}

/**
 * i40e_fcoe_setup_ddp_resources - allocate per cpu DDP resources
 * @vsi: the VSI FCoE is associated with
 *
 * Returns 0 on successful or non zero on failure
 *
 **/
int i40e_fcoe_setup_ddp_resources(struct i40e_vsi *vsi)
{
	struct i40e_pf *pf = vsi->back;
	struct device *dev = &pf->pdev->dev;
	struct i40e_fcoe *fcoe = &pf->fcoe;
	unsigned int cpu;
	int i;

	if (vsi->type != I40E_VSI_FCOE)
		return -ENODEV;

	/* do nothing if no DDP pools were allocated */
	if (fcoe->ddp_pool)
		return -EEXIST;

	/* allocate per CPU memory to track DDP pools */
	fcoe->ddp_pool = alloc_percpu(struct i40e_fcoe_ddp_pool);
	if (!fcoe->ddp_pool) {
		dev_err(&pf->pdev->dev, "failed to allocate percpu DDP\n");
		return -ENOMEM;
	}

	/* allocate pci pool for each cpu */
	for_each_possible_cpu(cpu) {
		if (!i40e_fcoe_dma_pool_create(fcoe, dev, cpu))
			continue;

		dev_err(dev, "failed to alloc DDP pool on cpu:%d\n", cpu);
		i40e_fcoe_free_ddp_resources(vsi);
		return -ENOMEM;
	}

	/* initialize the sw context */
	for (i = 0; i < I40E_FCOE_DDP_MAX; i++)
		i40e_fcoe_ddp_clear(&fcoe->ddp[i]);

	netdev_info(vsi->netdev, "VSI %d,%d FCoE DDP resources allocated\n",
		    vsi->id, vsi->seid);

	return 0;
}

/**
 * i40e_fcoe_handle_status - check the Programming Status for FCoE
 * @rx_ring: the Rx ring for this descriptor
 * @rx_desc: the Rx descriptor for Programming Status, not a packet descriptor.
 *
 * Check if this is the Rx Programming Status descriptor write-back for FCoE.
 * This is used to verify if the context/filter programming or invalidation
 * requested by SW to the HW is successful or not and take actions accordingly.
 **/
void i40e_fcoe_handle_status(struct i40e_ring *rx_ring,
			     union i40e_rx_desc *rx_desc, u8 prog_id)
{
	struct i40e_pf *pf = rx_ring->vsi->back;
	struct i40e_fcoe *fcoe = &pf->fcoe;
	struct i40e_fcoe_ddp *ddp;
	u32 error;
	u16 xid;
	u64 qw;

	/* we only care for FCoE here */
	if (!i40e_fcoe_progid_is_fcoe(prog_id))
		return;

	xid = le32_to_cpu(rx_desc->wb.qword0.hi_dword.fcoe_param) &
	      (I40E_FCOE_DDP_MAX - 1);

	if (!i40e_fcoe_xid_is_valid(xid))
		return;

	ddp = &fcoe->ddp[xid];
	WARN_ON(xid != ddp->xid);

	qw = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
	error = (qw & I40E_RX_PROG_STATUS_DESC_QW1_ERROR_MASK) >>
		I40E_RX_PROG_STATUS_DESC_QW1_ERROR_SHIFT;

	/* DDP context programming status: failure or success */
	if (prog_id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_PROG_STATUS) {
		if (I40E_RX_PROG_FCOE_ERROR_TBL_FULL(error)) {
			dev_err(&pf->pdev->dev, "xid %x ddp->xid %x TABLE FULL\n",
				xid, ddp->xid);
			ddp->prerr |= I40E_RX_PROG_FCOE_ERROR_TBL_FULL_BIT;
		}
		if (I40E_RX_PROG_FCOE_ERROR_CONFLICT(error)) {
			dev_err(&pf->pdev->dev, "xid %x ddp->xid %x CONFLICT\n",
				xid, ddp->xid);
			ddp->prerr |= I40E_RX_PROG_FCOE_ERROR_CONFLICT_BIT;
		}
	}

	/* DDP context invalidation status: failure or success */
	if (prog_id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_INVL_STATUS) {
		if (I40E_RX_PROG_FCOE_ERROR_INVLFAIL(error)) {
			dev_err(&pf->pdev->dev, "xid %x ddp->xid %x INVALIDATION FAILURE\n",
				xid, ddp->xid);
			ddp->prerr |= I40E_RX_PROG_FCOE_ERROR_INVLFAIL_BIT;
		}
		/* clear the flag so we can retry invalidation */
		clear_bit(__I40E_FCOE_DDP_ABORTED, &ddp->flags);
	}

	/* unmap DMA */
	i40e_fcoe_ddp_unmap(pf, ddp);
	i40e_fcoe_ddp_clear(ddp);
}

/**
 * i40e_fcoe_handle_offload - check ddp status and mark it done
 * @adapter: i40e adapter
 * @rx_desc: advanced rx descriptor
 * @skb: the skb holding the received data
 *
 * This checks ddp status.
 *
 * Returns : < 0 indicates an error or not a FCOE ddp, 0 indicates
 * not passing the skb to ULD, > 0 indicates is the length of data
 * being ddped.
 *
 **/
int i40e_fcoe_handle_offload(struct i40e_ring *rx_ring,
			     union i40e_rx_desc *rx_desc,
			     struct sk_buff *skb)
{
	struct i40e_pf *pf = rx_ring->vsi->back;
	struct i40e_fcoe *fcoe = &pf->fcoe;
	struct fc_frame_header *fh = NULL;
	struct i40e_fcoe_ddp *ddp = NULL;
	u32 status, fltstat;
	u32 error, fcerr;
	int rc = -EINVAL;
	u16 ptype;
	u16 xid;
	u64 qw;

	/* check this rxd is for programming status */
	qw = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
	/* packet descriptor, check packet type */
	ptype = (qw & I40E_RXD_QW1_PTYPE_MASK) >> I40E_RXD_QW1_PTYPE_SHIFT;
	if (!i40e_rx_is_fcoe(ptype))
		goto out_no_ddp;

	error = (qw & I40E_RXD_QW1_ERROR_MASK) >> I40E_RXD_QW1_ERROR_SHIFT;
	fcerr = (error >> I40E_RX_DESC_ERROR_L3L4E_SHIFT) &
		 I40E_RX_DESC_FCOE_ERROR_MASK;

	/* check stateless offload error */
	if (unlikely(fcerr == I40E_RX_DESC_ERROR_L3L4E_PROT)) {
		dev_err(&pf->pdev->dev, "Protocol Error\n");
		skb->ip_summed = CHECKSUM_NONE;
	} else {
		skb->ip_summed = CHECKSUM_UNNECESSARY;
	}

	/* check hw status on ddp */
	status = (qw & I40E_RXD_QW1_STATUS_MASK) >> I40E_RXD_QW1_STATUS_SHIFT;
	fltstat = (status >> I40E_RX_DESC_STATUS_FLTSTAT_SHIFT) &
		   I40E_RX_DESC_FLTSTAT_FCMASK;

	/* now we are ready to check DDP */
	fh = i40e_fcoe_fc_frame_header(skb);
	xid = i40e_fcoe_fc_get_xid(fh);
	if (!i40e_fcoe_xid_is_valid(xid))
		goto out_no_ddp;

	/* non DDP normal receive, return to the protocol stack */
	if (fltstat == I40E_RX_DESC_FLTSTAT_NOMTCH)
		goto out_no_ddp;

	/* do we have a sw ddp context setup ? */
	ddp = &fcoe->ddp[xid];
	if (!ddp->sgl)
		goto out_no_ddp;

	/* fetch xid from hw rxd wb, which should match up the sw ctxt */
	xid = le16_to_cpu(rx_desc->wb.qword0.lo_dword.mirr_fcoe.fcoe_ctx_id);
	if (ddp->xid != xid) {
		dev_err(&pf->pdev->dev, "xid 0x%x does not match ctx_xid 0x%x\n",
			ddp->xid, xid);
		goto out_put_ddp;
	}

	/* the same exchange has already errored out */
	if (ddp->fcerr) {
		dev_err(&pf->pdev->dev, "xid 0x%x fcerr 0x%x reported fcer 0x%x\n",
			xid, ddp->fcerr, fcerr);
		goto out_put_ddp;
	}

	/* fcoe param is valid by now with correct DDPed length */
	ddp->len = le32_to_cpu(rx_desc->wb.qword0.hi_dword.fcoe_param);
	ddp->fcerr = fcerr;
	/* header posting only, useful only for target mode and debugging */
	if (fltstat == I40E_RX_DESC_FLTSTAT_DDP) {
		/* For target mode, we get header of the last packet but it
		 * does not have the FCoE trailer field, i.e., CRC and EOF
		 * Ordered Set since they are offloaded by the HW, so fill
		 * it up correspondingly to allow the packet to pass through
		 * to the upper protocol stack.
		 */
		u32 f_ctl = ntoh24(fh->fh_f_ctl);

		if ((f_ctl & FC_FC_END_SEQ) &&
		    (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA)) {
			struct fcoe_crc_eof *crc = NULL;

			crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));
			crc->fcoe_eof = FC_EOF_T;
		} else {
			/* otherwise, drop the header only frame */
			rc = 0;
			goto out_no_ddp;
		}
	}

out_put_ddp:
	/* either we got RSP or we have an error, unmap DMA in both cases */
	i40e_fcoe_ddp_unmap(pf, ddp);
	if (ddp->len && !ddp->fcerr) {
		int pkts;

		rc = ddp->len;
		i40e_fcoe_ddp_clear(ddp);
		ddp->len = rc;
		pkts = DIV_ROUND_UP(rc, 2048);
		rx_ring->stats.bytes += rc;
		rx_ring->stats.packets += pkts;
		rx_ring->q_vector->rx.total_bytes += rc;
		rx_ring->q_vector->rx.total_packets += pkts;
		set_bit(__I40E_FCOE_DDP_DONE, &ddp->flags);
	}

out_no_ddp:
	return rc;
}

/**
 * i40e_fcoe_ddp_setup - called to set up ddp context
 * @netdev: the corresponding net_device
 * @xid: the exchange id requesting ddp
 * @sgl: the scatter-gather list for this request
 * @sgc: the number of scatter-gather items
 * @target_mode: indicates this is a DDP request for target
 *
 * Returns : 1 for success and 0 for no DDP on this I/O
 **/
static int i40e_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
			       struct scatterlist *sgl, unsigned int sgc,
			       int target_mode)
{
	static const unsigned int bufflen = I40E_FCOE_DDP_BUF_MIN;
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_fcoe_ddp_pool *ddp_pool;
	struct i40e_pf *pf = np->vsi->back;
	struct i40e_fcoe *fcoe = &pf->fcoe;
	unsigned int i, j, dmacount;
	struct i40e_fcoe_ddp *ddp;
	unsigned int firstoff = 0;
	unsigned int thisoff = 0;
	unsigned int thislen = 0;
	struct scatterlist *sg;
	dma_addr_t addr = 0;
	unsigned int len;

	if (xid >= I40E_FCOE_DDP_MAX) {
		dev_warn(&pf->pdev->dev, "xid=0x%x out-of-range\n", xid);
		return 0;
	}

	/* no DDP if we are already down or resetting */
	if (test_bit(__I40E_DOWN, &pf->state) ||
	    test_bit(__I40E_NEEDS_RESTART, &pf->state)) {
		dev_info(&pf->pdev->dev, "xid=0x%x device in reset/down\n",
			 xid);
		return 0;
	}

	ddp = &fcoe->ddp[xid];
	if (ddp->sgl) {
		dev_info(&pf->pdev->dev, "xid 0x%x w/ non-null sgl=%p nents=%d\n",
			 xid, ddp->sgl, ddp->sgc);
		return 0;
	}
	i40e_fcoe_ddp_clear(ddp);

	if (!fcoe->ddp_pool) {
		dev_info(&pf->pdev->dev, "No DDP pool, xid 0x%x\n", xid);
		return 0;
	}

	ddp_pool = per_cpu_ptr(fcoe->ddp_pool, get_cpu());
	if (!ddp_pool->pool) {
		dev_info(&pf->pdev->dev, "No percpu ddp pool, xid 0x%x\n", xid);
		goto out_noddp;
	}

	/* setup dma from scsi command sgl */
	dmacount = dma_map_sg(&pf->pdev->dev, sgl, sgc, DMA_FROM_DEVICE);
	if (dmacount == 0) {
		dev_info(&pf->pdev->dev, "dma_map_sg for sgl %p, sgc %d failed\n",
			 sgl, sgc);
		goto out_noddp_unmap;
	}

	/* alloc the udl from our ddp pool */
	ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_ATOMIC, &ddp->udp);
	if (!ddp->udl) {
		dev_info(&pf->pdev->dev,
			 "Failed allocated ddp context, xid 0x%x\n", xid);
		goto out_noddp_unmap;
	}

	j = 0;
	ddp->len = 0;
	for_each_sg(sgl, sg, dmacount, i) {
		addr = sg_dma_address(sg);
		len = sg_dma_len(sg);
		ddp->len += len;
		while (len) {
			/* max number of buffers allowed in one DDP context */
			if (j >= I40E_FCOE_DDP_BUFFCNT_MAX) {
				dev_info(&pf->pdev->dev,
					 "xid=%x:%d,%d,%d:addr=%llx not enough descriptors\n",
					 xid, i, j, dmacount, (u64)addr);
				goto out_noddp_free;
			}

			/* get the offset of length of current buffer */
			thisoff = addr & ((dma_addr_t)bufflen - 1);
			thislen = min_t(unsigned int, (bufflen - thisoff), len);
			/* all but the 1st buffer (j == 0)
			 * must be aligned on bufflen
			 */
			if ((j != 0) && (thisoff))
				goto out_noddp_free;

			/* all but the last buffer
			 * ((i == (dmacount - 1)) && (thislen == len))
			 * must end at bufflen
			 */
			if (((i != (dmacount - 1)) || (thislen != len)) &&
			    ((thislen + thisoff) != bufflen))
				goto out_noddp_free;

			ddp->udl[j] = (u64)(addr - thisoff);
			/* only the first buffer may have none-zero offset */
			if (j == 0)
				firstoff = thisoff;
			len -= thislen;
			addr += thislen;
			j++;
		}
	}
	/* only the last buffer may have non-full bufflen */
	ddp->lastsize = thisoff + thislen;
	ddp->firstoff = firstoff;
	ddp->list_len = j;
	ddp->pool = ddp_pool->pool;
	ddp->sgl = sgl;
	ddp->sgc = sgc;
	ddp->xid = xid;
	if (target_mode)
		set_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags);
	set_bit(__I40E_FCOE_DDP_INITALIZED, &ddp->flags);

	put_cpu();
	return 1; /* Success */

out_noddp_free:
	dma_pool_free(ddp->pool, ddp->udl, ddp->udp);
	i40e_fcoe_ddp_clear(ddp);

out_noddp_unmap:
	dma_unmap_sg(&pf->pdev->dev, sgl, sgc, DMA_FROM_DEVICE);
out_noddp:
	put_cpu();
	return 0;
}

/**
 * i40e_fcoe_ddp_get - called to set up ddp context in initiator mode
 * @netdev: the corresponding net_device
 * @xid: the exchange id requesting ddp
 * @sgl: the scatter-gather list for this request
 * @sgc: the number of scatter-gather items
 *
 * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup
 * and is expected to be called from ULD, e.g., FCP layer of libfc
 * to set up ddp for the corresponding xid of the given sglist for
 * the corresponding I/O.
 *
 * Returns : 1 for success and 0 for no ddp
 **/
static int i40e_fcoe_ddp_get(struct net_device *netdev, u16 xid,
			     struct scatterlist *sgl, unsigned int sgc)
{
	return i40e_fcoe_ddp_setup(netdev, xid, sgl, sgc, 0);
}

/**
 * i40e_fcoe_ddp_target - called to set up ddp context in target mode
 * @netdev: the corresponding net_device
 * @xid: the exchange id requesting ddp
 * @sgl: the scatter-gather list for this request
 * @sgc: the number of scatter-gather items
 *
 * This is the implementation of net_device_ops.ndo_fcoe_ddp_target
 * and is expected to be called from ULD, e.g., FCP layer of libfc
 * to set up ddp for the corresponding xid of the given sglist for
 * the corresponding I/O. The DDP in target mode is a write I/O request
 * from the initiator.
 *
 * Returns : 1 for success and 0 for no ddp
 **/
static int i40e_fcoe_ddp_target(struct net_device *netdev, u16 xid,
				struct scatterlist *sgl, unsigned int sgc)
{
	return i40e_fcoe_ddp_setup(netdev, xid, sgl, sgc, 1);
}

/**
 * i40e_fcoe_program_ddp - programs the HW DDP related descriptors
 * @tx_ring: transmit ring for this packet
 * @skb:     the packet to be sent out
 * @sof: the SOF to indicate class of service
 *
 * Determine if it is READ/WRITE command, and finds out if there is
 * a matching SW DDP context for this command. DDP is applicable
 * only in case of READ if initiator or WRITE in case of
 * responder (via checking XFER_RDY).
 *
 * Note: caller checks sof and ddp sw context
 *
 * Returns : none
 *
 **/
static void i40e_fcoe_program_ddp(struct i40e_ring *tx_ring,
				  struct sk_buff *skb,
				  struct i40e_fcoe_ddp *ddp, u8 sof)
{
	struct i40e_fcoe_filter_context_desc *filter_desc = NULL;
	struct i40e_fcoe_queue_context_desc *queue_desc = NULL;
	struct i40e_fcoe_ddp_context_desc *ddp_desc = NULL;
	struct i40e_pf *pf = tx_ring->vsi->back;
	u16 i = tx_ring->next_to_use;
	struct fc_frame_header *fh;
	u64 flags_rsvd_lanq = 0;
	bool target_mode;

	/* check if abort is still pending */
	if (test_bit(__I40E_FCOE_DDP_ABORTED, &ddp->flags)) {
		dev_warn(&pf->pdev->dev,
			 "DDP abort is still pending xid:%hx and ddp->flags:%lx:\n",
			 ddp->xid, ddp->flags);
		return;
	}

	/* set the flag to indicate this is programmed */
	if (test_and_set_bit(__I40E_FCOE_DDP_PROGRAMMED, &ddp->flags)) {
		dev_warn(&pf->pdev->dev,
			 "DDP is already programmed for xid:%hx and ddp->flags:%lx:\n",
			 ddp->xid, ddp->flags);
		return;
	}

	/* Prepare the DDP context descriptor */
	ddp_desc = I40E_DDP_CONTEXT_DESC(tx_ring, i);
	i++;
	if (i == tx_ring->count)
		i = 0;

	ddp_desc->type_cmd_foff_lsize =
				cpu_to_le64(I40E_TX_DESC_DTYPE_DDP_CTX	|
				((u64)I40E_FCOE_DDP_CTX_DESC_BSIZE_4K  <<
				I40E_FCOE_DDP_CTX_QW1_CMD_SHIFT)	|
				((u64)ddp->firstoff		       <<
				I40E_FCOE_DDP_CTX_QW1_FOFF_SHIFT)	|
				((u64)ddp->lastsize		       <<
				I40E_FCOE_DDP_CTX_QW1_LSIZE_SHIFT));
	ddp_desc->rsvd = cpu_to_le64(0);

	/* target mode needs last packet in the sequence  */
	target_mode = test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags);
	if (target_mode)
		ddp_desc->type_cmd_foff_lsize |=
			cpu_to_le64(I40E_FCOE_DDP_CTX_DESC_LASTSEQH);

	/* Prepare queue_context descriptor */
	queue_desc = I40E_QUEUE_CONTEXT_DESC(tx_ring, i++);
	if (i == tx_ring->count)
		i = 0;
	queue_desc->dmaindx_fbase = cpu_to_le64(ddp->xid | ((u64)ddp->udp));
	queue_desc->flen_tph = cpu_to_le64(ddp->list_len |
				((u64)(I40E_FCOE_QUEUE_CTX_DESC_TPHRDESC |
				I40E_FCOE_QUEUE_CTX_DESC_TPHDATA) <<
				I40E_FCOE_QUEUE_CTX_QW1_TPH_SHIFT));

	/* Prepare filter_context_desc */
	filter_desc = I40E_FILTER_CONTEXT_DESC(tx_ring, i);
	i++;
	if (i == tx_ring->count)
		i = 0;

	fh = (struct fc_frame_header *)skb_transport_header(skb);
	filter_desc->param = cpu_to_le32(ntohl(fh->fh_parm_offset));
	filter_desc->seqn = cpu_to_le16(ntohs(fh->fh_seq_cnt));
	filter_desc->rsvd_dmaindx = cpu_to_le16(ddp->xid <<
				I40E_FCOE_FILTER_CTX_QW0_DMAINDX_SHIFT);

	flags_rsvd_lanq = I40E_FCOE_FILTER_CTX_DESC_CTYP_DDP;
	flags_rsvd_lanq |= (u64)(target_mode ?
			I40E_FCOE_FILTER_CTX_DESC_ENODE_RSP :
			I40E_FCOE_FILTER_CTX_DESC_ENODE_INIT);

	flags_rsvd_lanq |= (u64)((sof == FC_SOF_I2 || sof == FC_SOF_N2) ?
			I40E_FCOE_FILTER_CTX_DESC_FC_CLASS2 :
			I40E_FCOE_FILTER_CTX_DESC_FC_CLASS3);

	flags_rsvd_lanq |= ((u64)skb->queue_mapping <<
				I40E_FCOE_FILTER_CTX_QW1_LANQINDX_SHIFT);
	filter_desc->flags_rsvd_lanq = cpu_to_le64(flags_rsvd_lanq);

	/* By this time, all offload related descriptors has been programmed */
	tx_ring->next_to_use = i;
}

/**
 * i40e_fcoe_invalidate_ddp - invalidates DDP in case of abort
 * @tx_ring: transmit ring for this packet
 * @skb: the packet associated w/ this DDP invalidation, i.e., ABTS
 * @ddp: the SW DDP context for this DDP
 *
 * Programs the Tx context descriptor to do DDP invalidation.
 **/
static void i40e_fcoe_invalidate_ddp(struct i40e_ring *tx_ring,
				     struct sk_buff *skb,
				     struct i40e_fcoe_ddp *ddp)
{
	struct i40e_tx_context_desc *context_desc;
	int i;

	if (test_and_set_bit(__I40E_FCOE_DDP_ABORTED, &ddp->flags))
		return;

	i = tx_ring->next_to_use;
	context_desc = I40E_TX_CTXTDESC(tx_ring, i);
	i++;
	if (i == tx_ring->count)
		i = 0;

	context_desc->tunneling_params = cpu_to_le32(0);
	context_desc->l2tag2 = cpu_to_le16(0);
	context_desc->rsvd = cpu_to_le16(0);
	context_desc->type_cmd_tso_mss = cpu_to_le64(
		I40E_TX_DESC_DTYPE_FCOE_CTX |
		(I40E_FCOE_TX_CTX_DESC_OPCODE_DDP_CTX_INVL <<
		I40E_TXD_CTX_QW1_CMD_SHIFT) |
		(I40E_FCOE_TX_CTX_DESC_OPCODE_SINGLE_SEND <<
		I40E_TXD_CTX_QW1_CMD_SHIFT));
	tx_ring->next_to_use = i;
}

/**
 * i40e_fcoe_handle_ddp - check we should setup or invalidate DDP
 * @tx_ring: transmit ring for this packet
 * @skb: the packet to be sent out
 * @sof: the SOF to indicate class of service
 *
 * Determine if it is ABTS/READ/XFER_RDY, and finds out if there is
 * a matching SW DDP context for this command. DDP is applicable
 * only in case of READ if initiator or WRITE in case of
 * responder (via checking XFER_RDY). In case this is an ABTS, send
 * just invalidate the context.
 **/
static void i40e_fcoe_handle_ddp(struct i40e_ring *tx_ring,
				 struct sk_buff *skb, u8 sof)
{
	struct i40e_pf *pf = tx_ring->vsi->back;
	struct i40e_fcoe *fcoe = &pf->fcoe;
	struct fc_frame_header *fh;
	struct i40e_fcoe_ddp *ddp;
	u32 f_ctl;
	u8 r_ctl;
	u16 xid;

	fh = (struct fc_frame_header *)skb_transport_header(skb);
	f_ctl = ntoh24(fh->fh_f_ctl);
	r_ctl = fh->fh_r_ctl;
	ddp = NULL;

	if ((r_ctl == FC_RCTL_DD_DATA_DESC) && (f_ctl & FC_FC_EX_CTX)) {
		/* exchange responder? if so, XFER_RDY for write */
		xid = ntohs(fh->fh_rx_id);
		if (i40e_fcoe_xid_is_valid(xid)) {
			ddp = &fcoe->ddp[xid];
			if ((ddp->xid == xid) &&
			    (test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags)))
				i40e_fcoe_program_ddp(tx_ring, skb, ddp, sof);
		}
	} else if (r_ctl == FC_RCTL_DD_UNSOL_CMD) {
		/* exchange originator, check READ cmd */
		xid = ntohs(fh->fh_ox_id);
		if (i40e_fcoe_xid_is_valid(xid)) {
			ddp = &fcoe->ddp[xid];
			if ((ddp->xid == xid) &&
			    (!test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags)))
				i40e_fcoe_program_ddp(tx_ring, skb, ddp, sof);
		}
	} else if (r_ctl == FC_RCTL_BA_ABTS) {
		/* exchange originator, check ABTS */
		xid = ntohs(fh->fh_ox_id);
		if (i40e_fcoe_xid_is_valid(xid)) {
			ddp = &fcoe->ddp[xid];
			if ((ddp->xid == xid) &&
			    (!test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags)))
				i40e_fcoe_invalidate_ddp(tx_ring, skb, ddp);
		}
	}
}

/**
 * i40e_fcoe_tso - set up FCoE TSO
 * @tx_ring:  ring to send buffer on
 * @skb:      send buffer
 * @tx_flags: collected send information
 * @hdr_len:  the tso header length
 * @sof: the SOF to indicate class of service
 *
 * Note must already have sof checked to be either class 2 or class 3 before
 * calling this function.
 *
 * Returns 1 to indicate sequence segmentation offload is properly setup
 * or returns 0 to indicate no tso is needed, otherwise returns error
 * code to drop the frame.
 **/
static int i40e_fcoe_tso(struct i40e_ring *tx_ring,
			 struct sk_buff *skb,
			 u32 tx_flags, u8 *hdr_len, u8 sof)
{
	struct i40e_tx_context_desc *context_desc;
	u32 cd_type, cd_cmd, cd_tso_len, cd_mss;
	struct fc_frame_header *fh;
	u64 cd_type_cmd_tso_mss;

	/* must match gso type as FCoE */
	if (!skb_is_gso(skb))
		return 0;

	/* is it the expected gso type for FCoE ?*/
	if (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE) {
		netdev_err(skb->dev,
			   "wrong gso type %d:expecting SKB_GSO_FCOE\n",
			   skb_shinfo(skb)->gso_type);
		return -EINVAL;
	}

	/* header and trailer are inserted by hw */
	*hdr_len = skb_transport_offset(skb) + sizeof(struct fc_frame_header) +
		   sizeof(struct fcoe_crc_eof);

	/* check sof to decide a class 2 or 3 TSO */
	if (likely(i40e_fcoe_sof_is_class3(sof)))
		cd_cmd = I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS3;
	else
		cd_cmd = I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS2;

	/* param field valid? */
	fh = (struct fc_frame_header *)skb_transport_header(skb);
	if (fh->fh_f_ctl[2] & FC_FC_REL_OFF)
		cd_cmd |= I40E_FCOE_TX_CTX_DESC_RELOFF;

	/* fill the field values */
	cd_type = I40E_TX_DESC_DTYPE_FCOE_CTX;
	cd_tso_len = skb->len - *hdr_len;
	cd_mss = skb_shinfo(skb)->gso_size;
	cd_type_cmd_tso_mss =
		((u64)cd_type  << I40E_TXD_CTX_QW1_DTYPE_SHIFT)     |
		((u64)cd_cmd     << I40E_TXD_CTX_QW1_CMD_SHIFT)	    |
		((u64)cd_tso_len << I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
		((u64)cd_mss     << I40E_TXD_CTX_QW1_MSS_SHIFT);

	/* grab the next descriptor */
	context_desc = I40E_TX_CTXTDESC(tx_ring, tx_ring->next_to_use);
	tx_ring->next_to_use++;
	if (tx_ring->next_to_use == tx_ring->count)
		tx_ring->next_to_use = 0;

	context_desc->tunneling_params = 0;
	context_desc->l2tag2 = cpu_to_le16((tx_flags & I40E_TX_FLAGS_VLAN_MASK)
					    >> I40E_TX_FLAGS_VLAN_SHIFT);
	context_desc->type_cmd_tso_mss = cpu_to_le64(cd_type_cmd_tso_mss);

	return 1;
}

/**
 * i40e_fcoe_tx_map - build the tx descriptor
 * @tx_ring:  ring to send buffer on
 * @skb:      send buffer
 * @first:    first buffer info buffer to use
 * @tx_flags: collected send information
 * @hdr_len:  ptr to the size of the packet header
 * @eof:      the frame eof value
 *
 * Note, for FCoE, sof and eof are already checked
 **/
static void i40e_fcoe_tx_map(struct i40e_ring *tx_ring,
			     struct sk_buff *skb,
			     struct i40e_tx_buffer *first,
			     u32 tx_flags, u8 hdr_len, u8 eof)
{
	u32 td_offset = 0;
	u32 td_cmd = 0;
	u32 maclen;

	/* insert CRC */
	td_cmd = I40E_TX_DESC_CMD_ICRC;

	/* setup MACLEN */
	maclen = skb_network_offset(skb);
	if (tx_flags & I40E_TX_FLAGS_SW_VLAN)
		maclen += sizeof(struct vlan_hdr);

	if (skb->protocol == htons(ETH_P_FCOE)) {
		/* for FCoE, maclen should exclude ether type */
		maclen -= 2;
		/* setup type as FCoE and EOF insertion */
		td_cmd |= (I40E_TX_DESC_CMD_FCOET | i40e_fcoe_ctxt_eof(eof));
		/* setup FCoELEN and FCLEN */
		td_offset |= ((((sizeof(struct fcoe_hdr) + 2) >> 2) <<
				I40E_TX_DESC_LENGTH_IPLEN_SHIFT) |
			      ((sizeof(struct fc_frame_header) >> 2) <<
				I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT));
		/* trim to exclude trailer */
		pskb_trim(skb, skb->len - sizeof(struct fcoe_crc_eof));
	}

	/* MACLEN is ether header length in words not bytes */
	td_offset |= (maclen >> 1) << I40E_TX_DESC_LENGTH_MACLEN_SHIFT;

	return i40e_tx_map(tx_ring, skb, first, tx_flags, hdr_len,
			   td_cmd, td_offset);
}

/**
 * i40e_fcoe_set_skb_header - adjust skb header point for FIP/FCoE/FC
 * @skb: the skb to be adjusted
 *
 * Returns true if this skb is a FCoE/FIP or VLAN carried FCoE/FIP and then
 * adjusts the skb header pointers correspondingly. Otherwise, returns false.
 **/
static inline int i40e_fcoe_set_skb_header(struct sk_buff *skb)
{
	__be16 protocol = skb->protocol;

	skb_reset_mac_header(skb);
	skb->mac_len = sizeof(struct ethhdr);
	if (protocol == htons(ETH_P_8021Q)) {
		struct vlan_ethhdr *veth = (struct vlan_ethhdr *)eth_hdr(skb);

		protocol = veth->h_vlan_encapsulated_proto;
		skb->mac_len += sizeof(struct vlan_hdr);
	}

	/* FCoE or FIP only */
	if ((protocol != htons(ETH_P_FIP)) &&
	    (protocol != htons(ETH_P_FCOE)))
		return -EINVAL;

	/* set header to L2 of FCoE/FIP */
	skb_set_network_header(skb, skb->mac_len);
	if (protocol == htons(ETH_P_FIP))
		return 0;

	/* set header to L3 of FC */
	skb_set_transport_header(skb, skb->mac_len + sizeof(struct fcoe_hdr));
	return 0;
}

/**
 * i40e_fcoe_xmit_frame - transmit buffer
 * @skb:     send buffer
 * @netdev:  the fcoe netdev
 *
 * Returns 0 if sent, else an error code
 **/
static netdev_tx_t i40e_fcoe_xmit_frame(struct sk_buff *skb,
					struct net_device *netdev)
{
	struct i40e_netdev_priv *np = netdev_priv(skb->dev);
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_ring *tx_ring = vsi->tx_rings[skb->queue_mapping];
	struct i40e_tx_buffer *first;
	u32 tx_flags = 0;
	u8 hdr_len = 0;
	u8 sof = 0;
	u8 eof = 0;
	int fso;

	if (i40e_fcoe_set_skb_header(skb))
		goto out_drop;

	if (!i40e_xmit_descriptor_count(skb, tx_ring))
		return NETDEV_TX_BUSY;

	/* prepare the xmit flags */
	if (i40e_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
		goto out_drop;

	/* record the location of the first descriptor for this packet */
	first = &tx_ring->tx_bi[tx_ring->next_to_use];

	/* FIP is a regular L2 traffic w/o offload */
	if (skb->protocol == htons(ETH_P_FIP))
		goto out_send;

	/* check sof and eof, only supports FC Class 2 or 3 */
	if (i40e_fcoe_fc_sof(skb, &sof) || i40e_fcoe_fc_eof(skb, &eof)) {
		netdev_err(netdev, "SOF/EOF error:%02x - %02x\n", sof, eof);
		goto out_drop;
	}

	/* always do FCCRC for FCoE */
	tx_flags |= I40E_TX_FLAGS_FCCRC;

	/* check we should do sequence offload */
	fso = i40e_fcoe_tso(tx_ring, skb, tx_flags, &hdr_len, sof);
	if (fso < 0)
		goto out_drop;
	else if (fso)
		tx_flags |= I40E_TX_FLAGS_FSO;
	else
		i40e_fcoe_handle_ddp(tx_ring, skb, sof);

out_send:
	/* send out the packet */
	i40e_fcoe_tx_map(tx_ring, skb, first, tx_flags, hdr_len, eof);

	i40e_maybe_stop_tx(tx_ring, DESC_NEEDED);
	return NETDEV_TX_OK;

out_drop:
	dev_kfree_skb_any(skb);
	return NETDEV_TX_OK;
}

/**
 * i40e_fcoe_change_mtu - NDO callback to change the Maximum Transfer Unit
 * @netdev: network interface device structure
 * @new_mtu: new value for maximum frame size
 *
 * Returns error as operation not permitted
 *
 **/
static int i40e_fcoe_change_mtu(struct net_device *netdev, int new_mtu)
{
	netdev_warn(netdev, "MTU change is not supported on FCoE interfaces\n");
	return -EPERM;
}

/**
 * i40e_fcoe_set_features - set the netdev feature flags
 * @netdev: ptr to the netdev being adjusted
 * @features: the feature set that the stack is suggesting
 *
 **/
static int i40e_fcoe_set_features(struct net_device *netdev,
				  netdev_features_t features)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_vsi *vsi = np->vsi;

	if (features & NETIF_F_HW_VLAN_CTAG_RX)
		i40e_vlan_stripping_enable(vsi);
	else
		i40e_vlan_stripping_disable(vsi);

	return 0;
}


static const struct net_device_ops i40e_fcoe_netdev_ops = {
	.ndo_open		= i40e_open,
	.ndo_stop		= i40e_close,
	.ndo_get_stats64	= i40e_get_netdev_stats_struct,
	.ndo_set_rx_mode	= i40e_set_rx_mode,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= i40e_set_mac,
	.ndo_change_mtu		= i40e_fcoe_change_mtu,
	.ndo_do_ioctl		= i40e_ioctl,
	.ndo_tx_timeout		= i40e_tx_timeout,
	.ndo_vlan_rx_add_vid	= i40e_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= i40e_vlan_rx_kill_vid,
	.ndo_setup_tc		= i40e_setup_tc,

#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= i40e_netpoll,
#endif
	.ndo_start_xmit		= i40e_fcoe_xmit_frame,
	.ndo_fcoe_enable	= i40e_fcoe_enable,
	.ndo_fcoe_disable	= i40e_fcoe_disable,
	.ndo_fcoe_ddp_setup	= i40e_fcoe_ddp_get,
	.ndo_fcoe_ddp_done	= i40e_fcoe_ddp_put,
	.ndo_fcoe_ddp_target	= i40e_fcoe_ddp_target,
	.ndo_set_features	= i40e_fcoe_set_features,
};

/**
 * i40e_fcoe_config_netdev - prepares the VSI context for creating a FCoE VSI
 * @vsi: pointer to the associated VSI struct
 * @ctxt: pointer to the associated VSI context to be passed to HW
 *
 * Returns 0 on success or < 0 on error
 **/
void i40e_fcoe_config_netdev(struct net_device *netdev, struct i40e_vsi *vsi)
{
	struct i40e_hw *hw = &vsi->back->hw;
	struct i40e_pf *pf = vsi->back;

	if (vsi->type != I40E_VSI_FCOE)
		return;

	netdev->features = (NETIF_F_HW_VLAN_CTAG_TX |
			    NETIF_F_HW_VLAN_CTAG_RX |
			    NETIF_F_HW_VLAN_CTAG_FILTER);

	netdev->vlan_features = netdev->features;
	netdev->vlan_features &= ~(NETIF_F_HW_VLAN_CTAG_TX |
				   NETIF_F_HW_VLAN_CTAG_RX |
				   NETIF_F_HW_VLAN_CTAG_FILTER);
	netdev->fcoe_ddp_xid = I40E_FCOE_DDP_MAX - 1;
	netdev->features |= NETIF_F_ALL_FCOE;
	netdev->vlan_features |= NETIF_F_ALL_FCOE;
	netdev->hw_features |= netdev->features;
	netdev->priv_flags |= IFF_UNICAST_FLT;
	netdev->priv_flags |= IFF_SUPP_NOFCS;

	strlcpy(netdev->name, "fcoe%d", IFNAMSIZ-1);
	netdev->mtu = FCOE_MTU;
	SET_NETDEV_DEV(netdev, &pf->pdev->dev);
	i40e_add_filter(vsi, hw->mac.san_addr, 0, false, false);
	i40e_add_filter(vsi, (u8[6]) FC_FCOE_FLOGI_MAC, 0, false, false);
	i40e_add_filter(vsi, FIP_ALL_FCOE_MACS, 0, false, false);
	i40e_add_filter(vsi, FIP_ALL_ENODE_MACS, 0, false, false);
	i40e_add_filter(vsi, FIP_ALL_VN2VN_MACS, 0, false, false);
	i40e_add_filter(vsi, FIP_ALL_P2P_MACS, 0, false, false);

	/* use san mac */
	ether_addr_copy(netdev->dev_addr, hw->mac.san_addr);
	ether_addr_copy(netdev->perm_addr, hw->mac.san_addr);
	/* fcoe netdev ops */
	netdev->netdev_ops = &i40e_fcoe_netdev_ops;
}

/**
 * i40e_fcoe_vsi_setup - allocate and set up FCoE VSI
 * @pf: the pf that VSI is associated with
 *
 **/
void i40e_fcoe_vsi_setup(struct i40e_pf *pf)
{
	struct i40e_vsi *vsi;
	u16 seid;
	int i;

	if (!(pf->flags & I40E_FLAG_FCOE_ENABLED))
		return;

	BUG_ON(!pf->vsi[pf->lan_vsi]);

	for (i = 0; i < pf->num_alloc_vsi; i++) {
		vsi = pf->vsi[i];
		if (vsi && vsi->type == I40E_VSI_FCOE) {
			dev_warn(&pf->pdev->dev,
				 "FCoE VSI already created\n");
			return;
		}
	}

	seid = pf->vsi[pf->lan_vsi]->seid;
	vsi = i40e_vsi_setup(pf, I40E_VSI_FCOE, seid, 0);
	if (vsi) {
		dev_dbg(&pf->pdev->dev,
			"Successfully created FCoE VSI seid %d id %d uplink_seid %d pf seid %d\n",
			vsi->seid, vsi->id, vsi->uplink_seid, seid);
	} else {
		dev_info(&pf->pdev->dev, "Failed to create FCoE VSI\n");
	}
}
