brintos

brintos / linux-shallow public Read only

0
0
Text · 27.6 KiB · 955dced Raw
1048 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 1999 - 2018 Intel Corporation. */3 4#include "ixgbe.h"5#include <linux/if_ether.h>6#include <linux/gfp.h>7#include <linux/if_vlan.h>8#include <generated/utsrelease.h>9#include <scsi/scsi_cmnd.h>10#include <scsi/scsi_device.h>11#include <scsi/fc/fc_fs.h>12#include <scsi/fc/fc_fcoe.h>13#include <scsi/libfc.h>14#include <scsi/libfcoe.h>15 16/**17 * ixgbe_fcoe_clear_ddp - clear the given ddp context18 * @ddp: ptr to the ixgbe_fcoe_ddp19 *20 * Returns : none21 *22 */23static inline void ixgbe_fcoe_clear_ddp(struct ixgbe_fcoe_ddp *ddp)24{25	ddp->len = 0;26	ddp->err = 1;27	ddp->udl = NULL;28	ddp->udp = 0UL;29	ddp->sgl = NULL;30	ddp->sgc = 0;31}32 33/**34 * ixgbe_fcoe_ddp_put - free the ddp context for a given xid35 * @netdev: the corresponding net_device36 * @xid: the xid that corresponding ddp will be freed37 *38 * This is the implementation of net_device_ops.ndo_fcoe_ddp_done39 * and it is expected to be called by ULD, i.e., FCP layer of libfc40 * to release the corresponding ddp context when the I/O is done.41 *42 * Returns : data length already ddp-ed in bytes43 */44int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid)45{46	int len;47	struct ixgbe_fcoe *fcoe;48	struct ixgbe_adapter *adapter;49	struct ixgbe_fcoe_ddp *ddp;50	struct ixgbe_hw *hw;51	u32 fcbuff;52 53	if (!netdev)54		return 0;55 56	if (xid >= netdev->fcoe_ddp_xid)57		return 0;58 59	adapter = netdev_priv(netdev);60	fcoe = &adapter->fcoe;61	ddp = &fcoe->ddp[xid];62	if (!ddp->udl)63		return 0;64 65	hw = &adapter->hw;66	len = ddp->len;67	/* if no error then skip ddp context invalidation */68	if (!ddp->err)69		goto skip_ddpinv;70 71	if (hw->mac.type == ixgbe_mac_X550) {72		/* X550 does not require DDP FCoE lock */73 74		IXGBE_WRITE_REG(hw, IXGBE_FCDFC(0, xid), 0);75		IXGBE_WRITE_REG(hw, IXGBE_FCDFC(3, xid),76				(xid | IXGBE_FCFLTRW_WE));77 78		/* program FCBUFF */79		IXGBE_WRITE_REG(hw, IXGBE_FCDDC(2, xid), 0);80 81		/* program FCDMARW */82		IXGBE_WRITE_REG(hw, IXGBE_FCDDC(3, xid),83				(xid | IXGBE_FCDMARW_WE));84 85		/* read FCBUFF to check context invalidated */86		IXGBE_WRITE_REG(hw, IXGBE_FCDDC(3, xid),87				(xid | IXGBE_FCDMARW_RE));88		fcbuff = IXGBE_READ_REG(hw, IXGBE_FCDDC(2, xid));89	} else {90		/* other hardware requires DDP FCoE lock */91		spin_lock_bh(&fcoe->lock);92		IXGBE_WRITE_REG(hw, IXGBE_FCFLT, 0);93		IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW,94				(xid | IXGBE_FCFLTRW_WE));95		IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, 0);96		IXGBE_WRITE_REG(hw, IXGBE_FCDMARW,97				(xid | IXGBE_FCDMARW_WE));98 99		/* guaranteed to be invalidated after 100us */100		IXGBE_WRITE_REG(hw, IXGBE_FCDMARW,101				(xid | IXGBE_FCDMARW_RE));102		fcbuff = IXGBE_READ_REG(hw, IXGBE_FCBUFF);103		spin_unlock_bh(&fcoe->lock);104		}105 106	if (fcbuff & IXGBE_FCBUFF_VALID)107		usleep_range(100, 150);108 109skip_ddpinv:110	if (ddp->sgl)111		dma_unmap_sg(&adapter->pdev->dev, ddp->sgl, ddp->sgc,112			     DMA_FROM_DEVICE);113	if (ddp->pool) {114		dma_pool_free(ddp->pool, ddp->udl, ddp->udp);115		ddp->pool = NULL;116	}117 118	ixgbe_fcoe_clear_ddp(ddp);119 120	return len;121}122 123/**124 * ixgbe_fcoe_ddp_setup - called to set up ddp context125 * @netdev: the corresponding net_device126 * @xid: the exchange id requesting ddp127 * @sgl: the scatter-gather list for this request128 * @sgc: the number of scatter-gather items129 * @target_mode: 1 to setup target mode, 0 to setup initiator mode130 *131 * Returns : 1 for success and 0 for no ddp132 */133static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,134				struct scatterlist *sgl, unsigned int sgc,135				int target_mode)136{137	struct ixgbe_adapter *adapter;138	struct ixgbe_hw *hw;139	struct ixgbe_fcoe *fcoe;140	struct ixgbe_fcoe_ddp *ddp;141	struct ixgbe_fcoe_ddp_pool *ddp_pool;142	struct scatterlist *sg;143	unsigned int i, j, dmacount;144	unsigned int len;145	static const unsigned int bufflen = IXGBE_FCBUFF_MIN;146	unsigned int firstoff = 0;147	unsigned int lastsize;148	unsigned int thisoff = 0;149	unsigned int thislen = 0;150	u32 fcbuff, fcdmarw, fcfltrw, fcrxctl;151	dma_addr_t addr = 0;152 153	if (!netdev || !sgl)154		return 0;155 156	adapter = netdev_priv(netdev);157	if (xid >= netdev->fcoe_ddp_xid) {158		e_warn(drv, "xid=0x%x out-of-range\n", xid);159		return 0;160	}161 162	/* no DDP if we are already down or resetting */163	if (test_bit(__IXGBE_DOWN, &adapter->state) ||164	    test_bit(__IXGBE_RESETTING, &adapter->state))165		return 0;166 167	fcoe = &adapter->fcoe;168	ddp = &fcoe->ddp[xid];169	if (ddp->sgl) {170		e_err(drv, "xid 0x%x w/ non-null sgl=%p nents=%d\n",171		      xid, ddp->sgl, ddp->sgc);172		return 0;173	}174	ixgbe_fcoe_clear_ddp(ddp);175 176 177	if (!fcoe->ddp_pool) {178		e_warn(drv, "No ddp_pool resources allocated\n");179		return 0;180	}181 182	ddp_pool = per_cpu_ptr(fcoe->ddp_pool, get_cpu());183	if (!ddp_pool->pool) {184		e_warn(drv, "xid=0x%x no ddp pool for fcoe\n", xid);185		goto out_noddp;186	}187 188	/* setup dma from scsi command sgl */189	dmacount = dma_map_sg(&adapter->pdev->dev, sgl, sgc, DMA_FROM_DEVICE);190	if (dmacount == 0) {191		e_err(drv, "xid 0x%x DMA map error\n", xid);192		goto out_noddp;193	}194 195	/* alloc the udl from per cpu ddp pool */196	ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_ATOMIC, &ddp->udp);197	if (!ddp->udl) {198		e_err(drv, "failed allocated ddp context\n");199		goto out_noddp_unmap;200	}201	ddp->pool = ddp_pool->pool;202	ddp->sgl = sgl;203	ddp->sgc = sgc;204 205	j = 0;206	for_each_sg(sgl, sg, dmacount, i) {207		addr = sg_dma_address(sg);208		len = sg_dma_len(sg);209		while (len) {210			/* max number of buffers allowed in one DDP context */211			if (j >= IXGBE_BUFFCNT_MAX) {212				ddp_pool->noddp++;213				goto out_noddp_free;214			}215 216			/* get the offset of length of current buffer */217			thisoff = addr & ((dma_addr_t)bufflen - 1);218			thislen = min((bufflen - thisoff), len);219			/*220			 * all but the 1st buffer (j == 0)221			 * must be aligned on bufflen222			 */223			if ((j != 0) && (thisoff))224				goto out_noddp_free;225			/*226			 * all but the last buffer227			 * ((i == (dmacount - 1)) && (thislen == len))228			 * must end at bufflen229			 */230			if (((i != (dmacount - 1)) || (thislen != len))231			    && ((thislen + thisoff) != bufflen))232				goto out_noddp_free;233 234			ddp->udl[j] = (u64)(addr - thisoff);235			/* only the first buffer may have none-zero offset */236			if (j == 0)237				firstoff = thisoff;238			len -= thislen;239			addr += thislen;240			j++;241		}242	}243	/* only the last buffer may have non-full bufflen */244	lastsize = thisoff + thislen;245 246	/*247	 * lastsize can not be buffer len.248	 * If it is then adding another buffer with lastsize = 1.249	 */250	if (lastsize == bufflen) {251		if (j >= IXGBE_BUFFCNT_MAX) {252			ddp_pool->noddp_ext_buff++;253			goto out_noddp_free;254		}255 256		ddp->udl[j] = (u64)(fcoe->extra_ddp_buffer_dma);257		j++;258		lastsize = 1;259	}260	put_cpu();261 262	fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);263	fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);264	fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);265	/* Set WRCONTX bit to allow DDP for target */266	if (target_mode)267		fcbuff |= (IXGBE_FCBUFF_WRCONTX);268	fcbuff |= (IXGBE_FCBUFF_VALID);269 270	fcdmarw = xid;271	fcdmarw |= IXGBE_FCDMARW_WE;272	fcdmarw |= (lastsize << IXGBE_FCDMARW_LASTSIZE_SHIFT);273 274	fcfltrw = xid;275	fcfltrw |= IXGBE_FCFLTRW_WE;276 277	/* program DMA context */278	hw = &adapter->hw;279 280	/* turn on last frame indication for target mode as FCP_RSPtarget is281	 * supposed to send FCP_RSP when it is done. */282	if (target_mode && !test_bit(__IXGBE_FCOE_TARGET, &fcoe->mode)) {283		set_bit(__IXGBE_FCOE_TARGET, &fcoe->mode);284		fcrxctl = IXGBE_READ_REG(hw, IXGBE_FCRXCTRL);285		fcrxctl |= IXGBE_FCRXCTRL_LASTSEQH;286		IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, fcrxctl);287	}288 289	if (hw->mac.type == ixgbe_mac_X550) {290		/* X550 does not require DDP lock */291 292		IXGBE_WRITE_REG(hw, IXGBE_FCDDC(0, xid),293				ddp->udp & DMA_BIT_MASK(32));294		IXGBE_WRITE_REG(hw, IXGBE_FCDDC(1, xid), (u64)ddp->udp >> 32);295		IXGBE_WRITE_REG(hw, IXGBE_FCDDC(2, xid), fcbuff);296		IXGBE_WRITE_REG(hw, IXGBE_FCDDC(3, xid), fcdmarw);297		/* program filter context */298		IXGBE_WRITE_REG(hw, IXGBE_FCDFC(0, xid), IXGBE_FCFLT_VALID);299		IXGBE_WRITE_REG(hw, IXGBE_FCDFC(1, xid), 0);300		IXGBE_WRITE_REG(hw, IXGBE_FCDFC(3, xid), fcfltrw);301	} else {302		/* DDP lock for indirect DDP context access */303		spin_lock_bh(&fcoe->lock);304 305		IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_BIT_MASK(32));306		IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32);307		IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff);308		IXGBE_WRITE_REG(hw, IXGBE_FCDMARW, fcdmarw);309		/* program filter context */310		IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0);311		IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID);312		IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw);313 314		spin_unlock_bh(&fcoe->lock);315	}316 317	return 1;318 319out_noddp_free:320	dma_pool_free(ddp->pool, ddp->udl, ddp->udp);321	ixgbe_fcoe_clear_ddp(ddp);322 323out_noddp_unmap:324	dma_unmap_sg(&adapter->pdev->dev, sgl, sgc, DMA_FROM_DEVICE);325out_noddp:326	put_cpu();327	return 0;328}329 330/**331 * ixgbe_fcoe_ddp_get - called to set up ddp context in initiator mode332 * @netdev: the corresponding net_device333 * @xid: the exchange id requesting ddp334 * @sgl: the scatter-gather list for this request335 * @sgc: the number of scatter-gather items336 *337 * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup338 * and is expected to be called from ULD, e.g., FCP layer of libfc339 * to set up ddp for the corresponding xid of the given sglist for340 * the corresponding I/O.341 *342 * Returns : 1 for success and 0 for no ddp343 */344int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,345		       struct scatterlist *sgl, unsigned int sgc)346{347	return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 0);348}349 350/**351 * ixgbe_fcoe_ddp_target - called to set up ddp context in target mode352 * @netdev: the corresponding net_device353 * @xid: the exchange id requesting ddp354 * @sgl: the scatter-gather list for this request355 * @sgc: the number of scatter-gather items356 *357 * This is the implementation of net_device_ops.ndo_fcoe_ddp_target358 * and is expected to be called from ULD, e.g., FCP layer of libfc359 * to set up ddp for the corresponding xid of the given sglist for360 * the corresponding I/O. The DDP in target mode is a write I/O request361 * from the initiator.362 *363 * Returns : 1 for success and 0 for no ddp364 */365int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid,366			    struct scatterlist *sgl, unsigned int sgc)367{368	return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 1);369}370 371/**372 * ixgbe_fcoe_ddp - check ddp status and mark it done373 * @adapter: ixgbe adapter374 * @rx_desc: advanced rx descriptor375 * @skb: the skb holding the received data376 *377 * This checks ddp status.378 *379 * Returns : < 0 indicates an error or not a FCiE ddp, 0 indicates380 * not passing the skb to ULD, > 0 indicates is the length of data381 * being ddped.382 */383int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,384		   union ixgbe_adv_rx_desc *rx_desc,385		   struct sk_buff *skb)386{387	int rc = -EINVAL;388	struct ixgbe_fcoe *fcoe;389	struct ixgbe_fcoe_ddp *ddp;390	struct fc_frame_header *fh;391	struct fcoe_crc_eof *crc;392	__le32 fcerr = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCERR);393	__le32 ddp_err;394	int ddp_max;395	u32 fctl;396	u16 xid;397 398	if (fcerr == cpu_to_le32(IXGBE_FCERR_BADCRC))399		skb->ip_summed = CHECKSUM_NONE;400	else401		skb->ip_summed = CHECKSUM_UNNECESSARY;402 403	if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q))404		fh = (struct fc_frame_header *)(skb->data +405			sizeof(struct vlan_hdr) + sizeof(struct fcoe_hdr));406	else407		fh = (struct fc_frame_header *)(skb->data +408			sizeof(struct fcoe_hdr));409 410	fctl = ntoh24(fh->fh_f_ctl);411	if (fctl & FC_FC_EX_CTX)412		xid =  be16_to_cpu(fh->fh_ox_id);413	else414		xid =  be16_to_cpu(fh->fh_rx_id);415 416	ddp_max = IXGBE_FCOE_DDP_MAX;417	/* X550 has different DDP Max limit */418	if (adapter->hw.mac.type == ixgbe_mac_X550)419		ddp_max = IXGBE_FCOE_DDP_MAX_X550;420	if (xid >= ddp_max)421		return -EINVAL;422 423	fcoe = &adapter->fcoe;424	ddp = &fcoe->ddp[xid];425	if (!ddp->udl)426		return -EINVAL;427 428	ddp_err = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCEOFE |429					      IXGBE_RXDADV_ERR_FCERR);430	if (ddp_err)431		return -EINVAL;432 433	switch (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_FCSTAT)) {434	/* return 0 to bypass going to ULD for DDPed data */435	case cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_DDP):436		/* update length of DDPed data */437		ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);438		rc = 0;439		break;440	/* unmap the sg list when FCPRSP is received */441	case cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_FCPRSP):442		dma_unmap_sg(&adapter->pdev->dev, ddp->sgl,443			     ddp->sgc, DMA_FROM_DEVICE);444		ddp->err = (__force u32)ddp_err;445		ddp->sgl = NULL;446		ddp->sgc = 0;447		fallthrough;448	/* if DDP length is present pass it through to ULD */449	case cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NODDP):450		/* update length of DDPed data */451		ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);452		if (ddp->len)453			rc = ddp->len;454		break;455	/* no match will return as an error */456	case cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NOMTCH):457	default:458		break;459	}460 461	/* In target mode, check the last data frame of the sequence.462	 * For DDP in target mode, data is already DDPed but the header463	 * indication of the last data frame ould allow is to tell if we464	 * got all the data and the ULP can send FCP_RSP back, as this is465	 * not a full fcoe frame, we fill the trailer here so it won't be466	 * dropped by the ULP stack.467	 */468	if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) &&469	    (fctl & FC_FC_END_SEQ)) {470		skb_linearize(skb);471		crc = skb_put(skb, sizeof(*crc));472		crc->fcoe_eof = FC_EOF_T;473	}474 475	return rc;476}477 478/**479 * ixgbe_fso - ixgbe FCoE Sequence Offload (FSO)480 * @tx_ring: tx desc ring481 * @first: first tx_buffer structure containing skb, tx_flags, and protocol482 * @hdr_len: hdr_len to be returned483 *484 * This sets up large send offload for FCoE485 *486 * Returns : 0 indicates success, < 0 for error487 */488int ixgbe_fso(struct ixgbe_ring *tx_ring,489	      struct ixgbe_tx_buffer *first,490	      u8 *hdr_len)491{492	struct sk_buff *skb = first->skb;493	struct fc_frame_header *fh;494	u32 vlan_macip_lens;495	u32 fcoe_sof_eof = 0;496	u32 mss_l4len_idx;497	u32 type_tucmd = IXGBE_ADVTXT_TUCMD_FCOE;498	u8 sof, eof;499 500	if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE)) {501		dev_err(tx_ring->dev, "Wrong gso type %d:expecting SKB_GSO_FCOE\n",502			skb_shinfo(skb)->gso_type);503		return -EINVAL;504	}505 506	/* resets the header to point fcoe/fc */507	skb_set_network_header(skb, skb->mac_len);508	skb_set_transport_header(skb, skb->mac_len +509				 sizeof(struct fcoe_hdr));510 511	/* sets up SOF and ORIS */512	sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof;513	switch (sof) {514	case FC_SOF_I2:515		fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_ORIS;516		break;517	case FC_SOF_I3:518		fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF |519			       IXGBE_ADVTXD_FCOEF_ORIS;520		break;521	case FC_SOF_N2:522		break;523	case FC_SOF_N3:524		fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF;525		break;526	default:527		dev_warn(tx_ring->dev, "unknown sof = 0x%x\n", sof);528		return -EINVAL;529	}530 531	/* the first byte of the last dword is EOF */532	skb_copy_bits(skb, skb->len - 4, &eof, 1);533	/* sets up EOF and ORIE */534	switch (eof) {535	case FC_EOF_N:536		fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N;537		break;538	case FC_EOF_T:539		/* lso needs ORIE */540		if (skb_is_gso(skb))541			fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N |542					IXGBE_ADVTXD_FCOEF_ORIE;543		else544			fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_T;545		break;546	case FC_EOF_NI:547		fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_NI;548		break;549	case FC_EOF_A:550		fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_A;551		break;552	default:553		dev_warn(tx_ring->dev, "unknown eof = 0x%x\n", eof);554		return -EINVAL;555	}556 557	/* sets up PARINC indicating data offset */558	fh = (struct fc_frame_header *)skb_transport_header(skb);559	if (fh->fh_f_ctl[2] & FC_FC_REL_OFF)560		fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_PARINC;561 562	/* include trailer in headlen as it is replicated per frame */563	*hdr_len = sizeof(struct fcoe_crc_eof);564 565	/* hdr_len includes fc_hdr if FCoE LSO is enabled */566	if (skb_is_gso(skb)) {567		*hdr_len += skb_transport_offset(skb) +568			    sizeof(struct fc_frame_header);569		/* update gso_segs and bytecount */570		first->gso_segs = DIV_ROUND_UP(skb->len - *hdr_len,571					       skb_shinfo(skb)->gso_size);572		first->bytecount += (first->gso_segs - 1) * *hdr_len;573		first->tx_flags |= IXGBE_TX_FLAGS_TSO;574		/* Hardware expects L4T to be RSV for FCoE TSO */575		type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_RSV;576	}577 578	/* set flag indicating FCOE to ixgbe_tx_map call */579	first->tx_flags |= IXGBE_TX_FLAGS_FCOE | IXGBE_TX_FLAGS_CC;580 581	/* mss_l4len_id: use 0 for FSO as TSO, no need for L4LEN */582	mss_l4len_idx = skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT;583 584	/* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */585	vlan_macip_lens = skb_transport_offset(skb) +586			  sizeof(struct fc_frame_header);587	vlan_macip_lens |= (skb_transport_offset(skb) - 4)588			   << IXGBE_ADVTXD_MACLEN_SHIFT;589	vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;590 591	/* write context desc */592	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fcoe_sof_eof,593			  type_tucmd, mss_l4len_idx);594 595	return 0;596}597 598static void ixgbe_fcoe_dma_pool_free(struct ixgbe_fcoe *fcoe, unsigned int cpu)599{600	struct ixgbe_fcoe_ddp_pool *ddp_pool;601 602	ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu);603	dma_pool_destroy(ddp_pool->pool);604	ddp_pool->pool = NULL;605}606 607static int ixgbe_fcoe_dma_pool_alloc(struct ixgbe_fcoe *fcoe,608				     struct device *dev,609				     unsigned int cpu)610{611	struct ixgbe_fcoe_ddp_pool *ddp_pool;612	struct dma_pool *pool;613	char pool_name[32];614 615	snprintf(pool_name, 32, "ixgbe_fcoe_ddp_%u", cpu);616 617	pool = dma_pool_create(pool_name, dev, IXGBE_FCPTR_MAX,618			       IXGBE_FCPTR_ALIGN, PAGE_SIZE);619	if (!pool)620		return -ENOMEM;621 622	ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu);623	ddp_pool->pool = pool;624	ddp_pool->noddp = 0;625	ddp_pool->noddp_ext_buff = 0;626 627	return 0;628}629 630/**631 * ixgbe_configure_fcoe - configures registers for fcoe at start632 * @adapter: ptr to ixgbe adapter633 *634 * This sets up FCoE related registers635 *636 * Returns : none637 */638void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)639{640	struct ixgbe_ring_feature *fcoe = &adapter->ring_feature[RING_F_FCOE];641	struct ixgbe_hw *hw = &adapter->hw;642	int i, fcoe_q, fcoe_i, fcoe_q_h = 0;643	int fcreta_size;644	u32 etqf;645 646	/* Minimal functionality for FCoE requires at least CRC offloads */647	if (!(adapter->netdev->features & NETIF_F_FCOE_CRC))648		return;649 650	/* Enable L2 EtherType filter for FCoE, needed for FCoE CRC and DDP */651	etqf = ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN;652	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {653		etqf |= IXGBE_ETQF_POOL_ENABLE;654		etqf |= VMDQ_P(0) << IXGBE_ETQF_POOL_SHIFT;655	}656	IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE), etqf);657	IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);658 659	/* leave registers un-configured if FCoE is disabled */660	if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))661		return;662 663	/* Use one or more Rx queues for FCoE by redirection table */664	fcreta_size = IXGBE_FCRETA_SIZE;665	if (adapter->hw.mac.type == ixgbe_mac_X550)666		fcreta_size = IXGBE_FCRETA_SIZE_X550;667 668	for (i = 0; i < fcreta_size; i++) {669		if (adapter->hw.mac.type == ixgbe_mac_X550) {670			int fcoe_i_h = fcoe->offset + ((i + fcreta_size) %671							fcoe->indices);672			fcoe_q_h = adapter->rx_ring[fcoe_i_h]->reg_idx;673			fcoe_q_h = FIELD_PREP(IXGBE_FCRETA_ENTRY_HIGH_MASK,674					      fcoe_q_h);675		}676 677		fcoe_i = fcoe->offset + (i % fcoe->indices);678		fcoe_i &= IXGBE_FCRETA_ENTRY_MASK;679		fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;680		fcoe_q |= fcoe_q_h;681		IXGBE_WRITE_REG(hw, IXGBE_FCRETA(i), fcoe_q);682	}683	IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA);684 685	/* Enable L2 EtherType filter for FIP */686	etqf = ETH_P_FIP | IXGBE_ETQF_FILTER_EN;687	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {688		etqf |= IXGBE_ETQF_POOL_ENABLE;689		etqf |= VMDQ_P(0) << IXGBE_ETQF_POOL_SHIFT;690	}691	IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FIP), etqf);692 693	/* Send FIP frames to the first FCoE queue */694	fcoe_q = adapter->rx_ring[fcoe->offset]->reg_idx;695	IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),696			IXGBE_ETQS_QUEUE_EN |697			(fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));698 699	/* Configure FCoE Rx control */700	IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL,701			IXGBE_FCRXCTRL_FCCRCBO |702			(FC_FCOE_VER << IXGBE_FCRXCTRL_FCOEVER_SHIFT));703}704 705/**706 * ixgbe_free_fcoe_ddp_resources - release all fcoe ddp context resources707 * @adapter : ixgbe adapter708 *709 * Cleans up outstanding ddp context resources710 *711 * Returns : none712 */713void ixgbe_free_fcoe_ddp_resources(struct ixgbe_adapter *adapter)714{715	struct ixgbe_fcoe *fcoe = &adapter->fcoe;716	int cpu, i, ddp_max;717 718	/* do nothing if no DDP pools were allocated */719	if (!fcoe->ddp_pool)720		return;721 722	ddp_max = IXGBE_FCOE_DDP_MAX;723	/* X550 has different DDP Max limit */724	if (adapter->hw.mac.type == ixgbe_mac_X550)725		ddp_max = IXGBE_FCOE_DDP_MAX_X550;726 727	for (i = 0; i < ddp_max; i++)728		ixgbe_fcoe_ddp_put(adapter->netdev, i);729 730	for_each_possible_cpu(cpu)731		ixgbe_fcoe_dma_pool_free(fcoe, cpu);732 733	dma_unmap_single(&adapter->pdev->dev,734			 fcoe->extra_ddp_buffer_dma,735			 IXGBE_FCBUFF_MIN,736			 DMA_FROM_DEVICE);737	kfree(fcoe->extra_ddp_buffer);738 739	fcoe->extra_ddp_buffer = NULL;740	fcoe->extra_ddp_buffer_dma = 0;741}742 743/**744 * ixgbe_setup_fcoe_ddp_resources - setup all fcoe ddp context resources745 * @adapter: ixgbe adapter746 *747 * Sets up ddp context resouces748 *749 * Returns : 0 indicates success or -EINVAL on failure750 */751int ixgbe_setup_fcoe_ddp_resources(struct ixgbe_adapter *adapter)752{753	struct ixgbe_fcoe *fcoe = &adapter->fcoe;754	struct device *dev = &adapter->pdev->dev;755	void *buffer;756	dma_addr_t dma;757	unsigned int cpu;758 759	/* do nothing if no DDP pools were allocated */760	if (!fcoe->ddp_pool)761		return 0;762 763	/* Extra buffer to be shared by all DDPs for HW work around */764	buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_KERNEL);765	if (!buffer)766		return -ENOMEM;767 768	dma = dma_map_single(dev, buffer, IXGBE_FCBUFF_MIN, DMA_FROM_DEVICE);769	if (dma_mapping_error(dev, dma)) {770		e_err(drv, "failed to map extra DDP buffer\n");771		kfree(buffer);772		return -ENOMEM;773	}774 775	fcoe->extra_ddp_buffer = buffer;776	fcoe->extra_ddp_buffer_dma = dma;777 778	/* allocate pci pool for each cpu */779	for_each_possible_cpu(cpu) {780		int err = ixgbe_fcoe_dma_pool_alloc(fcoe, dev, cpu);781		if (!err)782			continue;783 784		e_err(drv, "failed to alloc DDP pool on cpu:%d\n", cpu);785		ixgbe_free_fcoe_ddp_resources(adapter);786		return -ENOMEM;787	}788 789	return 0;790}791 792static int ixgbe_fcoe_ddp_enable(struct ixgbe_adapter *adapter)793{794	struct ixgbe_fcoe *fcoe = &adapter->fcoe;795 796	if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))797		return -EINVAL;798 799	fcoe->ddp_pool = alloc_percpu(struct ixgbe_fcoe_ddp_pool);800 801	if (!fcoe->ddp_pool) {802		e_err(drv, "failed to allocate percpu DDP resources\n");803		return -ENOMEM;804	}805 806	adapter->netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;807	/* X550 has different DDP Max limit */808	if (adapter->hw.mac.type == ixgbe_mac_X550)809		adapter->netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX_X550 - 1;810 811	return 0;812}813 814static void ixgbe_fcoe_ddp_disable(struct ixgbe_adapter *adapter)815{816	struct ixgbe_fcoe *fcoe = &adapter->fcoe;817 818	adapter->netdev->fcoe_ddp_xid = 0;819 820	if (!fcoe->ddp_pool)821		return;822 823	free_percpu(fcoe->ddp_pool);824	fcoe->ddp_pool = NULL;825}826 827/**828 * ixgbe_fcoe_enable - turn on FCoE offload feature829 * @netdev: the corresponding netdev830 *831 * Turns on FCoE offload feature in 82599.832 *833 * Returns : 0 indicates success or -EINVAL on failure834 */835int ixgbe_fcoe_enable(struct net_device *netdev)836{837	struct ixgbe_adapter *adapter = netdev_priv(netdev);838	struct ixgbe_fcoe *fcoe = &adapter->fcoe;839 840	atomic_inc(&fcoe->refcnt);841 842	if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))843		return -EINVAL;844 845	if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)846		return -EINVAL;847 848	e_info(drv, "Enabling FCoE offload features.\n");849 850	if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)851		e_warn(probe, "Enabling FCoE on PF will disable legacy VFs\n");852 853	if (netif_running(netdev))854		netdev->netdev_ops->ndo_stop(netdev);855 856	/* Allocate per CPU memory to track DDP pools */857	ixgbe_fcoe_ddp_enable(adapter);858 859	/* enable FCoE and notify stack */860	adapter->flags |= IXGBE_FLAG_FCOE_ENABLED;861	netdev->fcoe_mtu = true;862	netdev_features_change(netdev);863 864	/* release existing queues and reallocate them */865	ixgbe_clear_interrupt_scheme(adapter);866	ixgbe_init_interrupt_scheme(adapter);867 868	if (netif_running(netdev))869		netdev->netdev_ops->ndo_open(netdev);870 871	return 0;872}873 874/**875 * ixgbe_fcoe_disable - turn off FCoE offload feature876 * @netdev: the corresponding netdev877 *878 * Turns off FCoE offload feature in 82599.879 *880 * Returns : 0 indicates success or -EINVAL on failure881 */882int ixgbe_fcoe_disable(struct net_device *netdev)883{884	struct ixgbe_adapter *adapter = netdev_priv(netdev);885 886	if (!atomic_dec_and_test(&adapter->fcoe.refcnt))887		return -EINVAL;888 889	if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))890		return -EINVAL;891 892	e_info(drv, "Disabling FCoE offload features.\n");893	if (netif_running(netdev))894		netdev->netdev_ops->ndo_stop(netdev);895 896	/* Free per CPU memory to track DDP pools */897	ixgbe_fcoe_ddp_disable(adapter);898 899	/* disable FCoE and notify stack */900	adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;901	netdev->fcoe_mtu = false;902 903	netdev_features_change(netdev);904 905	/* release existing queues and reallocate them */906	ixgbe_clear_interrupt_scheme(adapter);907	ixgbe_init_interrupt_scheme(adapter);908 909	if (netif_running(netdev))910		netdev->netdev_ops->ndo_open(netdev);911 912	return 0;913}914 915/**916 * ixgbe_fcoe_get_wwn - get world wide name for the node or the port917 * @netdev : ixgbe adapter918 * @wwn : the world wide name919 * @type: the type of world wide name920 *921 * Returns the node or port world wide name if both the prefix and the san922 * mac address are valid, then the wwn is formed based on the NAA-2 for923 * IEEE Extended name identifier (ref. to T10 FC-LS Spec., Sec. 15.3).924 *925 * Returns : 0 on success926 */927int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)928{929	u16 prefix = 0xffff;930	struct ixgbe_adapter *adapter = netdev_priv(netdev);931	struct ixgbe_mac_info *mac = &adapter->hw.mac;932 933	switch (type) {934	case NETDEV_FCOE_WWNN:935		prefix = mac->wwnn_prefix;936		break;937	case NETDEV_FCOE_WWPN:938		prefix = mac->wwpn_prefix;939		break;940	default:941		break;942	}943 944	if ((prefix != 0xffff) &&945	    is_valid_ether_addr(mac->san_addr)) {946		*wwn = ((u64) prefix << 48) |947		       ((u64) mac->san_addr[0] << 40) |948		       ((u64) mac->san_addr[1] << 32) |949		       ((u64) mac->san_addr[2] << 24) |950		       ((u64) mac->san_addr[3] << 16) |951		       ((u64) mac->san_addr[4] << 8)  |952		       ((u64) mac->san_addr[5]);953		return 0;954	}955	return -EINVAL;956}957 958/**959 * ixgbe_fcoe_get_hbainfo - get FCoE HBA information960 * @netdev : ixgbe adapter961 * @info : HBA information962 *963 * Returns ixgbe HBA information964 *965 * Returns : 0 on success966 */967int ixgbe_fcoe_get_hbainfo(struct net_device *netdev,968			   struct netdev_fcoe_hbainfo *info)969{970	struct ixgbe_adapter *adapter = netdev_priv(netdev);971	struct ixgbe_hw *hw = &adapter->hw;972	u64 dsn;973 974	if (!info)975		return -EINVAL;976 977	/* Don't return information on unsupported devices */978	if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))979		return -EINVAL;980 981	/* Manufacturer */982	snprintf(info->manufacturer, sizeof(info->manufacturer),983		 "Intel Corporation");984 985	/* Serial Number */986 987	/* Get the PCI-e Device Serial Number Capability */988	dsn = pci_get_dsn(adapter->pdev);989	if (dsn)990		snprintf(info->serial_number, sizeof(info->serial_number),991			 "%016llX", dsn);992	else993		snprintf(info->serial_number, sizeof(info->serial_number),994			 "Unknown");995 996	/* Hardware Version */997	snprintf(info->hardware_version,998		 sizeof(info->hardware_version),999		 "Rev %d", hw->revision_id);1000	/* Driver Name/Version */1001	snprintf(info->driver_version,1002		 sizeof(info->driver_version),1003		 "%s v%s",1004		 ixgbe_driver_name,1005		 UTS_RELEASE);1006	/* Firmware Version */1007	strscpy(info->firmware_version, adapter->eeprom_id,1008		sizeof(info->firmware_version));1009 1010	/* Model */1011	if (hw->mac.type == ixgbe_mac_82599EB) {1012		snprintf(info->model,1013			 sizeof(info->model),1014			 "Intel 82599");1015	} else if (hw->mac.type == ixgbe_mac_X550) {1016		snprintf(info->model,1017			 sizeof(info->model),1018			 "Intel X550");1019	} else {1020		snprintf(info->model,1021			 sizeof(info->model),1022			 "Intel X540");1023	}1024 1025	/* Model Description */1026	snprintf(info->model_description,1027		 sizeof(info->model_description),1028		 "%s",1029		 ixgbe_default_device_descr);1030 1031	return 0;1032}1033 1034/**1035 * ixgbe_fcoe_get_tc - get the current TC that fcoe is mapped to1036 * @adapter: pointer to the device adapter structure1037 *1038 * Return : TC that FCoE is mapped to1039 */1040u8 ixgbe_fcoe_get_tc(struct ixgbe_adapter *adapter)1041{1042#ifdef CONFIG_IXGBE_DCB1043	return netdev_get_prio_tc_map(adapter->netdev, adapter->fcoe.up);1044#else1045	return 0;1046#endif1047}1048