@@ -324,14 +324,15 @@ netdev_tx_t nfp_nfd3_tx(struct sk_buff *skb, struct net_device *netdev)
/* Do not reorder - tso may adjust pkt cnt, vlan may override fields */
nfp_nfd3_tx_tso(r_vec, txbuf, txd, skb, md_bytes);
- nfp_nfd3_tx_csum(dp, r_vec, txbuf, txd, skb);
+ if (ipsec)
+ nfp_nfd3_ipsec_tx(txd, skb);
+ else
+ nfp_nfd3_tx_csum(dp, r_vec, txbuf, txd, skb);
if (skb_vlan_tag_present(skb) && dp->ctrl & NFP_NET_CFG_CTRL_TXVLAN) {
txd->flags |= NFD3_DESC_TX_VLAN;
txd->vlan = cpu_to_le16(skb_vlan_tag_get(skb));
}
- if (ipsec)
- nfp_nfd3_ipsec_tx(txd, skb);
/* Gather DMA */
if (nr_frags > 0) {
__le64 second_half;
@@ -10,9 +10,30 @@
void nfp_nfd3_ipsec_tx(struct nfp_nfd3_tx_desc *txd, struct sk_buff *skb)
{
struct xfrm_state *x = xfrm_input_state(skb);
+ struct xfrm_offload *xo = xfrm_offload(skb);
+ struct iphdr *iph = ip_hdr(skb);
+ int l4_proto;
if (x->xso.dev && (x->xso.dev->features & NETIF_F_HW_ESP_TX_CSUM)) {
- txd->flags |= NFD3_DESC_TX_CSUM | NFD3_DESC_TX_IP4_CSUM |
- NFD3_DESC_TX_TCP_CSUM | NFD3_DESC_TX_UDP_CSUM;
+ txd->flags |= NFD3_DESC_TX_CSUM;
+
+ if (iph->version == 4)
+ txd->flags |= NFD3_DESC_TX_IP4_CSUM;
+
+ if (x->props.mode == XFRM_MODE_TRANSPORT)
+ l4_proto = xo->proto;
+ else if (x->props.mode == XFRM_MODE_TUNNEL)
+ l4_proto = xo->inner_ipproto;
+ else
+ return;
+
+ switch (l4_proto) {
+ case IPPROTO_UDP:
+ txd->flags |= NFD3_DESC_TX_UDP_CSUM;
+ return;
+ case IPPROTO_TCP:
+ txd->flags |= NFD3_DESC_TX_TCP_CSUM;
+ return;
+ }
}
}