*******************************************************************************/
#include "ixgbe.h"
-#ifdef CONFIG_IXGBE_DCB
-#include "ixgbe_dcb_82599.h"
-#endif /* CONFIG_IXGBE_DCB */
#include <linux/if_ether.h>
#include <linux/gfp.h>
#include <linux/if_vlan.h>
#include <scsi/libfc.h>
#include <scsi/libfcoe.h>
-/**
- * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type
- * @rx_desc: advanced rx descriptor
- *
- * Returns : true if it is FCoE pkt
- */
-static inline bool ixgbe_rx_is_fcoe(union ixgbe_adv_rx_desc *rx_desc)
-{
- u16 p;
-
- p = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info);
- if (p & IXGBE_RXDADV_PKTTYPE_ETQF) {
- p &= IXGBE_RXDADV_PKTTYPE_ETQF_MASK;
- p >>= IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT;
- return p == IXGBE_ETQF_FILTER_FCOE;
- }
- return false;
-}
-
/**
* ixgbe_fcoe_clear_ddp - clear the given ddp context
* @ddp - ptr to the ixgbe_fcoe_ddp
return len;
}
-
/**
* ixgbe_fcoe_ddp_setup - called to set up ddp context
* @netdev: the corresponding net_device
*/
int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
union ixgbe_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
+ struct sk_buff *skb,
+ u32 staterr)
{
u16 xid;
u32 fctl;
- u32 sterr, fceofe, fcerr, fcstat;
+ u32 fceofe, fcerr, fcstat;
int rc = -EINVAL;
struct ixgbe_fcoe *fcoe;
struct ixgbe_fcoe_ddp *ddp;
struct fc_frame_header *fh;
struct fcoe_crc_eof *crc;
- if (!ixgbe_rx_is_fcoe(rx_desc))
- goto ddp_out;
-
- sterr = le32_to_cpu(rx_desc->wb.upper.status_error);
- fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR);
- fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE);
+ fcerr = (staterr & IXGBE_RXDADV_ERR_FCERR);
+ fceofe = (staterr & IXGBE_RXDADV_ERR_FCEOFE);
if (fcerr == IXGBE_FCERR_BADCRC)
skb_checksum_none_assert(skb);
else
if (fcerr | fceofe)
goto ddp_out;
- fcstat = (sterr & IXGBE_RXDADV_STAT_FCSTAT);
+ fcstat = (staterr & IXGBE_RXDADV_STAT_FCSTAT);
if (fcstat) {
/* update length of DDPed data */
ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
*
* Returns : 0 indicates no FSO, > 0 for FSO, < 0 for error
*/
-int ixgbe_fso(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb,
u32 tx_flags, u8 *hdr_len)
{
- u8 sof, eof;
+ struct fc_frame_header *fh;
u32 vlan_macip_lens;
- u32 fcoe_sof_eof;
- u32 type_tucmd;
+ u32 fcoe_sof_eof = 0;
u32 mss_l4len_idx;
- int mss = 0;
- unsigned int i;
- struct ixgbe_tx_buffer *tx_buffer_info;
- struct ixgbe_adv_tx_context_desc *context_desc;
- struct fc_frame_header *fh;
+ u8 sof, eof;
if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE)) {
- e_err(drv, "Wrong gso type %d:expecting SKB_GSO_FCOE\n",
- skb_shinfo(skb)->gso_type);
+ dev_err(tx_ring->dev, "Wrong gso type %d:expecting SKB_GSO_FCOE\n",
+ skb_shinfo(skb)->gso_type);
return -EINVAL;
}
sizeof(struct fcoe_hdr));
/* sets up SOF and ORIS */
- fcoe_sof_eof = 0;
sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof;
switch (sof) {
case FC_SOF_I2:
- fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS;
+ fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_ORIS;
break;
case FC_SOF_I3:
- fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF;
- fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS;
+ fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF |
+ IXGBE_ADVTXD_FCOEF_ORIS;
break;
case FC_SOF_N2:
break;
case FC_SOF_N3:
- fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF;
+ fcoe_sof_eof = IXGBE_ADVTXD_FCOEF_SOF;
break;
default:
- e_warn(drv, "unknown sof = 0x%x\n", sof);
+ dev_warn(tx_ring->dev, "unknown sof = 0x%x\n", sof);
return -EINVAL;
}
break;
case FC_EOF_T:
/* lso needs ORIE */
- if (skb_is_gso(skb)) {
- fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N;
- fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIE;
- } else {
+ if (skb_is_gso(skb))
+ fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N |
+ IXGBE_ADVTXD_FCOEF_ORIE;
+ else
fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_T;
- }
break;
case FC_EOF_NI:
fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_NI;
fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_A;
break;
default:
- e_warn(drv, "unknown eof = 0x%x\n", eof);
+ dev_warn(tx_ring->dev, "unknown eof = 0x%x\n", eof);
return -EINVAL;
}
if (fh->fh_f_ctl[2] & FC_FC_REL_OFF)
fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_PARINC;
- /* hdr_len includes fc_hdr if FCoE lso is enabled */
+ /* include trailer in headlen as it is replicated per frame */
*hdr_len = sizeof(struct fcoe_crc_eof);
+
+ /* hdr_len includes fc_hdr if FCoE LSO is enabled */
if (skb_is_gso(skb))
*hdr_len += (skb_transport_offset(skb) +
sizeof(struct fc_frame_header));
- /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
- vlan_macip_lens = (skb_transport_offset(skb) +
- sizeof(struct fc_frame_header));
- vlan_macip_lens |= ((skb_transport_offset(skb) - 4)
- << IXGBE_ADVTXD_MACLEN_SHIFT);
- vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
-
- /* type_tycmd and mss: set TUCMD.FCoE to enable offload */
- type_tucmd = IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT |
- IXGBE_ADVTXT_TUCMD_FCOE;
- if (skb_is_gso(skb))
- mss = skb_shinfo(skb)->gso_size;
+
/* mss_l4len_id: use 1 for FSO as TSO, no need for L4LEN */
- mss_l4len_idx = (mss << IXGBE_ADVTXD_MSS_SHIFT) |
- (1 << IXGBE_ADVTXD_IDX_SHIFT);
+ mss_l4len_idx = skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT;
+ mss_l4len_idx |= 1 << IXGBE_ADVTXD_IDX_SHIFT;
+
+ /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
+ vlan_macip_lens = skb_transport_offset(skb) +
+ sizeof(struct fc_frame_header);
+ vlan_macip_lens |= (skb_transport_offset(skb) - 4)
+ << IXGBE_ADVTXD_MACLEN_SHIFT;
+ vlan_macip_lens |= tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
/* write context desc */
- i = tx_ring->next_to_use;
- context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i);
- context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
- context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof);
- context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd);
- context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
-
- tx_buffer_info = &tx_ring->tx_buffer_info[i];
- tx_buffer_info->time_stamp = jiffies;
- tx_buffer_info->next_to_watch = i;
-
- i++;
- if (i == tx_ring->count)
- i = 0;
- tx_ring->next_to_use = i;
+ ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fcoe_sof_eof,
+ IXGBE_ADVTXT_TUCMD_FCOE, mss_l4len_idx);
return skb_is_gso(skb);
}
struct ixgbe_hw *hw = &adapter->hw;
struct ixgbe_fcoe *fcoe = &adapter->fcoe;
struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
-#ifdef CONFIG_IXGBE_DCB
- u8 tc;
- u32 up2tc;
-#endif
if (!fcoe->pool) {
spin_lock_init(&fcoe->lock);
IXGBE_FCRXCTRL_FCOELLI |
IXGBE_FCRXCTRL_FCCRCBO |
(FC_FCOE_VER << IXGBE_FCRXCTRL_FCOEVER_SHIFT));
-#ifdef CONFIG_IXGBE_DCB
- up2tc = IXGBE_READ_REG(&adapter->hw, IXGBE_RTTUP2TC);
- for (i = 0; i < MAX_USER_PRIORITY; i++) {
- tc = (u8)(up2tc >> (i * IXGBE_RTTUP2TC_UP_SHIFT));
- tc &= (MAX_TRAFFIC_CLASS - 1);
- if (fcoe->tc == tc) {
- fcoe->up = i;
- break;
- }
- }
-#endif
-
return;
out_extra_ddp_buffer:
return rc;
}
-#ifdef CONFIG_IXGBE_DCB
-/**
- * ixgbe_fcoe_setapp - sets the user priority bitmap for FCoE
- * @adapter : ixgbe adapter
- * @up : 802.1p user priority bitmap
- *
- * Finds out the traffic class from the input user priority
- * bitmap for FCoE.
- *
- * Returns : 0 on success otherwise returns 1 on error
- */
-u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up)
-{
- int i;
- u32 up2tc;
-
- /* valid user priority bitmap must not be 0 */
- if (up) {
- /* from user priority to the corresponding traffic class */
- up2tc = IXGBE_READ_REG(&adapter->hw, IXGBE_RTTUP2TC);
- for (i = 0; i < MAX_USER_PRIORITY; i++) {
- if (up & (1 << i)) {
- up2tc >>= (i * IXGBE_RTTUP2TC_UP_SHIFT);
- up2tc &= (MAX_TRAFFIC_CLASS - 1);
- adapter->fcoe.tc = (u8)up2tc;
- adapter->fcoe.up = i;
- return 0;
- }
- }
- }
-
- return 1;
-}
-#endif /* CONFIG_IXGBE_DCB */
-
/**
* ixgbe_fcoe_get_wwn - get world wide name for the node or the port
* @netdev : ixgbe adapter