Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Feb 2001 19:41:44 +0100
From:      Gerhard Sittig <Gerhard.Sittig@gmx.net>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   misc/25147: [PATCH] to make D-Link DFE-650 work with -STABLE
Message-ID:  <20010216194144.A20830@speedy.gsinet>

next in thread | raw e-mail | index | archive | help

>Number:         25147
>Category:       misc
>Synopsis:       [PATCH] to make D-Link DFE-650 work with -STABLE
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 16 11:00:01 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Gerhard Sittig
>Release:        FreeBSD 4.2-STABLE i386
>Organization:
System Defenestrators Inc.
>Environment:

Toshiba Satellite 210CS notebook
D-Link DFE-650 NIC
noname switch

>Description:

The above card gets recognized, but refuses to work.  All the
LEDs at the connector are constantly blinking (slowly) while the
card never gets to the state of being useful.  Trying to operate
the card all one will get is "/kernel: edN: device timeout" lines
in /var/llog/messages.

>How-To-Repeat:

I've seen this behaviour with -CURRENT snapshot boot floppies as
of early January as well as on -STABLE as of mid January.  Recent
threads in -current show that the problem still exists (see
Julian Elischer's message <3A8AA8D4.A3E73136@elischer.org>).  And
I haven't seen any related commits since the ed(4) extension with
the Linksys flag on December 18th (-CURRENT) or January 17th
(-STABLE).

>Fix:

http://www.freebsddiary.org/last-netgear.html talks about an
fa_select.c tool to force media selection while the card seems to
fail in negotiating this.  Tests proved the tool to make the
above card work.  And I assume it does for Netgear's FA410TX,
too.

Since I didn't like the need to hardcode and compile the i/o
address into the utility, I changed the code a little bit to scan
command line options (see the patch below, Q&D for minimal
diffs).  To further reduce manual action I made pccardd(8)
resolve the i/o address in pccard.conf just like it does with the
device name and ethernet address (another patch below; and one
could think of exporting even more potentially useful data).  So
one can have pccardd detect the card's presence and have it run
fa_select on it before doing ifconfig(8) actions.  The
pccard.conf code snippet (third part) has the glue logic.

I'm aware of the fact that the doc patches are missing, but I
just wanted that thing to work.  UNIX is not nearly the same when
the machine lacks networking support! :>


--- fa_select.c.orig	Thu Feb 15 23:29:43 2001
+++ fa_select.c.work	Thu Feb 15 23:29:53 2001
@@ -12,7 +12,7 @@
 #include <unistd.h>
 #include <machine/sysarch.h>
 
-#define BASE_ADDR	0x240 /* replace with the card base address */
+#define BASE_ADDR_DFLT	0x240 /* fallback */
 
 
 inline unsigned char
@@ -159,24 +170,92 @@
     write_bit(port, 1);
     return 0;
 }
