📄 ns8390.c
字号:
nic->node_addr[i] = inb(i+eth_asic_base+WD_LAR); } printf("\n%s base %#hx", brd->name, eth_asic_base); if (eth_flags & FLAG_790) {#ifdef WD_790_PIO printf(", PIO mode, addr %!\n", nic->node_addr); eth_bmem = 0; eth_flags |= FLAG_PIO; /* force PIO mode */ outb(0, eth_asic_base+WD_MSR);#else printf(", memory %#x, addr %!\n", eth_bmem, nic->node_addr); outb(WD_MSR_MENB, eth_asic_base+WD_MSR); outb((inb(eth_asic_base+0x04) | 0x80), eth_asic_base+0x04); outb(((unsigned)(eth_bmem >> 13) & 0x0F) | ((unsigned)(eth_bmem >> 11) & 0x40) | (inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B); outb((inb(eth_asic_base+0x04) & ~0x80), eth_asic_base+0x04);#endif } else { printf(", memory %#x, addr %!\n", eth_bmem, nic->node_addr); outb(((unsigned)(eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR); } if (eth_flags & FLAG_16BIT) { if (eth_flags & FLAG_790) { eth_laar = inb(eth_asic_base + WD_LAAR); outb(WD_LAAR_M16EN, eth_asic_base + WD_LAAR); } else { outb((eth_laar = WD_LAAR_L16EN | 1), eth_asic_base + WD_LAAR);/* The previous line used to be WD_LAAR_M16EN | WD_LAAR_L16EN | 1)); jluke@deakin.edu.au reported that removing WD_LAAR_M16EN made it work for WD8013s. This seems to work for my 8013 boards. I don't know what is really happening. I wish I had data sheets or more time to decode the Linux driver. - Ken*/ } inb(0x84); }}#endif#ifdef INCLUDE_3C503#ifdef T503_AUI nic->flags = 1; /* aui */#else nic->flags = 0; /* no aui */#endif /****************************************************************** Search for 3Com 3c503 if no WD/SMC cards ******************************************************************/ if (eth_vendor == VENDOR_NONE) { int idx; int iobase_reg, membase_reg; static unsigned short base[] = { 0x300, 0x310, 0x330, 0x350, 0x250, 0x280, 0x2A0, 0x2E0, 0 }; /* Loop through possible addresses checking each one */ for (idx = 0; (eth_nic_base = base[idx]) != 0; ++idx) { eth_asic_base = eth_nic_base + _3COM_ASIC_OFFSET;/* * Note that we use the same settings for both 8 and 16 bit cards: * both have an 8K bank of memory at page 1 while only the 16 bit * cards have a bank at page 0. */ eth_memsize = MEM_16384; eth_tx_start = 32; eth_rx_start = 32 + D8390_TXBUF_SIZE; /* Check our base address. iobase and membase should */ /* both have a maximum of 1 bit set or be 0. */ iobase_reg = inb(eth_asic_base + _3COM_BCFR); membase_reg = inb(eth_asic_base + _3COM_PCFR); if ((iobase_reg & (iobase_reg - 1)) || (membase_reg & (membase_reg - 1))) continue; /* nope */ /* Now get the shared memory address */ eth_flags = 0; switch (membase_reg) { case _3COM_PCFR_DC000: eth_bmem = 0xdc000; break; case _3COM_PCFR_D8000: eth_bmem = 0xd8000; break; case _3COM_PCFR_CC000: eth_bmem = 0xcc000; break; case _3COM_PCFR_C8000: eth_bmem = 0xc8000; break; case _3COM_PCFR_PIO: eth_flags |= FLAG_PIO; eth_bmem = 0; break; default: continue; /* nope */ } break; } if (base[idx] == 0) /* not found */ return (0);#ifndef T503_SHMEM eth_flags |= FLAG_PIO; /* force PIO mode */ eth_bmem = 0;#endif eth_vendor = VENDOR_3COM; /* Need this to make ns8390_poll() happy. */ eth_rmem = eth_bmem - 0x2000; /* Reset NIC and ASIC */ outb(_3COM_CR_RST | _3COM_CR_XSEL, eth_asic_base + _3COM_CR ); outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR ); /* Get our ethernet address */ outb(_3COM_CR_EALO | _3COM_CR_XSEL, eth_asic_base + _3COM_CR); printf("\n3Com 3c503 base %#hx, ", eth_nic_base); if (eth_flags & FLAG_PIO) printf("PIO mode"); else printf("memory %#x", eth_bmem); for (i=0; i<ETH_ALEN; i++) { nic->node_addr[i] = inb(eth_nic_base+i); } printf(", %s, addr %!\n", nic->flags ? "AUI" : "internal xcvr", nic->node_addr); outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR); /* * Initialize GA configuration register. Set bank and enable shared * mem. We always use bank 1. Disable interrupts. */ outb(_3COM_GACFR_RSEL | _3COM_GACFR_MBS0 | _3COM_GACFR_TCM | _3COM_GACFR_NIM, eth_asic_base + _3COM_GACFR); outb(0xff, eth_asic_base + _3COM_VPTR2); outb(0xff, eth_asic_base + _3COM_VPTR1); outb(0x00, eth_asic_base + _3COM_VPTR0); /* * Clear memory and verify that it worked (we use only 8K) */ if (!(eth_flags & FLAG_PIO)) { memset(bus_to_virt(eth_bmem), 0, 0x2000); for(i = 0; i < 0x2000; ++i) if (*((char *)(bus_to_virt(eth_bmem+i)))) { printf ("Failed to clear 3c503 shared mem.\n"); return (0); } } /* * Initialize GA page/start/stop registers. */ outb(eth_tx_start, eth_asic_base + _3COM_PSTR); outb(eth_memsize, eth_asic_base + _3COM_PSPR); }#endif#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390){ /****************************************************************** Search for NE1000/2000 if no WD/SMC or 3com cards ******************************************************************/ unsigned char c; if (eth_vendor == VENDOR_NONE) { char romdata[16], testbuf[32]; int idx; static char test[] = "NE*000 memory"; static unsigned short base[] = {#ifdef NE_SCAN NE_SCAN,#endif 0 }; /* if no addresses supplied, fall back on defaults */ if (probe_addrs == 0 || probe_addrs[0] == 0) probe_addrs = base; eth_bmem = 0; /* No shared memory */ for (idx = 0; (eth_nic_base = probe_addrs[idx]) != 0; ++idx) { eth_flags = FLAG_PIO; eth_asic_base = eth_nic_base + NE_ASIC_OFFSET; eth_memsize = MEM_16384; eth_tx_start = 32; eth_rx_start = 32 + D8390_TXBUF_SIZE; c = inb(eth_asic_base + NE_RESET); outb(c, eth_asic_base + NE_RESET); inb(0x84); outb(D8390_COMMAND_STP | D8390_COMMAND_RD2, eth_nic_base + D8390_P0_COMMAND); outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR); outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR); outb(MEM_8192, eth_nic_base + D8390_P0_PSTART); outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP);#ifdef NS8390_FORCE_16BIT eth_flags |= FLAG_16BIT; /* force 16-bit mode */#endif eth_pio_write(test, 8192, sizeof(test)); eth_pio_read(8192, testbuf, sizeof(test)); if (!memcmp(test, testbuf, sizeof(test))) break; eth_flags |= FLAG_16BIT; eth_memsize = MEM_32768; eth_tx_start = 64; eth_rx_start = 64 + D8390_TXBUF_SIZE; outb(D8390_DCR_WTS | D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR); outb(MEM_16384, eth_nic_base + D8390_P0_PSTART); outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP); eth_pio_write(test, 16384, sizeof(test)); eth_pio_read(16384, testbuf, sizeof(test)); if (!memcmp(testbuf, test, sizeof(test))) break; } if (eth_nic_base == 0) return (0); if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */ eth_flags |= FLAG_16BIT; eth_vendor = VENDOR_NOVELL; eth_pio_read(0, romdata, sizeof(romdata)); for (i=0; i<ETH_ALEN; i++) { nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)]; } printf("\nNE%c000 base %#hx, addr %!\n", (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base, nic->node_addr); }}#endif if (eth_vendor == VENDOR_NONE) return(0); if (eth_vendor != VENDOR_3COM) eth_rmem = eth_bmem; ns8390_reset(nic); dev->disable = ns8390_disable; nic->poll = ns8390_poll; nic->transmit = ns8390_transmit; /* Based on PnP ISA map */#ifdef INCLUDE_WD dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR); dev->devid.device_id = htons(0x812a);#endif#ifdef INCLUDE_3C503 dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR); dev->devid.device_id = htons(0x80f3);#endif#ifdef INCLUDE_NE dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR); dev->devid.device_id = htons(0x80d6);#endif return 1;}#ifdef INCLUDE_WDstatic struct isa_driver wd_driver __isa_driver = { .type = NIC_DRIVER, .name = "WD", .probe = wd_probe, .ioaddrs = 0, };#endif#ifdef INCLUDE_3C503static struct isa_driver t503_driver __isa_driver = { .type = NIC_DRIVER, .name = "3C503", .probe = t503_probe, .ioaddrs = 0, };#endif#ifdef INCLUDE_NEstatic struct isa_driver ne_driver __isa_driver = { .type = NIC_DRIVER, .name = "NE*000", .probe = ne_probe, .ioaddrs = 0, };#endif#ifdef INCLUDE_NS8390static struct pci_id nepci_nics[] = {/* A few NE2000 PCI clones, list not exhaustive */PCI_ROM(0x10ec, 0x8029, "rtl8029", "Realtek 8029"),PCI_ROM(0x1186, 0x0300, "dlink-528", "D-Link DE-528"),PCI_ROM(0x1050, 0x0940, "winbond940", "Winbond NE2000-PCI"), /* Winbond 86C940 / 89C940 */PCI_ROM(0x1050, 0x5a5a, "winbond940f", "Winbond W89c940F"), /* Winbond 89C940F */PCI_ROM(0x11f6, 0x1401, "compexrl2000", "Compex ReadyLink 2000"),PCI_ROM(0x8e2e, 0x3000, "ktiet32p2", "KTI ET32P2"),PCI_ROM(0x4a14, 0x5000, "nv5000sc", "NetVin NV5000SC"),PCI_ROM(0x12c3, 0x0058, "holtek80232", "Holtek HT80232"),PCI_ROM(0x12c3, 0x5598, "holtek80229", "Holtek HT80229"),PCI_ROM(0x10bd, 0x0e34, "surecom-ne34", "Surecom NE34"),PCI_ROM(0x1106, 0x0926, "via86c926", "Via 86c926"),};static struct pci_driver nepci_driver __pci_driver = { .type = NIC_DRIVER, .name = "NE2000/PCI", .probe = nepci_probe, .ids = nepci_nics, .id_count = sizeof(nepci_nics)/sizeof(nepci_nics[0]), .class = 0,};#endif /* INCLUDE_NS8390 *//* * Local variables: * c-basic-offset: 8 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -