From shelton@www.granch.ru  Mon Jul 17 07:53:29 2006
Return-Path: <shelton@www.granch.ru>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 0BD7516A4DA
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 17 Jul 2006 07:53:29 +0000 (UTC)
	(envelope-from shelton@www.granch.ru)
Received: from www.granch.ru (www.granch.ru [81.1.252.58])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 1715843D45
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 17 Jul 2006 07:53:27 +0000 (GMT)
	(envelope-from shelton@www.granch.ru)
Received: from www.granch.ru (IDENT:25@localhost.granch.ru [127.0.0.1])
	by www.granch.ru (8.13.4/8.13.4) with ESMTP id k6H7mWJN025477
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 17 Jul 2006 14:48:32 +0700 (NOVST)
	(envelope-from shelton@www.granch.ru)
Received: (from root@localhost)
	by www.granch.ru (8.13.4/8.13.4/Submit) id k6H7mWRf025476;
	Mon, 17 Jul 2006 14:48:32 +0700 (NOVST)
	(envelope-from shelton)
Message-Id: <200607170748.k6H7mWRf025476@www.granch.ru>
Date: Mon, 17 Jul 2006 14:48:32 +0700 (NOVST)
From: "Rashid N. Achilov" <shelton@www.granch.ru>
Reply-To: "Rashid N. Achilov" <shelton@www.granch.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: sbni drivers does not work under 5.x
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         100425
>Category:       kern
>Synopsis:       [sbni] [patch] sbni drivers does not work under 5.x
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    jhb
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jul 17 08:00:34 GMT 2006
>Closed-Date:    Wed Sep 17 20:19:21 UTC 2008
>Last-Modified:  Wed Sep 17 20:19:21 UTC 2008
>Originator:     Rashid N. Achilov
>Release:        FreeBSD 5.5-PRERELEASE i386
>Organization:
>Environment:
System: FreeBSD www.granch.ru 5.5-PRERELEASE FreeBSD 5.5-PRERELEASE #2: Thu May 18 19:26:36 NOVST 2006 shelton@www.granch.ru:/usr/obj/usr/src/sys/Proxy i386
>Description:
Driver for device sbni does not work correctly under 5.4 and high. When
connect between two devices established (with any OS - FreeBSD, linux,
Windows), all incoming packets qualified as 'bad' and drop down.  So, data
exchange is impossible.  A trouble source is a calc_crc32 procedure, which
was sometime written by ASM insertions.  GCC 3.x produced code, which calcs
CRC incorrectly, so calc_crc32 decline ALL incoming packets.  A sbni driver 
as also (still unusable) C-sourced calc_crc32 procedure.  When I have
switched to use it, driver start to work.
>How-To-Repeat:
Install a couple sbni devices at a couple boxes, one side with FreeBSD 5.x,
two with any other supported system. Install sbni device into a kernel or
load kernel module.  Install sbniconfig utility.  Connect devices.  You can
see in a sbniconfig output, that "rx" will increased, and "bad rx" will
increased too and all received packets will 'bad'.
>Fix:
Go to /usr/src/sys and appy this patch
--- modules/sbni/Makefile	Thu Nov 22 04:29:35 2001
+++ Makefile.new	Mon Jul 17 14:10:21 2006
@@ -7,4 +7,7 @@

 SRCS+=	bus_if.h device_if.h isa_if.h pci_if.h

+# To build with lost of debug messages, uncomment here
+#CFLAGS += -DDEBUG
+
 .include <bsd.kmod.mk>
--- dev/sbni/if_sbni.c	Sun Jan 30 07:00:01 2005
+++ if_sbni.c.new	Fri Jul 14 12:35:47 2006
@@ -57,6 +57,9 @@
  * Revision 4.1 2001/01/21
  * Support for PCI Dual cards and new SBNI12D-10, -11 Dual/ISA cards
  *
+ * Revision 4.2 2006/07/12 by Rashid N. "CityCat" Achilov
+ * Incorrect checksum calculation under 5.x eliminated
+ *
  * Written with reference to NE2000 driver developed by David Greenman.
  */

