@@ -296,6 +296,7 @@ enum {
MLX5E_RQ_STATE_ENABLED,
MLX5E_RQ_STATE_AM,
MLX5E_RQ_STATE_NO_CSUM_COMPLETE,
+ MLX5E_RQ_STATE_CSUM_FULL, /* cqe_csum_full hw bit is set */
};
#define MLX5E_TEST_BIT(state, nr) (state & BIT(nr))
@@ -925,6 +925,9 @@ static int mlx5e_open_rq(struct mlx5e_channel *c,
if (params->rx_am_enabled)
c->rq.state |= BIT(MLX5E_RQ_STATE_AM);
+ if (MLX5_CAP_ETH(c->mdev, cqe_checksum_full))
+ __set_bit(MLX5E_RQ_STATE_CSUM_FULL, &c->rq.state);
+
/* We disable csum_complete when XDP is enabled since
* XDP programs might manipulate packets which will render
* skb->checksum incorrect.
@@ -770,8 +770,14 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
if (unlikely(get_ip_proto(skb, network_depth, proto) == IPPROTO_SCTP))
goto csum_unnecessary;
+ rq->stats.csum_complete++;
skb->ip_summed = CHECKSUM_COMPLETE;
skb->csum = csum_unfold((__force __sum16)cqe->check_sum);
+
+ if (test_bit(MLX5E_RQ_STATE_CSUM_FULL, &rq->state))
+ return; /* CQE csum covers all received bytes */
+
+ /* csum might need some fixups ...*/
if (network_depth > ETH_HLEN)
/* CQE csum is calculated from the IP header and does
* not cover VLAN headers (if present). This will add
@@ -781,7 +787,6 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
network_depth - ETH_HLEN,
skb->csum);
mlx5e_skb_padding_csum(skb, network_depth, proto, &rq->stats);
- rq->stats.csum_complete++;
return;
}
@@ -614,7 +614,8 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
u8 swp[0x1];
u8 swp_csum[0x1];
u8 swp_lso[0x1];
- u8 reserved_at_23[0x1b];
+ u8 cqe_checksum_full[0x1];
+ u8 reserved_at_24[0x1a];
u8 max_geneve_opt_len[0x1];
u8 tunnel_stateless_geneve_rx[0x1];