Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1017760 authored by Ahmad Masri's avatar Ahmad Masri Committed by Maya Erez
Browse files

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: default avatarAhmad Masri <amasri@codeaurora.org>
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Git-commit: 4bf019865cf327df2fed403d35bb36ecb6617e8a
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git


[merez@codeaurora.org: SPDX license conflict]
Change-Id: Id0a525b78ea37f41dad599a5d1d014cd284e57a0
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
parent fa4615c1
Loading
Loading
Loading
Loading
+1 −20
Original line number Diff line number Diff line
@@ -826,18 +826,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",
@@ -866,17 +857,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;
}
+39 −0
Original line number Diff line number Diff line
@@ -505,6 +505,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,