Re: Problem with checksum offloading on RPi3 (PF + Jails involved)

Hans Petter Selasky <[email protected]>
Newsgroups gmane.os.freebsd.devel.arm,gmane.os.freebsd.devel.hackers
Message-ID <[email protected]>
On 2020-11-03 09:19, Hans Petter Selasky wrote:
> It looks like smsc(4) uses the following RX format but I don't
> know actual RX format of H/W(no access to datasheet).
> 
> <---------------------------- actlen 
> -------------------------------------------------->
>                  <------------- pktlen ------------------------>
> rxhdr(4 bytes) | padding (2 bytes) | RX frame | FCS(4 bytes) | partial 
> checksum(2 bytes)

Hi,

I wonder if the checksum is zero, when not valid, and that we should 
check for this in the driver!

Can you try this patch?

Also enabling debugging in the SMSC driver would be useful.

--HPS

_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "[email protected]"
smsc.diff (text/x-patch, 2 KB)
Index: sys/dev/usb/net/if_smsc.c
===================================================================
--- sys/dev/usb/net/if_smsc.c	(revision 367268)
+++ sys/dev/usb/net/if_smsc.c	(working copy)
@@ -1020,7 +1020,7 @@
 					pktlen -= 2;
 
 					/* The checksum appears to be simplistically calculated
-					 * over the udp/tcp header and data up to the end of the
+					 * over the UDP/TCP header and data up to the end of the
 					 * eth frame.  Which means if the eth frame is padded
 					 * the csum calculation is incorrectly performed over
 					 * the padding bytes as well. Therefore to be safe we
@@ -1031,27 +1031,21 @@
 					 */
 					if ((be16toh(eh->ether_type) == ETHERTYPE_IP) &&
 					    (pktlen > ETHER_MIN_LEN)) {
-						struct ip *ip;
+						/* Copy the TCP/UDP checksum from the last 2 bytes
+						 * of the transfer and put in the csum_data field.
+						 */
+						usbd_copy_out(pc, (off + pktlen), &m->m_pkthdr.csum_data, 2);
 
-						ip = (struct ip *)(eh + 1);
-						if ((ip->ip_v == IPVERSION) &&
-						    ((ip->ip_p == IPPROTO_TCP) ||
-						     (ip->ip_p == IPPROTO_UDP))) {
+						/* The data is copied in network order, but the
+						 * csum algorithm in the kernel expects it to be
+						 * in host network order.
+						 */
+						m->m_pkthdr.csum_data = ntohs(m->m_pkthdr.csum_data);
+
+						if (m->m_pkthdr.csum_data != 0) {
 							/* Indicate the UDP/TCP csum has been calculated */
 							m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
 
-							/* Copy the TCP/UDP checksum from the last 2 bytes
-							 * of the transfer and put in the csum_data field.
-							 */
-							usbd_copy_out(pc, (off + pktlen),
-							              &m->m_pkthdr.csum_data, 2);
-
-							/* The data is copied in network order, but the
-							 * csum algorithm in the kernel expects it to be
-							 * in host network order.
-							 */
-							m->m_pkthdr.csum_data = ntohs(m->m_pkthdr.csum_data);
-
 							smsc_dbg_printf(sc, "RX checksum offloaded (0x%04x)\n",
 							                m->m_pkthdr.csum_data);
 						}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.