Bug 25147

Summary: [PATCH] to make D-Link DFE-650 work with -STABLE
Product: Base System Reporter: Gerhard Sittig <Gerhard.Sittig>
Component: miscAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.2-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Gerhard Sittig 2001-02-16 19:00:01 UTC
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.

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! :>




$ 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.--IGXoRqjVgDZz4sGVs9xclZGTpD60qIwdi8hSMc9O497o3PPM
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

--- 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;
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).
Comment 1 iedowse freebsd_committer freebsd_triage 2001-07-28 21:25:17 UTC
State Changed
From-To: open->closed


The ed driver now has support for the miibus PHYs on these cards, 
so there should be no longer any need for the fa_select utility.