Subject: Re: sk(4) problems on the AlphaServer ES40...
To: NetBSD/alpha Discussion List <port-alpha@NetBSD.ORG>
From: Greg A. Woods <woods@planix.com>
List: tech-net
Date: 12/16/2004 18:58:42
[ On Tuesday, December 7, 2004 at 22:19:39 (-0500), Greg A. Woods wrote: ]
> Subject: sk(4) problems on the AlphaServer ES40...
>
> Well things aren't looking so good for the sk(4) driver on the ES40
> either.  We managed to source a D-Link Systems DGE-530T card to test as
> well, and it is at least recognized:

A "real" SysKonnect SK-9821 card fairs no better than the D-Link card.

	[console]<@> # dmesg | fgrep sk
	skc0 at pci1 dev 1 function 0: dec 6600 irq 24
	skc0: SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter rev. (0x1)
	sk0 at skc0 port A: Ethernet address 00:00:5a:9c:df:55
	makphy0 at sk0 phy 0: Marvell 88E1011 Gigabit PHY, rev. 3

It will link up and can receive packets in promiscuous mode, just like
the DGE-530T, but it cannot send, and when it is brought down and back
up again it fails re-initialization just like the DGE-530T did:

	[console]<@> # ifconfig sk0 down
	[console]<@> # netstat -in       
	Name  Mtu   Network       Address              Ipkts Ierrs    Opkts Oerrs Colls
	tlp0* 1500  <Link>        08:00:2b:c4:b5:26        0     0        0     0     0
	sk0*  1500  <Link>        00:00:5a:9c:df:55       45     0        0     0     0
	sk0*  1500  10.10.10/24   10.10.10.2              45     0        0     0     0
	wm0*  1500  <Link>        00:0e:0c:5a:ee:9d        0     0        0     0     0
	tlp1* 1500  <Link>        08:00:2b:c4:7a:70        0     0        0     0     0
	bge0* 1500  <Link>        00:08:02:91:89:ae        0     0        0     0     0
	lo0   33136 <Link>                                50     0       50     0     0
	lo0   33136 127           127.0.0.1               50     0       50     0     0
	[console]<@> # ifconfig sk0 up
	sk0: failed alloc of 0th mbuf
	sk0: initialization failed: no memory for rx buffers
	sk0: failed alloc of 0th mbuf
	sk0: initialization failed: no memory for rx buffers


So, I thought I'd have a go at trying to make a similar fix to if_sk.c
as Jason suggested for if_bge.c when it was behaving similarly,
especially since the code looked so much the same between the two
drivers.

And so I've come up with the following patch:

Index: sys/dev/pci/if_sk.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/sys/dev/pci/if_sk.c,v
retrieving revision 1.12
diff -u -r1.12 if_sk.c
--- sys/dev/pci/if_sk.c	30 Oct 2004 18:09:22 -0000	1.12
+++ sys/dev/pci/if_sk.c	16 Dec 2004 23:35:18 -0000
@@ -781,8 +781,7 @@
 			       sc_if->sk_dev.dv_xname);
 			return(ENOMEM);
 		}
-	} else if (m == NULL)
-		bus_dmamap_unload(sc->sc_dmatag, dmamap);
+	}
 
 	sc_if->sk_cdata.sk_rx_map[i] = dmamap;
 
@@ -805,9 +804,6 @@
 
 		m_adj(m_new, ETHER_ALIGN);
 
-		if (bus_dmamap_load_mbuf(sc->sc_dmatag, dmamap, m_new,
-					 BUS_DMA_NOWAIT))
-			return(ENOBUFS);
 	} else {
 		/*
 	 	 * We're re-using a previously allocated mbuf;
@@ -819,6 +815,9 @@
 		m_adj(m_new, ETHER_ALIGN);
 		m_new->m_data = m_new->m_ext.ext_buf;
 	}
+	if (bus_dmamap_load_mbuf(sc->sc_dmatag, dmamap, m_new,
+				 BUS_DMA_READ|BUS_DMA_NOWAIT))
+		return(ENOBUFS);	/* panic() ala if_bge? */
 
 	c = &sc_if->sk_cdata.sk_rx_chain[i];
 	r = c->sk_desc;
@@ -1837,6 +1836,8 @@
 
 		SK_INC(i, SK_RX_RING_CNT);
 
+		bus_dmamap_unload(sc_if->sk_softc->sc_dmatag, dmamap);
+
 		if (rxstat & XM_RXSTAT_ERRFRAME) {
 			ifp->if_ierrors++;
 			sk_newbuf(sc_if, cur, m, dmamap);
@@ -2537,16 +2538,16 @@
 
 	/* Init descriptors */
 	if (sk_init_rx_ring(sc_if) == ENOBUFS) {
-		printf("%s: initialization failed: no "
-		    "memory for rx buffers\n", sc_if->sk_dev.dv_xname);
+		printf("%s: initialization failed: "
+		    "no memory for rx buffers\n", sc_if->sk_dev.dv_xname);
 		sk_stop(ifp,0);
 		splx(s);
 		return(ENOBUFS);
 	}
 
 	if (sk_init_tx_ring(sc_if) == ENOBUFS) {
-		printf("%s: initialization failed: no "
-		    "memory for tx buffers\n", sc_if->sk_dev.dv_xname);
+		printf("%s: initialization failed: "
+		    "no memory for tx buffers\n", sc_if->sk_dev.dv_xname);
 		sk_stop(ifp,0);
 		splx(s);
 		return(ENOBUFS);

(those last two changes make it a bit easier to find the error message!
People should learn to code with wider windows or better editors and
quit all this silly unnecessary wrapping of code!)

and what do you know but it works!  though not very fast.....

	[console]<@> # ttcp -v -t -s -n 100000 10.10.10.1
	ttcp-t: buflen=8192, nbuf=100000, align=16384/0, port=5001  tcp  -> 10.10.10.1
	ttcp-t: socket
	ttcp-t: connect
	ttcp-t: 819200000 bytes in 40.59 real seconds = 19709.66 KB/sec +++
	ttcp-t: 819200000 bytes in 40.55 CPU seconds = 19726.60 KB/cpu sec
	ttcp-t: 100000 I/O calls, msec/call = 0.42, calls/sec = 2463.71
	ttcp-t: 0.0user 40.4sys 0:40real 99% 0i+0d 0maxrss 0+100001pf 9+450csw
	ttcp-t: buffer address 0x20050000

and apparently without any hardware checksum offloading capability:

	[console]<@> # ifconfig sk0
	sk0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	        address: 00:00:5a:9c:df:55
	        media: Ethernet autoselect (1000baseT full-duplex)
	        status: active
	        inet 10.10.10.2 netmask 0xffffff00 broadcast 10.10.10.255

No wonder the manual page is self-contradicting on this matter....


So, now, maybe I should go back to the bge(4) driver and see if I can
make it go faster.....

-- 
						Greg A. Woods

+1 416 218-0098                  VE3TCP            RoboHack <woods@robohack.ca>
Planix, Inc. <woods@planix.com>          Secrets of the Weird <woods@weird.com>