+
+char *
+mediatext(int m)
+{
+  switch(m) {
+  case 0 : return "10BaseT"    ; break;
+  case 1 : return "10BaseT FD" ; break;
+  case 2 : return "100BaseT"   ; break;
+  default: return "100BaseT FD"; break;
+  }
+}
+
 int 
 main(int argc, char **argv)
 {
-    int skfd, i, sub;
+    int skfd, sub;
     struct ifreq ifr;
+    int c;
+    int BASE_ADDR = BASE_ADDR_DFLT;
+    char *iface = NULL;
+    int media = 0;
+    int vflag = 0;
+    int tflag = 0;
+
+#if defined(DEBUG)
+    vflag++;
+#endif
+
+    /* usual getopt loop */
+    while (-1 != (c = getopt(argc, argv, "b:i:m:tv"))) {
+      switch(c) {
+      case 'b':
+	BASE_ADDR = strtoul(optarg, NULL, 0);
+	break;
+      case 'i':
+	iface = optarg;
+	break;
+      case 'm':
+	media = atoi(optarg);
+	break;
+      case 't':
+	tflag++;
+	break;
+      case 'v':
+	vflag++;
+	break;
+      default:
+	exit(1);
+      }
+    }
+
+    /* "traditional" (positional) interpretation */
+    if (optind < argc) {
+      iface = argv[optind];
+      optind++;
+    }
+    if (optind < argc) {
+      media = atoi(argv[optind]);
+      optind++;
+    }
+
+    /* sanity check */
+    if (optind < argc)
+      err(1, "too many parameters");
+    if (! iface)
+      err(1, "no interface");
+    if (! BASE_ADDR)
+      err(1, "no base address");
+
+    /* special treatment for -v and -t */
+    if (vflag)
+      printf("switching interface \"%s\" at addr 0x%04X to media %d (%s)\n",
+	   iface, BASE_ADDR, media, mediatext(media));
+    if (tflag) {
+      printf("test mode, bailing out with no further action\n");
+      exit(0);
+    }
     
     skfd = sockets_open();
     if (skfd == -1) {
 	perror("socket");
 	exit(1);
     }
-    strcpy(ifr.ifr_name, argv[1]);
-/*    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
-	perror("ioctl");
-	exit(1);
-    }*/
-    i = atoi(argv[2]);
-    switch(i) {
+
+    strcpy(ifr.ifr_name, iface);
+    switch(media) {
     case 0:
 	sub = 0x0000;
 	break;


Index: pccardd/util.c
===================================================================
RCS file: /CVSREPO/fbsd/src/usr.sbin/pccard/pccardd/util.c,v
retrieving revision 1.13.2.3
diff -u -r1.13.2.3 util.c
--- pccardd/util.c	2000/10/15 04:12:45	1.13.2.3
+++ pccardd/util.c	2001/02/15 21:59:57
@@ -237,8 +237,8 @@
 			/* copy over preceding string. */
 			while (lp != p)
 				*cp++ = *lp++;
-			/* stringify ethernet address and place here. */
 			if (strncmp(p, "$ether", 6) == 0) {
+			/* stringify ethernet address and place here. */
 				sprintf(cp, "%x:%x:%x:%x:%x:%x",
 				    sp->eaddr[0],
 				    sp->eaddr[1],
@@ -249,18 +249,36 @@
 				while (*++cp)
 					continue;
 				lp += 6;
-			} else
-				/* replace device name */
-				if (strncmp(p, "$device", 7) == 0) {
-					sprintf(cp, "%s%d",
-					    sp->config->driver->kernel,
-					    sp->config->driver->unit);
-					while (*cp)
-						cp++;
-					lp += 7;
-				} else
-					/* Copy the `$' and rescan. */
-					*cp++ = *lp++;
+			} else if (strncmp(p, "$device", 7) == 0) {
+			/* replace device name */
+				sprintf(cp, "%s%d",
+				    sp->config->driver->kernel,
+				    sp->config->driver->unit);
+				while (*cp)
+					cp++;
+				lp += 7;
+			} else if (strncmp(p, "$ioaddr", 7) == 0) {
+			/* replace i/o address */
+				sprintf(cp, "0x%X", sp->io.addr);
+				while (*cp)
+					cp++;
+				lp += 7;
+			} else if (strncmp(p, "$iosize", 7) == 0) {
+			/* replace i/o window size */
+				sprintf(cp, "0x%X", sp->io.size);
+				while (*cp)
+					cp++;
+				lp += 7;
+			} else if (strncmp(p, "$irqnum", 7) == 0) {
+			/* replace irq number */
+				sprintf(cp, "%d", sp->irq);
+				while (*cp)
+					cp++;
+				lp += 7;
+			} else {
+			/* Copy the `$' and rescan. */
+				*cp++ = *lp++;
+			}
 		}
 		/* No more replacements. Copy rest of string. */
 		while ((*cp++ = *lp++) != 0)


$ grep -C 0x80010 /etc/pccard.conf
# D-Link DFE-650 Fast Ethernet Card
card "D-Link" "DFE-650"
        config  auto "ed" ? 0x80010
        insert  /usr/local/sbin/fa_select -b $ioaddr $device 3; /etc/pccard_ether $device start
        remove  /etc/pccard_ether $device stop


virtually yours   82D1 9B9C 01DC 4FB4 D7B4  61BE 3F49 4F77 72DE DA76
Gerhard Sittig   true | mail -s "get gpg key" Gerhard.Sittig@gmx.net
-- 
     If you don't understand or are scared by any of the above
             ask your parents or an adult to help you.

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010216194144.A20830>