@@ -84,7 +87,12 @@
 #include <dev/sbni/if_sbnireg.h>
 #include <dev/sbni/if_sbnivar.h>

+/* In 5.x ASM source for CRC caclulations produced incorrect CRC check */
+#if __FreeBSD_version < 500000
 #define ASM_CRC 1
+#else
+#undef ASM_CRC
+#endif

 static void	sbni_init(void *);
 static void	sbni_start(struct ifnet *);
@@ -374,7 +382,7 @@
 		 */
 		csr0 = sbni_inb(sc, CSR0);
 		if ((csr0 & TR_RDY) == 0 || (csr0 & RC_RDY) != 0)
-			printf("sbni: internal error!\n");
+		  printf("sbni: incorrect state, TR not ready, but RC ready\n");

 		/* if state & FL_NEED_RESEND != 0 then tx_frameno != 0 */
 		if (req_ans || sc->tx_frameno != 0)
@@ -406,21 +414,41 @@
 		frame_ok = framelen > 4 ?
 		    upload_data(sc, framelen, frameno, is_first, crc) :
 		    skip_tail(sc, framelen, crc);
+#ifdef DEBUG
+		printf("[RF]header OK, frame_ok=%d, framelen=%d\n",frame_ok,framelen);
+#endif
 		if (frame_ok)
 			interpret_ack(sc, ack);
 	} else
+            {
+#ifdef DEBUG
+              printf("[RF]Header BAD!\n");
+#endif
 		frame_ok = 0;
+            }

 	sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) ^ CT_ZER);
 	if (frame_ok) {
+#ifdef DEBUG
+                printf("[RF]Good: frame_ok=%d,framelen=%d\n",frame_ok,framelen);
+#endif
 		sc->state |= FL_PREV_OK;
 		if (framelen > 4)
+                  {
 			sc->in_stats.all_rx_number++;
+#ifdef DEBUG
+                    printf("[RF]Good: received: %d\n",sc->in_stats.all_rx_number);
+#endif
+                  }
 	} else {
 		sc->state &= ~FL_PREV_OK;
 		change_level(sc);
 		sc->in_stats.all_rx_number++;
 		sc->in_stats.bad_rx_number++;
+#ifdef DEBUG
+                printf("[RF]Bad: received all: %d\n",sc->in_stats.all_rx_number);
+                printf("[RF]Bad: received bad: %d\n",sc->in_stats.bad_rx_number);
+#endif
 	}

 	return (!frame_ok || framelen > 4);
@@ -548,29 +576,46 @@

 		if (sc->inppos + framelen  <=  ETHER_MAX_LEN) {
 			frame_ok = append_frame_to_pkt(sc, framelen, crc);
+#ifdef DEBUG
+                        printf("[UD]Append frame,frame_ok=%d\n",frame_ok);
+#endif

 		/*
 		 * if CRC is right but framelen incorrect then transmitter
 		 * error was occured... drop entire packet
 		 */
 		} else if ((frame_ok = skip_tail(sc, framelen, crc)) != 0) {
+#ifdef DEBUG
+                        printf("[UD]CRC OK, but framelen incorrect\n");
+#endif
 			sc->wait_frameno = 0;
 			sc->inppos = 0;
 			sc->arpcom.ac_if.if_ierrors++;
 			/* now skip all frames until is_first != 0 */
 		}
 	} else
+            {
 		frame_ok = skip_tail(sc, framelen, crc);
+#ifdef DEBUG
+              printf("[UD]sc->wait_frameno=%d != frameno=%d\n",sc->wait_frameno,frameno);
+#endif
+            }

 	if (is_first && !frame_ok) {
 		/*
 		 * Frame has been violated, but we have stored
 		 * is_first already... Drop entire packet.
 		 */
+#ifdef DEBUG
+                printf("[UD]is_first (%ud) && !frame_ok (%d)\n",is_first,frame_ok);
+#endif
 		sc->wait_frameno = 0;
 		sc->arpcom.ac_if.if_ierrors++;
 	}

+#ifdef DEBUG
+        printf("[UD]returning frame_ok=%d\n",frame_ok);
+#endif
 	return (frame_ok);
 }

