From owner-freebsd-mobile Mon Jun 26 21:50:51 2000 Delivered-To: freebsd-mobile@freebsd.org Received: from dynas.se (c220966-a.smateo1.sfba.home.com [24.19.156.4]) by hub.freebsd.org (Postfix) with ESMTP id 4B0F137B6DF for ; Mon, 26 Jun 2000 21:50:46 -0700 (PDT) (envelope-from mikko@dynas.se) Received: (from mikko@localhost) by shiba.smateo1.sfba.home.com (8.9.3/8.9.3) id GAA00318; Tue, 27 Jun 2000 06:48:29 +0200 (CEST) (envelope-from mikko) Date: Tue, 27 Jun 2000 06:48:29 +0200 (CEST) From: =?ISO-8859-1?Q?Mikko_Ty=F6l=E4j=E4rvi?= X-Sender: mikko@dynas.se To: freebsd-mobile@freebsd.org Subject: Netgear FA410TX - Some progress (Patch included) Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Reply-To: mikko@dynas.se X-MIME-Autoconverted: to 8bit by snemail 0.35 Sender: owner-freebsd-mobile@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Hi, Having seen this card mentioned in pccard.conf, I bought one. As other already have discovered, it didn't work. Probes, attaches, but no data. As someone on this list mentioned that Linux already has support for this chip, I grabbed the Linux source (beware the GPL!), extracted what seemed to be somewhat relevant parts, and squeezed into "if_ed.c," with little or no clue as to what I was doing. It worked. It looks like newer versions of this card use an updated ethernet controller (DL10022 instead of DL10019), and that the lack of the correct incantations is why initializatio fails. Now, I'd be most grateful if someone more knowledgeable would have a look at this, and perhaps get hold of specs from wherever the specs on the old chip (DL10019) came from, and maybe update if_ed.c in a controlled fashion, to support these new cards. I haven't tested the hack with any other cards, or in any other setup than the one on my desk right now, so it may in fact not work for anyone else, or anywhere else :) The Linux driver (pcnet_cs) also contains code to disable collision detection on full duplex duplex links, but it was not obvious where to put it, so it is not included. /Mikko (Most of this code has been blatantly copied from the Linux driver) ----8<--------------------------------------------------------------- --- if_ed.c.org Tue Jun 27 05:18:58 2000 +++ if_ed.c Tue Jun 27 06:35:48 2000 @@ -71,6 +71,13 @@ #include #include +#define LINKSYS_HACK +#ifdef LINKSYS_HACK +# define DL10019 19 +# define DL10022 22 +# define dl_type hpp_options /* XXX Q&D overloading... */ +#endif + static void ed_init __P((void *)); static int ed_ioctl __P((struct ifnet *, u_long, caddr_t)); static void ed_start __P((struct ifnet *)); @@ -902,6 +909,8 @@ u_char sum; int i; + sc->dl_type = 0; + /* * Linksys registers(offset from ASIC base) * @@ -916,6 +925,10 @@ for (i = 0; i < ETHER_ADDR_LEN; i++) { sc->arpcom.ac_enaddr[i] = inb(sc->asic_addr + 0x04 + i); } +#ifdef LINKSYS_HACK + i = inb(sc->asic_addr + 0x0f); + sc->dl_type = (i == 0x91 || i == 0x99) ? DL10022 : DL10019; +#endif return (1); } @@ -1674,6 +1687,11 @@ else printf("%s ", sc->isa16bit ? "(16 bit)" : "(8 bit)"); +#ifdef LINKSYS_HACK + if (sc->type == ED_TYPE_NE2000 && sc->dl_type) + printf("DL100%d\n", sc->dl_type); +#endif + printf("%s\n", (((sc->vendor == ED_VENDOR_3COM) || (sc->vendor == ED_VENDOR_HP)) && (ifp->if_flags & IFF_ALTPHYS)) ? " tranceiver disabled" : ""); @@ -1750,6 +1768,87 @@ ed_reset(ifp); } + +#ifdef LINKSYS_HACK + +/*====================================================================== + + MII interface support for DL10019 and DL10022 based cards + + On the DL10019, the MII IO direction bit is 0x10; on the DL10022 + it is 0x20. Setting both bits seems to work on both card types. + +======================================================================*/ + +#define DLINK_GPIO 0x1c +#define DLINK_DIAG 0x1d +#define MDIO_SHIFT_CLK 0x80 +#define MDIO_DATA_OUT 0x40 +#define MDIO_DIR_WRITE 0x30 +#define MDIO_DATA_WRITE0 (MDIO_DIR_WRITE) +#define MDIO_DATA_WRITE1 (MDIO_DIR_WRITE | MDIO_DATA_OUT) +#define MDIO_DATA_READ 0x10 +#define MDIO_MASK 0x0f + +typedef ushort ioaddr_t; + +static void mdio_sync(ioaddr_t addr) +{ + int bits, mask = inb(addr) & MDIO_MASK; + for (bits = 0; bits < 32; bits++) { + outb(addr, mask | MDIO_DATA_WRITE1); + outb(addr, mask | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK); + } +} + +static int mdio_read(ioaddr_t addr, int phy_id, int loc) +{ + u_int cmd = (0x06<<10)|(phy_id<<5)|loc; + int i, retval = 0, mask = inb(addr) & MDIO_MASK; + + mdio_sync(addr); + for (i = 13; i >= 0; i--) { + int dat = (cmd&(1< 0; i--) { + outb(addr, mask); + retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0); + outb(addr, mask | MDIO_SHIFT_CLK); + } + return (retval>>1) & 0xffff; +} + +static void mdio_write(ioaddr_t addr, int phy_id, int loc, int value) +{ + u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value; + int i, mask = inb(addr) & MDIO_MASK; + + mdio_sync(addr); + for (i = 31; i >= 0; i--) { + int dat = (cmd&(1<= 0; i--) { + outb(addr, mask); + outb(addr, mask | MDIO_SHIFT_CLK); + } +} + +static void mdio_reset(ioaddr_t addr, int phy_id) +{ + outb(addr, 0x08); + outb(addr, 0x0c); + outb(addr, 0x08); + outb(addr, 0x0c); + outb(addr, 0x00); +} + +#endif + + /* * Initialize device. */ @@ -1891,6 +1990,15 @@ } } +#ifdef LINKSYS_HACK + if (sc->type == ED_TYPE_NE2000 && sc->dl_type == DL10022) { + mdio_reset(sc->nic_addr + DLINK_GPIO, 0); + /* Restart MII autonegotiation */ + mdio_write(sc->nic_addr + DLINK_GPIO, 0, 0, 0x0000); + mdio_write(sc->nic_addr + DLINK_GPIO, 0, 0, 0x1200); + } +#endif + /* * Set 'running' flag, and clear output active flag. */ @@ -3302,3 +3410,4 @@ af[index >> 3] |= 1 << (index & 7); } } + Mikko Työläjärvi_______________________________________mikko@rsasecurity.com RSA Security To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-mobile" in the body of the message