Skip site navigation (1)Skip section navigation (2)
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>