net/mlx5e: Fix checksum handling for non-stripped vlan packets
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_rx.c
index ee5fa16..23adfe2 100644 (file)
@@ -447,9 +447,14 @@ bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
 
        while (!mlx5_wq_ll_is_full(wq)) {
                struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(wq, wq->head);
+               int err;
 
-               if (unlikely(rq->alloc_wqe(rq, wqe, wq->head)))
+               err = rq->alloc_wqe(rq, wqe, wq->head);
+               if (unlikely(err)) {
+                       if (err != -EBUSY)
+                               rq->stats.buff_alloc_err++;
                        break;
+               }
 
                mlx5_wq_ll_push(wq, be16_to_cpu(wqe->next.next_wqe_index));
        }
@@ -538,16 +543,26 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
 
        if (lro) {
                skb->ip_summed = CHECKSUM_UNNECESSARY;
-       } else if (likely(is_first_ethertype_ip(skb))) {
+               return;
+       }
+
+       if (is_first_ethertype_ip(skb)) {
                skb->ip_summed = CHECKSUM_COMPLETE;
                skb->csum = csum_unfold((__force __sum16)cqe->check_sum);
                rq->stats.csum_sw++;
-       } else {
-               goto csum_none;
+               return;
        }
 
-       return;
-
+       if (likely((cqe->hds_ip_ext & CQE_L3_OK) &&
+                  (cqe->hds_ip_ext & CQE_L4_OK))) {
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+               if (cqe_is_tunneled(cqe)) {
+                       skb->csum_level = 1;
+                       skb->encapsulation = 1;
+                       rq->stats.csum_inner++;
+               }
+               return;
+       }
 csum_none:
        skb->ip_summed = CHECKSUM_NONE;
        rq->stats.csum_none++;
@@ -701,8 +716,10 @@ void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
        skb = napi_alloc_skb(rq->cq.napi,
                             ALIGN(MLX5_MPWRQ_SMALL_PACKET_THRESHOLD,
                                   sizeof(long)));
-       if (unlikely(!skb))
+       if (unlikely(!skb)) {
+               rq->stats.buff_alloc_err++;
                goto mpwrq_cqe_out;
+       }
 
        prefetch(skb->data);
        cqe_bcnt = mpwrq_get_cqe_byte_cnt(cqe);