diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_fcoe.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_fcoe.c | 85 |
1 files changed, 31 insertions, 54 deletions
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index f5f39edb86ab..9c20077dd44b 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -474,24 +474,18 @@ ddp_out: * * 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; } @@ -501,23 +495,22 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, 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; } @@ -530,12 +523,11 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, 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; @@ -544,7 +536,7 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, 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; } @@ -553,43 +545,28 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, 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); } |