summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Masri <amasri@codeaurora.org>2019-02-28 10:34:59 +0100
committerKalle Valo <kvalo@codeaurora.org>2019-04-03 14:44:38 +0200
commit4bf019865cf327df2fed403d35bb36ecb6617e8a (patch)
tree7f325f59b9f3c946b53e8431d806012022115dd9
parentwil6210: free edma_rx_swtail upon reset (diff)
downloadlinux-4bf019865cf327df2fed403d35bb36ecb6617e8a.tar.xz
linux-4bf019865cf327df2fed403d35bb36ecb6617e8a.zip
wil6210: fix report of rx packet checksum in edma mode
Update the rx packet checksum of received packet according to edma HW spec: No need to calculate checksum in the following cases: L4_status=0 and L3_status=0 - No L3 and no L4 known protocols found L4_status=0 and L3_status=1 - L3 was found, and checksum check passed. No known L4 protocol was found. L4_status=1 - L4 was found, and checksum check passed. Recalculate checksum in the following cases: L4_status=3 and L3_status=1 - It means that L3 protocol was found, and checksum passed, but L4 checksum failed. L4_status=3 and L3_status=2 - Both L3 and L4 checksum check failed. Signed-off-by: Ahmad Masri <amasri@codeaurora.org> Signed-off-by: Maya Erez <merez@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx_edma.c21
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx_edma.h41
2 files changed, 41 insertions, 21 deletions
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c
index 48098ae62677..492f7bdf39d9 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.c
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c
@@ -807,18 +807,9 @@ static int wil_rx_error_check_edma(struct wil6210_priv *wil,
struct sk_buff *skb,
struct wil_net_stats *stats)
{
- int error;
int l2_rx_status;
- int l3_rx_status;
- int l4_rx_status;
void *msg = wil_skb_rxstatus(skb);
- error = wil_rx_status_get_error(msg);
- if (!error) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- return 0;
- }
-
l2_rx_status = wil_rx_status_get_l2_rx_status(msg);
if (l2_rx_status != 0) {
wil_dbg_txrx(wil, "L2 RX error, l2_rx_status=0x%x\n",
@@ -847,17 +838,7 @@ static int wil_rx_error_check_edma(struct wil6210_priv *wil,
return -EFAULT;
}
- l3_rx_status = wil_rx_status_get_l3_rx_status(msg);
- l4_rx_status = wil_rx_status_get_l4_rx_status(msg);
- if (!l3_rx_status && !l4_rx_status)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- /* If HW reports bad checksum, let IP stack re-check it
- * For example, HW don't understand Microsoft IP stack that
- * mis-calculates TCP checksum - if it should be 0x0,
- * it writes 0xffff in violation of RFC 1624
- */
- else
- stats->rx_csum_err++;
+ skb->ip_summed = wil_rx_status_get_checksum(msg, stats);
return 0;
}
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h
index 343516a03a1e..9cf9ecf6e8cf 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.h
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016,2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016,2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -511,6 +511,45 @@ static inline int wil_rx_status_get_l4_rx_status(void *msg)
5, 6);
}
+/* L4 L3 Expected result
+ * 0 0 Ok. No L3 and no L4 known protocols found.
+ * Treated as L2 packet. (no offloads on this packet)
+ * 0 1 Ok. It means that L3 was found, and checksum check passed.
+ * No known L4 protocol was found.
+ * 0 2 It means that L3 protocol was found, and checksum check failed.
+ * No L4 known protocol was found.
+ * 1 any Ok. It means that L4 was found, and checksum check passed.
+ * 3 0 Not a possible scenario.
+ * 3 1 Recalculate. It means that L3 protocol was found, and checksum
+ * passed. But L4 checksum failed. Need to see if really failed,
+ * or due to fragmentation.
+ * 3 2 Both L3 and L4 checksum check failed.
+ */
+static inline int wil_rx_status_get_checksum(void *msg,
+ struct wil_net_stats *stats)
+{
+ int l3_rx_status = wil_rx_status_get_l3_rx_status(msg);
+ int l4_rx_status = wil_rx_status_get_l4_rx_status(msg);
+
+ if (l4_rx_status == 1)
+ return CHECKSUM_UNNECESSARY;
+
+ if (l4_rx_status == 0 && l3_rx_status == 1)
+ return CHECKSUM_UNNECESSARY;
+
+ if (l3_rx_status == 0 && l4_rx_status == 0)
+ /* L2 packet */
+ return CHECKSUM_NONE;
+
+ /* If HW reports bad checksum, let IP stack re-check it
+ * For example, HW doesn't understand Microsoft IP stack that
+ * mis-calculates TCP checksum - if it should be 0x0,
+ * it writes 0xffff in violation of RFC 1624
+ */
+ stats->rx_csum_err++;
+ return CHECKSUM_NONE;
+}
+
static inline int wil_rx_status_get_security(void *msg)
{
return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d0,