/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Driver
 * Copyright(c) 2013 - 2015 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_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 and that already checks for all supported valid eof values.
 **/
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:
		/* Supported valid eof shall be already checked by
		 * calling i40e_fcoe_eof_is_supported() first,
		 * therefore this default case shall never hit.
		 */
		WARN_ON(1);
		return -EINVAL;
	}
}

/**
 * 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
 **/
void 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_dbg(&pf->pdev->dev, "FCoE capability is disabled\n");
		return;
	}

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

	/* enable FCoE hash filter */
	val = i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1));
	val |= BIT(I40E_FILTER_PCTYPE_FCOE_OX - 32);
	val |= BIT(I40E_FILTER_PCTYPE_FCOE_RX - 32);
	val &= I40E_PFQF_HENA_PTYPE_ENA_MASK;
	i40e_write_rx_ctl(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 = BIT(I40E_DMA_CNTX_SIZE_4K) *
				I40E_DMA_CNTX_BASE_SIZE;
	pf->fcoe_hmc_filt_num = pf->fcoe_hmc_cntx_num +
				BIT(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 = i40e_read_rx_ctl(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);
	i40e_write_rx_ctl(hw, I40E_GLFCOE_RCTL, val);

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

/**
 * 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 |= BIT(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 = I40E_AQ_VSI_CONN_TYPE_NORMAL;
	ctxt->flags = I40E_AQ_VSI_TYPE_PF;

	/* FCoE VSI would need the following sections */
	info->valid_sections |= cpu_to_le16(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));

	if (i40e_is_vsi_uplink_mode_veb(vsi)) {
		info->valid_sections |=
				cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
		info->switch_id =
				cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
	}
	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;

	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;
	int fso, count;
	u8 hdr_len = 0;
	u8 sof = 0;
	u8 eof = 0;

	if (i40e_fcoe_set_skb_header(skb))
		goto out_drop;

	count = i40e_xmit_descriptor_count(skb);
	if (i40e_chk_linearize(skb, count)) {
		if (__skb_linearize(skb))
			goto out_drop;
		count = TXD_USE_COUNT(skb->len);
		tx_ring->tx_stats.tx_linearize++;
	}

	/* need: 1 descriptor per page * PAGE_SIZE/I40E_MAX_DATA_PER_TXD,
	 *       + 1 desc for skb_head_len/I40E_MAX_DATA_PER_TXD,
	 *       + 4 desc gap to avoid the cache line where head is,
	 *       + 1 desc for context descriptor,
	 * otherwise try next time
	 */
	if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
		tx_ring->tx_stats.tx_busy++;
		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,
};

/* fcoe network device type */
static struct device_type fcoe_netdev_type = {
	.name = "fcoe",
};

/**
 * 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);
	SET_NETDEV_DEVTYPE(netdev, &fcoe_netdev_type);
	/* set different dev_port value 1 for FCoE netdev than the default
	 * zero dev_port value for PF netdev, this helps biosdevname user
	 * tool to differentiate them correctly while both attached to the
	 * same PCI function.
	 */
	netdev->dev_port = 1;
	spin_lock_bh(&vsi->mac_filter_list_lock);
	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);
	spin_unlock_bh(&vsi->mac_filter_list_lock);

	/* 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;

	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");
	}
}
