qcacmn: Fix checksum offload logic for rx packets

Currently, hardware supports checksum offload for only ipv4, tcpv4/v6 and
udpv4/v6 packets. But driver sets checksum as CHECKSUM_UNNECESSARY for
all rx packets if tcp_udp_err and ip_err bit in rx_attention_tlv is not
set. If driver sets CHECKSUM_UNNECESSARY in skb then network stack will
not validate checksum and will reply to even wrong checksum packets
which is incorrect.

So, fix is to set checksum for all rx packets other than ipv4, tcpv4/v6 and
udpv4/v6 to CHECKSUM_NONE instead of CHECKSUM_UNNECESSARY so that network
stack validates checksum.

Change-Id: Ifb9c74fb729361da6db715fa667f926b71ce948f
CRs-Fixed: 3378925
This commit is contained in:
Surabhi Vishnoi
2023-02-13 11:14:20 +05:30
committed by Madan Koyyalamudi
parent 0be3bb02d9
commit bbae800e14
3 changed files with 28 additions and 5 deletions

View File

@@ -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

View File

@@ -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 */

View File

@@ -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;