Skip to content

Commit

Permalink
wil6210: fix report of rx packet checksum in edma mode
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ahmad Masri authored and Kalle Valo committed Apr 3, 2019
1 parent 29ca376 commit 4bf0198
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 21 deletions.
21 changes: 1 addition & 20 deletions drivers/net/wireless/ath/wil6210/txrx_edma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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;
}
Expand Down
41 changes: 40 additions & 1 deletion drivers/net/wireless/ath/wil6210/txrx_edma.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 4bf0198

Please sign in to comment.