@@ -620,15 +665,30 @@
 	caddr_t p;

 	if (sc->inppos + framelen > ETHER_MAX_LEN)
+          {
+#ifdef DEBUG
+            printf("[AF]sc->inppos + framelen (%d) > ETHER_MAX\n",sc->inppos + framelen);
+#endif
 		return (0);
+          }

 	if (!sc->rx_buf_p && !get_rx_buf(sc))
+          {
+#ifdef DEBUG
+            printf("[AF]Cannot get RX buffer\n");
+#endif
 		return (0);
+          }

 	p = sc->rx_buf_p->m_data + sc->inppos;
 	sbni_insb(sc, p, framelen);
 	if (calc_crc32(crc, p, framelen) != CRC32_REMAINDER)
+          {
+#ifdef DEBUG
+            printf("[AF]calc_crc32 != CRC32_REMAINDER\n");
+#endif
 		return (0);
+          }

 	sc->inppos += framelen - 4;
 	if (--sc->wait_frameno == 0) {		/* last frame received */
@@ -636,6 +696,9 @@
 		sc->arpcom.ac_if.if_ipackets++;
 	}

+#ifdef DEBUG
+        printf("[AF]Append OK, sc->inppos = %d\n",sc->inppos);
+#endif
 	return (1);
 }

@@ -1144,8 +1207,10 @@

 /* -------------------------------------------------------------------------- */

+/* Beware! Under 5.x ASM code produced incorrect CRC!, so you MUST	*
+ * use C procedure for CRC calculations. So, this code will in play	*
+ * only under 4.x							*/
 #ifdef ASM_CRC
-
 static u_int32_t
 calc_crc32(u_int32_t crc, caddr_t p, u_int len)
 {
@@ -1223,7 +1288,6 @@

 	return (_crc);
 }
-
 #else	/* ASM_CRC */

 static u_int32_t

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Fri Jul 4 23:48:16 UTC 2008 
State-Changed-Why:  
This PR has been obsoleted by subsequent events: 

There has been a pass through many drivers to try to make them MPSAFE. 
Although jhb did the work to do this, no one volunteered to step up and 
test the fixed code. 

He committed the fixed (but untested) code, for posterity, in: 

200807042053.m64Krwuj077486@repoman.freebsd.org 

and then right afterwards deleted it from -current: 

200807042114.m64LEqbU080477@repoman.freebsd.org 

If anyone wishes to test/revive this driver, that is where they should 
start. 


Responsible-Changed-From-To: freebsd-bugs->linimon 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Fri Jul 4 23:48:16 UTC 2008 
Responsible-Changed-Why:  
Track possible followups with bugmeister hat on. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100425 
State-Changed-From-To: closed->patched 
State-Changed-By: jhb 
State-Changed-When: Wed Sep 10 18:42:30 UTC 2008 
State-Changed-Why:  
Fixed in HEAD (now that the sbni driver in HEAD is confirmed to work with 
this patch).  Will MFC in a week or so. 


Responsible-Changed-From-To: linimon->jhb 
Responsible-Changed-By: jhb 
Responsible-Changed-When: Wed Sep 10 18:42:30 UTC 2008 
Responsible-Changed-Why:  
Fixed in HEAD (now that the sbni driver in HEAD is confirmed to work with 
this patch).  Will MFC in a week or so. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100425 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/100425: commit references a PR
Date: Wed, 10 Sep 2008 18:44:33 +0000 (UTC)

 jhb         2008-09-10 18:42:19 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/dev/sbni         if_sbni.c 
   Log:
   SVN rev 182913 on 2008-09-10 18:42:19Z by jhb
   
   Disable the inline assembly crc32 routine and use the C version instead.
   The assembly version is reported to be broken on 5.x+.
   
   PR:             kern/100425
   Submitted by:   Rashid N. Achilov  shelton www.granch.ru
   MFC after:      1 week
   
   Revision  Changes    Path
   1.28      +0 -87     src/sys/dev/sbni/if_sbni.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: jhb 
State-Changed-When: Wed Sep 17 20:18:59 UTC 2008 
State-Changed-Why:  
Fix merged to 6.x and 7.x. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100425 
>Unformatted:
