static int ed_pccard_rom_mac(device_t dev, uint8_t *enaddr) { struct ed_softc *sc = device_get_softc(dev); uint8_t romdata[32], sum; int i; /* * Read in the rom data at location 0. Since there are no * NE-1000 based PC Card devices, we'll assume we're 16-bit. * * In researching what format this takes, I've found that the * following appears to be true for multiple cards based on * observation as well as datasheet digging. * * Data is stored in some ROM and is copied out 8 bits at a time * into 16-bit wide locations. This means that the odd locations * of the ROM are not used (and can be either 0 or ff). * * The contents appears to be as follows: * PROM RAM * Offset Offset What * 0 0 ENETADDR 0 * 1 2 ENETADDR 1 * 2 4 ENETADDR 2 * 3 6 ENETADDR 3 * 4 8 ENETADDR 4 * 5 10 ENETADDR 5 * 6-13 12-26 Reserved (varies by manufacturer) * 14 28 0x57 * 15 30 0x57 * * Some manufacturers have another image of enetaddr from * PROM offset 0x10 to 0x15 with 0x42 in 0x1e and 0x1f, but * this doesn't appear to be universally documented in the * datasheets. Some manufactuers have a card type, card config * checksums, etc encoded into PROM offset 6-13, but deciphering it * requires more knowledge about the exact underlying chipset than * we possess (and maybe can possess). */ ed_pio_readmem(sc, 0, romdata, 32); if (bootverbose) device_printf(dev, "ROM DATA: %32D\n", romdata, " "); if (romdata[28] != 0x57 || romdata[30] != 0x57) return (0); for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) sum |= romdata[i * 2]; if (sum == 0) return (0); for (i = 0; i < ETHER_ADDR_LEN; i++) enaddr[i] = romdata[i * 2]; return (1); }
void ed_Novell_read_mac(struct ed_softc *sc) { int n; uint8_t romdata[16]; /* * Most ne1000/ne2000 compatible cards have their MAC address * located in the first few words of the address space. This seems * universally true for ISA and PCI implementations, but PC Card * devices seem to have more variance. */ ed_pio_readmem(sc, 0, romdata, 16); for (n = 0; n < ETHER_ADDR_LEN; n++) sc->enaddr[n] = romdata[n * (sc->isa16bit + 1)]; }
/* * Probe and vendor-specific initialization routine for ax88x90 boards */ static int ed_probe_ax88x90_generic(device_t dev, int flags) { struct ed_softc *sc = device_get_softc(dev); u_int memsize; static char test_pattern[32] = "THIS is A memory TEST pattern"; char test_buffer[32]; ed_pccard_ax88x90_reset(sc); DELAY(10*1000); /* Make sure that we really have an 8390 based board */ if (!ed_probe_generic8390(sc)) return (ENXIO); sc->vendor = ED_VENDOR_NOVELL; sc->mem_shared = 0; sc->cr_proto = ED_CR_RD2; /* * This prevents packets from being stored in the NIC memory when the * readmem routine turns on the start bit in the CR. We write some * bytes in word mode and verify we can read them back. If we can't * then we don't have an AX88x90 chip here. */ sc->isa16bit = 1; ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON); ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern)); ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern)); if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) != 0) return (ENXIO); /* * Hard code values based on the datasheet. We're NE-2000 compatible * NIC with 16kb of packet memory starting at 16k offset. */ sc->type = ED_TYPE_NE2000; memsize = sc->mem_size = 16*1024; sc->mem_start = 16 * 1024; if (ed_asic_inb(sc, ED_AX88X90_TEST) != 0) sc->chip_type = ED_CHIP_TYPE_AX88790; else { sc->chip_type = ED_CHIP_TYPE_AX88190; /* * The AX88190 (not A) has external 64k SRAM. Probe for this * here. Most of the cards I have either use the AX88190A * part, or have only 32k SRAM for some reason, so I don't * know if this works or not. */ ed_pio_writemem(sc, test_pattern, 32768, sizeof(test_pattern)); ed_pio_readmem(sc, 32768, test_buffer, sizeof(test_pattern)); if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) { sc->mem_start = 2*1024; memsize = sc->mem_size = 62 * 1024; } } sc->mem_end = sc->mem_start + memsize; sc->tx_page_start = memsize / ED_PAGE_SIZE; if (sc->mem_size > 16 * 1024) sc->txb_cnt = 3; else 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; ed_nic_outb(sc, ED_P0_PSTART, sc->mem_start / ED_PAGE_SIZE); ed_nic_outb(sc, ED_P0_PSTOP, sc->mem_end / ED_PAGE_SIZE); /* Get the mac before we go -- It's just at 0x400 in "SRAM" */ ed_pio_readmem(sc, 0x400, sc->enaddr, ETHER_ADDR_LEN); /* clear any pending interrupts that might have occurred above */ ed_nic_outb(sc, ED_P0_ISR, 0xff); sc->sc_write_mbufs = ed_pio_write_mbufs; return (0); }
/* * Probe and vendor-specific initialization routine for NE1000/2000 boards */ int ed_probe_Novell_generic(device_t dev, int flags) { struct ed_softc *sc = device_get_softc(dev); u_int memsize; int error; u_char tmp; static char test_pattern[32] = "THIS is A memory TEST pattern"; char test_buffer[32]; /* Reset the board */ if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) { ed_asic_outb(sc, ED_NOVELL_RESET, 0); DELAY(200); } tmp = ed_asic_inb(sc, 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 */ ed_asic_outb(sc, 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 */ ed_nic_outb(sc, 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 (ENXIO); sc->vendor = ED_VENDOR_NOVELL; 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. */ /* * This prevents packets from being stored in the NIC memory when the * readmem routine turns on the start bit in the CR. */ ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON); /* Temporarily initialize DCR for byte operations */ ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); ed_nic_outb(sc, ED_P0_PSTART, 8192 / ED_PAGE_SIZE); ed_nic_outb(sc, ED_P0_PSTOP, 16384 / ED_PAGE_SIZE); /* * Some devices identify themselves. Some of those devices * can't handle being probed, so we allow forcing a mode. If * these flags are set, force it, otherwise probe. */ if (flags & ED_FLAGS_FORCE_8BIT_MODE) { sc->isa16bit = 0; sc->type = ED_TYPE_NE1000; sc->type_str = "NE1000"; } else if (flags & ED_FLAGS_FORCE_16BIT_MODE) { sc->isa16bit = 1; sc->type = ED_TYPE_NE2000; sc->type_str = "NE2000"; ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE); ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE); } else { /* * Write a test pattern in byte mode. If this fails, then there * probably isn't any memory at 8k - which likely means that the board * is an NE2000. */ ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern)); ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern)); if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) { sc->type = ED_TYPE_NE1000; sc->type_str = "NE1000"; sc->isa16bit = 0; } else { /* Not an NE1000 - try NE2000 */ sc->isa16bit = 1; ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE); ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE); /* * Write a test pattern in word mode. If this also fails, then * we don't know what this board is. */ ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern)); ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern)); if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) { sc->type = ED_TYPE_NE2000; sc->type_str = "NE2000"; } else { return (ENXIO); } } } sc->chip_type = ED_CHIP_TYPE_DP8390; /* 8k of memory plus an additional 8k if 16bit */ memsize = 8192 + sc->isa16bit * 8192; 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 = 8192 + sc->isa16bit * 8192; sc->mem_end = sc->mem_start + memsize; sc->tx_page_start = memsize / ED_PAGE_SIZE; if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) { error = ed_probe_gwether(dev); if (error) return (error); } /* * Use one xmit buffer if < 16k, two buffers otherwise (if not told * otherwise). */ if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) sc->txb_cnt = 1; else 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 */ ed_nic_outb(sc, ED_P0_ISR, 0xff); sc->sc_write_mbufs = ed_pio_write_mbufs; return (0); }
static int ed_probe_gwether(device_t dev) { int x, i, msize = 0; bus_size_t mstart = 0; char pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE]; struct ed_softc *sc = device_get_softc(dev); for (i = 0; i < ED_PAGE_SIZE; i++) pbuf0[i] = 0; /* Clear all the memory. */ for (x = 1; x < 256; x++) ed_pio_writemem(sc, pbuf0, x * 256, ED_PAGE_SIZE); /* Search for the start of RAM. */ for (x = 1; x < 256; x++) { ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) { for (i = 0; i < ED_PAGE_SIZE; i++) pbuf[i] = 255 - x; ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE); ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) { mstart = x * ED_PAGE_SIZE; msize = ED_PAGE_SIZE; break; } } } if (mstart == 0) { device_printf(dev, "Cannot find start of RAM.\n"); return (ENXIO); } /* Probe the size of RAM. */ for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) { ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) { for (i = 0; i < ED_PAGE_SIZE; i++) pbuf[i] = 255 - x; ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE); ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) msize += ED_PAGE_SIZE; else { break; } } else { break; } } if (msize == 0) { device_printf(dev, "Cannot find any RAM, start : %d, x = %d.\n", (int)mstart, x); return (ENXIO); } if (bootverbose) device_printf(dev, "RAM start at %d, size : %d.\n", (int)mstart, msize); sc->mem_size = msize; sc->mem_start = mstart; sc->mem_end = msize + mstart; sc->tx_page_start = mstart / ED_PAGE_SIZE; return 0; }