Date: Tue, 8 Jun 1999 14:22:11 -0700 (PDT) From: pete@altadena.net To: FreeBSD-gnats-submit@freebsd.org Subject: i386/12088: i386 Message-ID: <199906082122.OAA00592@portable.altadena.net>
index | next in thread | raw e-mail
>Number: 12088
>Category: i386
>Synopsis: Enhancement to ed driver for Linksys 10/100 or DLink DFE650
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Tue Jun 8 14:30:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator: Pete Carah
>Release: FreeBSD 3.2-STABLE i386
>Organization:
Altadena Internet
>Environment:
3.x (the if_ed driver appears to not have changed since 3.0-stable.)
PCMCIA 10/100 ethernet.
>Description:
Add full functionality for Linksys 10/100 or DLink DFE650
>How-To-Repeat:
Use either of these cards in a laptop
>Fix:
This was made up by fitting data from the linux driver into
the existing if_ed.c framework.
Apply diff: (debug stuff isn't really needed :-)
*** if_ed.c Thu Mar 18 10:47:27 1999
--- if_ed.c.new Thu Apr 29 10:16:46 1999
***************
*** 157,162 ****
--- 157,165 ----
static int ed_probe_Novell_generic __P((struct ed_softc *, int, int, int));
static int ed_probe_HP_pclanp __P((struct isa_device *));
+ static int ed_probe_DL10019A __P((struct isa_device *));
+ static int ed_probe_DL10019A_generic __P((struct ed_softc *, int, int, int));
+
#include "pci.h"
#if NPCI > 0
void *ed_attach_NE2000_pci __P((int, int));
***************
*** 221,229 ****
--- 224,240 ----
u_char e;
struct ed_softc *sc = &ed_softc[devi->isahd.id_unit];
+ #if ED_DEBUG
+ printf("EDINIT called %d\n", devi->isahd.id_unit);
+ #endif
+
/* validate unit number. */
if (devi->isahd.id_unit >= NEDTOT)
return(ENODEV);
+
+ #if ED_DEBUG
+ printf("Unit valid, probing\n");
+ #endif
/*
* Probe the device. If a value is returned, the
* device was found at the location.
***************
*** 231,242 ****
--- 242,257 ----
sc->gone = 0;
if (ed_probe_pccard(&devi->isahd, devi->misc) == 0)
return(ENXIO);
+ #if ED_DEBUG
+ printf("Probed OK\n");
+ #endif
e = 0;
for (i = 0; i < ETHER_ADDR_LEN; ++i)
e |= devi->misc[i];
if (e)
for (i = 0; i < ETHER_ADDR_LEN; ++i)
sc->arpcom.ac_enaddr[i] = devi->misc[i];
+
if (ed_attach_isa(&devi->isahd) == 0)
return(ENXIO);
***************
*** 742,748 ****
sc->cr_proto = 0;
}
! #if 0
printf("starting memory performance test at 0x%x, size %d...\n",
sc->mem_start, memsize*16384);
for (i = 0; i < 16384; i++)
--- 757,763 ----
sc->cr_proto = 0;
}
! #if ED_DEBUG
printf("starting memory performance test at 0x%x, size %d...\n",
sc->mem_start, memsize*16384);
for (i = 0; i < 16384; i++)
***************
*** 1158,1164 ****
--- 1173,1181 ----
ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern));
if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)))
+ {
return (0); /* not an NE2000 either */
+ }
sc->type = ED_TYPE_NE2000;
sc->type_str = "NE2000";
***************
*** 1288,1293 ****
--- 1305,1500 ----
isa_dev->id_unit, isa_dev->id_flags);
}
+ static int
+ ed_probe_DL10019A_generic(sc, port, unit, flags)
+ struct ed_softc *sc;
+ int port;
+ int unit;
+ int flags;
+ {
+ u_int memsize, n;
+ u_char romdata[16], tmp;
+ static char test_pattern[32] = "THIS is A memory TEST pattern";
+ char test_buffer[32];
+ u_int i, sum, c;
+
+ sc->asic_addr = port + 0x10;
+ sc->nic_addr = port + 0x00;
+
+ /* XXX - do Novell-specific probe here */
+
+ /* Reset the board */
+ tmp = inb(sc->asic_addr + ED_NOVELL_RESET);
+
+ /*
+ * I don't know if this is necessary; probably cruft leftover from
+ * Clarkson packet driver code. Doesn't do a thing on the boards I've
+ * tested. -DG [note that a outb(0x84, 0) seems to work here, and is
+ * non-invasive...but some boards don't seem to reset and I don't have
+ * complete documentation on what the 'right' thing to do is...so we
+ * do the invasive thing for now. Yuck.]
+ */
+ outb(sc->asic_addr + ED_NOVELL_RESET, tmp);
+ DELAY(5000);
+
+ /*
+ * This is needed because some NE clones apparently don't reset the
+ * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
+ * - this makes the probe invasive! ...Done against my better
+ * judgement. -DLG
+ */
+ outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
+
+ DELAY(5000);
+
+ /* Make sure that we really have an 8390 based board */
+ if (!ed_probe_generic8390(sc))
+ return (0);
+
+ sc->vendor = ED_VENDOR_DL10019A;
+ sc->mem_shared = 0;
+ sc->cr_proto = ED_CR_RD2;
+
+ /*
+ * Test the ability to read and write to the NIC memory. This has the
+ * side affect of determining if this is an NE1000 or an NE2000.
+ */
+
+ #if ED_DEBUG
+ printf("Checking address - ");
+ #endif
+ for(sum = 0,i = 0x14; i < 0x1c; ++i)
+ {
+ sum += (c = inb(sc->nic_addr + i));
+ #if ED_DEBUG
+ printf("%02x:", c);
+ #endif
+ }
+ #if ED_DEBUG
+ printf(" - sum=%02x\n", sum);
+ #endif
+
+ if ((sum & 0xff) != 0xff)
+ return 0;
+
+ #if ED_DEBUG
+ printf("Getting address\n");
+ #endif
+
+ for (n = 0; n < ETHER_ADDR_LEN; n++)
+ sc->arpcom.ac_enaddr[n] = inb(sc->nic_addr + 0x14 + n);
+
+ #if ED_DEBUG
+ printf("Structure address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
+ sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
+ sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5]);
+ #endif
+ /*
+ * This prevents packets from being stored in the NIC memory when the
+ * readmem routine turns on the start bit in the CR.
+ */
+
+ outb(sc->nic_addr + ED_P0_RCR, ED_RCR_MON);
+
+ outb(sc->nic_addr + ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
+ outb(sc->nic_addr + ED_P0_PSTART, 0 / ED_PAGE_SIZE);
+ outb(sc->nic_addr + ED_P0_PSTOP, 32768 / ED_PAGE_SIZE);
+
+ sc->isa16bit = 1;
+
+ ed_pio_writemem(sc, test_pattern, 1024, sizeof(test_pattern));
+ ed_pio_readmem(sc, 1024, test_buffer, sizeof(test_pattern));
+
+ #if ED_DEBUG
+ printf("Test Pattern %-30.30s\n", test_pattern);
+ printf("Test as seen %-30.30s\n", test_buffer);
+ #endif
+
+ if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)))
+ {
+ return (0); /* not an NE2000 either */
+ }
+
+ /* try top of memory - Linksys is 32k and D-Link is 64k */
+ ed_pio_writemem(sc, test_pattern, 32000, sizeof(test_pattern));
+ ed_pio_readmem(sc, 32000, test_buffer, sizeof(test_pattern));
+
+ #if ED_DEBUG
+ printf("Test Pattern %-30.30s\n", test_pattern);
+ printf("Test as seen %-30.30s\n", test_buffer);
+ #endif
+
+ if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)))
+ {
+ return (0); /* not an NE2000 either */
+ }
+
+ /* try D-Link with 64k buffer */
+ outb(sc->nic_addr + ED_P0_PSTOP, 65280 / ED_PAGE_SIZE);
+
+ ed_pio_writemem(sc, test_pattern, 65200, sizeof(test_pattern));
+ ed_pio_readmem(sc, 65200, test_buffer, sizeof(test_pattern));
+
+ #if ED_DEBUG
+ printf("Test Pattern %-30.30s\n", test_pattern);
+ printf("Test as seen %-30.30s\n", test_buffer);
+ #endif
+
+ if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)))
+ {
+ sc->type_str = "LinkSys";
+
+ /* 8k of memory plus an additional 8k if 16bit */
+ memsize = 32768;
+ outb(sc->nic_addr + ED_P0_PSTOP, 32768 / ED_PAGE_SIZE);
+
+ }
+ else
+ {
+ sc->type_str = "D-Link";
+ /* More memory */
+ memsize = 65280;
+ }
+
+
+ sc->mem_size = memsize;
+
+ /* NIC memory doesn't start at zero on an NE board */
+ /* The start address is tied to the bus width */
+ sc->mem_start = 0;
+ sc->mem_end = sc->mem_start + memsize;
+ sc->tx_page_start = 0 / ED_PAGE_SIZE;
+
+
+ /*
+ * Use one xmit buffer if < 16k, two buffers otherwise (if not told
+ * otherwise).
+ */
+ sc->txb_cnt = 2;
+
+ sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
+ sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
+
+ sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
+
+ /* clear any pending interrupts that might have occurred above */
+ outb(sc->nic_addr + ED_P0_ISR, 0xff);
+
+ return (32);
+ }
+
+ static int
+ ed_probe_DL10019A(isa_dev)
+ struct isa_device *isa_dev;
+ {
+ struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
+
+ isa_dev->id_maddr = 0;
+ return ed_probe_DL10019A_generic(sc, isa_dev->id_iobase,
+ isa_dev->id_unit, isa_dev->id_flags);
+ }
+
#if NCARD > 0
/*
* Probe framework for pccards. Replicates the standard framework,
***************
*** 1301,1306 ****
--- 1508,1517 ----
{
int nports;
+ nports = ed_probe_DL10019A(isa_dev);
+ if (nports)
+ return(nports);
+
nports = ed_probe_WD80x3(isa_dev);
if (nports)
return (nports);
***************
*** 2877,2883 ****
{
int maxwait = 200; /* about 240us */
! if (sc->vendor == ED_VENDOR_NOVELL) {
/* select page 0 registers */
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA);
--- 3088,3095 ----
{
int maxwait = 200; /* about 240us */
! if (sc->vendor == ED_VENDOR_NOVELL ||
! sc->vendor == ED_VENDOR_DL10019A) {
/* select page 0 registers */
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA);
*** if_edreg.h Thu Oct 8 10:20:58 1998
--- if_edreg.h.new Thu Apr 29 10:16:59 1999
***************
*** 571,576 ****
--- 571,578 ----
#define ED_VENDOR_PCCARD 0x03 /* PCMCIA/PCCARD */
#define ED_VENDOR_HP 0x04 /* Hewlett Packard */
+ #define ED_VENDOR_DL10019A 0x05 /* LinkSys, maybe DLINK */
+
/*
* Compile-time config flags
*/
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199906082122.OAA00592>
