Subject: kern/14237: patch for wireless NIC
To: None <gnats-bugs@gnats.netbsd.org>
From: None <alfred@freebsd.org>
List: netbsd-bugs
Date: 10/12/2001 22:07:34
>Number:         14237
>Category:       kern
>Synopsis:       Addtron wireless fails to read MAC/probe
>Confidential:   no
>Severity:       non-critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Oct 13 05:14:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Alfred Perlstein <alfred@freebsd.org>
>Release:        NetBSD 1.5.2
>Organization:
QuartetNS
	
>Environment:
Dell Inspiron 4000 (i386), netbsd 1.5.3

	
System: NetBSD frodo 1.5.3_ALPHA NetBSD 1.5.3_ALPHA (FRODO) #1: Fri Oct 12 21:40:19 PDT 2001 root@frodo:/usr/src/sys/arch/i386/compile/FRODO i386


>Description:
	My Wavelan style card doesn't init.
>How-To-Repeat:
	Go to Frys, get "Addtron" brand wireless NIC, try it on NetBSD
        1.5.2.  It will fail to "init" and get the mac addess.
>Fix:

I don't know if the sys/dev/ic/wi.c in netbsd-current addresses this,
it looks like it may as it has DELAY calls close to the same place
that this patch inserts delays.

I basically stole this from the FreeBSD driver.

Index: if_wi.c
===================================================================
RCS file: /vol/nfs/home/cvs/netcvs/syssrc/sys/dev/pcmcia/Attic/if_wi.c,v
retrieving revision 1.21.2.9
diff -u -r1.21.2.9 if_wi.c
--- if_wi.c	2001/05/26 16:10:03	1.21.2.9
+++ if_wi.c	2001/10/13 04:39:41
@@ -352,7 +352,10 @@
 	/* Read the station address. */
 	mac.wi_type = WI_RID_MAC_NODE;
 	mac.wi_len = 4;
-	wi_read_record(sc, (struct wi_ltv_gen *)&mac);
+	if (wi_read_record(sc, (struct wi_ltv_gen *)&mac) != 0) {
+		printf("mac read failed\n");
+		goto bad_enaddr;
+	}
 	memcpy(sc->sc_macaddr, mac.wi_mac_addr, ETHER_ADDR_LEN);
 
 	/*
@@ -731,7 +734,18 @@
 {
 	int			i, s = 0;
 
+	/* wait for the busy bit to clear */
+	for (i = 500; i > 0; i--) {     /* 5s */
+		if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
+			break;
+		DELAY(10*1000); /* 10 m sec */
+	}
+	if (i == 0)
+		return(ETIMEDOUT);
+
 	CSR_WRITE_2(sc, WI_PARAM0, val);
+	CSR_WRITE_2(sc, WI_PARAM1, 0);
+	CSR_WRITE_2(sc, WI_PARAM2, 0);
 	CSR_WRITE_2(sc, WI_COMMAND, cmd);
 
 	for (i = 0; i < WI_TIMEOUT; i++) {
@@ -763,8 +777,17 @@
 static void wi_reset(sc)
 	struct wi_softc		*sc;
 {
-	if (wi_cmd(sc, WI_CMD_INI, 0))
+#define WI_INIT_TRIES 5
+	int i;
+	
+	for (i = 0; i < WI_INIT_TRIES; i++) {
+		if (wi_cmd(sc, WI_CMD_INI, 0) == 0)
+			break;
+		DELAY(50 * 1000);	/* 50ms */
+	}
+	if (i == WI_INIT_TRIES)
 		printf("%s: init failed\n", sc->sc_dev.dv_xname);
+ 
 	CSR_WRITE_2(sc, WI_INT_EN, 0);
 	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
 
>Release-Note:
>Audit-Trail:
>Unformatted: