From owner-freebsd-bugs Tue Jun 8 14:30: 9 1999 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 1955215580 for ; Tue, 8 Jun 1999 14:30:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id OAA54797; Tue, 8 Jun 1999 14:30:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from portable.altadena.net (dhcp121.conference.usenix.org [209.179.127.121]) by hub.freebsd.org (Postfix) with ESMTP id 0F4DF14D26 for ; Tue, 8 Jun 1999 14:22:11 -0700 (PDT) (envelope-from pete@portable.altadena.net) Received: (from pete@localhost) by portable.altadena.net (8.9.3/8.8.8) id OAA00592; Tue, 8 Jun 1999 14:22:11 -0700 (PDT) (envelope-from pete) Message-Id: <199906082122.OAA00592@portable.altadena.net> Date: Tue, 8 Jun 1999 14:22:11 -0700 (PDT) From: pete@altadena.net Reply-To: pete@altadena.net To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: i386/12088: i386 Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >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