diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 77c5859343..2797ea25ef 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -2542,13 +2542,33 @@ void dp_rx_cksum_offload(struct dp_pdev *pdev, hal_rx_tlv_csum_err_get(pdev->soc->hal_soc, rx_tlv_hdr, &ip_csum_err, &tcp_udp_csum_er); - if (qdf_likely(!ip_csum_err && !tcp_udp_csum_er)) { - cksum.l4_result = QDF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY; - qdf_nbuf_set_rx_cksum(nbuf, &cksum); + if (qdf_nbuf_is_ipv4_pkt(nbuf)) { + if (qdf_likely(!ip_csum_err)) { + cksum.l4_result = QDF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY; + if (qdf_nbuf_is_ipv4_udp_pkt(nbuf) || + qdf_nbuf_is_ipv4_tcp_pkt(nbuf)) { + if (qdf_likely(!tcp_udp_csum_er)) + cksum.csum_level = 1; + else + DP_STATS_INCC(pdev, + err.tcp_udp_csum_err, 1, + tcp_udp_csum_er); + } + } else { + DP_STATS_INCC(pdev, err.ip_csum_err, 1, ip_csum_err); + } + } else if (qdf_nbuf_is_ipv6_udp_pkt(nbuf) || + qdf_nbuf_is_ipv6_tcp_pkt(nbuf)) { + if (qdf_likely(!tcp_udp_csum_er)) + cksum.l4_result = QDF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY; + else + DP_STATS_INCC(pdev, err.tcp_udp_csum_err, 1, + tcp_udp_csum_er); } else { - DP_STATS_INCC(pdev, err.ip_csum_err, 1, ip_csum_err); - DP_STATS_INCC(pdev, err.tcp_udp_csum_err, 1, tcp_udp_csum_er); + cksum.l4_result = QDF_NBUF_RX_CKSUM_NONE; } + + qdf_nbuf_set_rx_cksum(nbuf, &cksum); } #else static inline diff --git a/qdf/inc/qdf_net_types.h b/qdf/inc/qdf_net_types.h index 4cb797ab13..3cf00039ab 100644 --- a/qdf/inc/qdf_net_types.h +++ b/qdf/inc/qdf_net_types.h @@ -275,11 +275,13 @@ typedef enum { * typedef qdf_nbuf_rx_cksum_t - receive checksum type * @l4_type: L4 type * @l4_result: L4 result + * @csum_level: indicates number of checksum are calculated */ typedef struct { qdf_nbuf_l4_rx_cksum_type_t l4_type; qdf_nbuf_l4_rx_cksum_result_t l4_result; uint32_t val; + uint32_t csum_level; } qdf_nbuf_rx_cksum_t; #define QDF_ARP_REQ 1 /* ARP request */ diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 05a37f1176..d247f34869 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -1276,6 +1276,7 @@ __qdf_nbuf_set_rx_cksum(struct sk_buff *skb, qdf_nbuf_rx_cksum_t *cksum) break; case QDF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY: skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->csum_level = cksum->csum_level; break; case QDF_NBUF_RX_CKSUM_TCP_UDP_HW: skb->ip_summed = CHECKSUM_PARTIAL;