Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Jun 2000 12:47:54 -0700
From:      Paul Saab <paul@mu.org>
To:        Marc Fonvieille <fonvi@easynet.fr>
Cc:        freebsd-mobile@freebsd.org, phthin@club-internet.fr
Subject:   Re: 4.0-RELEASE, Netgear FA410TXC, device timeout [Long Solution]
Message-ID:  <20000620124753.A57147@elvis.mu.org>
In-Reply-To: <20000620140632.A10243@vobiscum.styx.org>; from fonvi@easynet.fr on Tue, Jun 20, 2000 at 02:06:32PM %2B0200
References:  <20000620140632.A10243@vobiscum.styx.org>

next in thread | previous in thread | raw e-mail | index | archive | help
There is a fix in -current and -stable now that fixes the detection
problem properly.

paul

Marc Fonvieille (fonvi@easynet.fr) wrote:
> Hello,
> 
> Now my Netgear FA410TXC runs fine!!!
> 
> Well, here's the solution:
> 
> 
> 1- Correct card detection:
> 	The card MAC address is written on the card (Node ID), mine is
> 	00 E0 98 7A F5 61. By default the ed driver doesn't detect the
> 	good type of card and so the correct MAC address.
> 
> 	To fix that we need to modify /usr/src/sys/dev/ed/if_ed.c
> 	at line 1016 (for 4.0R, 1011 for 4.0S) we've got this:
> 
>         if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
> 	/* could be either an NE1000 or a Linksys ethernet controller */
> 		linksys = ed_get_Linksys(sc);
> 
> 	replace with:
> 	
> 	/* if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {*/
> 	if (1) {
> 	/* could be either an NE1000 or a Linksys ethernet controller */
> 		linksys = ed_get_Linksys(sc);
> 
> 	Rebuild your kernel, now your card must be detect with correct
> 	address and type Linksys (16 bit)
> 
> 2- Force speed negociation
> 	The card seems unable to negociate link.
> 	I modified the fa_select.c used under linux to fix that pb.
> 	Here's the code for FreeBSD:
> 
> /* fa_select.c			*/
> /* modified for FreeBSD 4.x	*/
> /*				*/
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <sys/ioctl.h>
> #include <net/if.h>
> #include <stdio.h>
> #include <errno.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
> #include <machine/sysarch.h>
> 
> #define BASE_ADDR	0x240 /* replace with the card base address */
> 
> 
> inline unsigned char
> inb (unsigned short port)
> {
>     unsigned char _v;
>     
>     __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
>     return _v;
> }
> 
> inline void
> outb (unsigned char value, unsigned short port)
> {
>     __asm__ __volatile__ ("outb %b0,%w1"::"a" (value), "Nd" (port));
> }
> 
> static int sockets_open(void)
> {
>     int sock;
>     if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) != -1)
> 	return sock;
>     else if ((sock = socket(AF_IPX, SOCK_DGRAM, 0)) != -1)
> 	return sock;
>     else
> 	return socket(AF_APPLETALK, SOCK_DGRAM, 0);
> }
> void write_bit(int port, int bit)
> {
>     outb((bit << 6) + 0x20, port);
>     usleep(1);
>     outb((bit << 6) + 0xa0, port);
>     usleep(1);
>     outb((bit << 6) + 0x20, port);
> }
> int read_bit(int port)
> {
>     int i;
>     outb(0,    port);
>     usleep(1);
>     outb(0x80, port);
>     usleep(1);
>     i = inb(port);
>     outb(0,    port);
>     return (i & 0x10) >> 4;
> }
> void reset(int port)
> {
>     outb(0x08, port);
>     usleep(1);
>     outb(0x0C, port);
>     usleep(1);
>     outb(0x08, port);
>     usleep(1);
>     outb(0x0C, port);
>     outb(0x00, port);
> }
> int reada(int port, int adr)
> {
>     int i,j;
>     
>     for (i=0; i<0x20; i++)
> 	write_bit(port, 1);
>     
>     write_bit(port, 0);
>     write_bit(port, 1);
>     write_bit(port, 1);
>     write_bit(port, 0);
>     
>     write_bit(port, 0);
>     write_bit(port, 0);
>     write_bit(port, 0);
>     write_bit(port, 0);
>     write_bit(port, 0);
>     
>     write_bit(port, (adr & 0x10) >> 4);
>     write_bit(port, (adr & 0x08) >> 3);
>     write_bit(port, (adr & 0x04) >> 2);
>     write_bit(port, (adr & 0x02) >> 1);
>     write_bit(port, (adr & 0x01) >> 0);
>     
>     j = read_bit(port);
>     if (j == 1)
> 	j = read_bit(port);
>     for (i=0; i<16; i++) {
> 	j = (j << 1) + read_bit(port);
>     }
>     write_bit(port, 1);
>     return j;
> }
> int writea(int port, int adr, int val)
> {
>     int i;
>     
>     outb(0x08, port);
>     usleep(1);
>     outb(0x0C, port);
>     usleep(1);
>     outb(0x08, port);
>     usleep(1);
>     outb(0x0C, port);
>     outb(0x00, port);
>     
>     for (i=0; i<0x20; i++)
> 	write_bit(port, 1);
>     
>     write_bit(port, 0);
>     write_bit(port, 1);
>     write_bit(port, 0);
>     write_bit(port, 1);
>     
>     write_bit(port, 0);
>     write_bit(port, 0);
>     write_bit(port, 0);
>     write_bit(port, 0);
>     write_bit(port, 0);
>     
>     write_bit(port, (adr & 0x10) >> 4);
>     write_bit(port, (adr & 0x08) >> 3);
>     write_bit(port, (adr & 0x04) >> 2);
>     write_bit(port, (adr & 0x02) >> 1);
>     write_bit(port, (adr & 0x01) >> 0);
>     
>     write_bit(port, 1);
>     write_bit(port, 0);
>     
>     write_bit(port, (val & 0x8000) >> 15);
>     write_bit(port, (val & 0x4000) >> 14);
>     write_bit(port, (val & 0x2000) >> 13);
>     write_bit(port, (val & 0x1000) >> 12);
>     write_bit(port, (val & 0x0800) >> 11);
>     write_bit(port, (val & 0x0400) >> 10);
>     write_bit(port, (val & 0x0200) >> 9);
>     write_bit(port, (val & 0x0100) >> 8);
>     write_bit(port, (val & 0x0080) >> 7);
>     write_bit(port, (val & 0x0040) >> 6);
>     write_bit(port, (val & 0x0020) >> 5);
>     write_bit(port, (val & 0x0010) >> 4);
>     write_bit(port, (val & 0x0008) >> 3);
>     write_bit(port, (val & 0x0004) >> 2);
>     write_bit(port, (val & 0x0002) >> 1);
>     write_bit(port, (val & 0x0001) >> 0);
>     
>     write_bit(port, 1);
>     return 0;
> }
> int 
> main(int argc, char **argv)
> {
>     int skfd, i, sub;
>     struct ifreq ifr;
>     
> /*    base_addr = atoi(argv[3]);*/
> /*    printf ("%i",base_addr);*/
>     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) {
>     case 0:
> 	sub = 0x0000;
> 	break;
>     case 1:
> 	sub = 0x0100;
> 	break;
>     case 2:
> 	sub = 0x2000;
> 	break;
>     default:
> 	sub = 0x2100;
> 	break;
>     }
>     i386_set_ioperm(BASE_ADDR+0x1c, 1, 1);
>     reset(BASE_ADDR+0x1c);
>     writea(BASE_ADDR+0x1c, 0, 0x8000);
>     writea(BASE_ADDR+0x1c, 0, sub);
>     close(skfd);
>     exit(0);
>     return 0;
> }
> 
> Don't forget to change #define BASE_ADDR 0x240 with the card address.
> 
> 	To compile it: gcc -Wall fa_select.c -o fa_select
> 
> 	To use it:
> 
> 		fa_select device rate
> 
> 	where device is: ed0, ed1...
> 	      rate is:  0	for 10BaseT
> 	      		1	for 10Base2 (full duplex)
> 			2	for 100BaseT
> 			3	for 100Mbit  (full duplex)
> 
> I tried this with my adsl modem (Alcatel 1000 Adsl) with 'fa_select ed1 0'
> and it runs fine without timeout.
> 
> Ok, that's all.
> 
> Great thanks for the help to all persons from the mailing list.
> 
> Marc
> 
> 
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-mobile" in the body of the message

-- 
Paul Saab
Technical Yahoo
paul@mu.org - ps@yahoo-inc.com - ps@freebsd.org
Do You .. uhh .. Yahoo!?


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




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