Date: Tue, 20 Jun 2000 14:06:32 +0200 From: Marc Fonvieille <fonvi@easynet.fr> To: freebsd-mobile@freebsd.org Cc: phthin@club-internet.fr Subject: 4.0-RELEASE, Netgear FA410TXC, device timeout [Long Solution] Message-ID: <20000620140632.A10243@vobiscum.styx.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000620140632.A10243>