diff --git a/sys/pc98/pc98/if_ed.c b/sys/pc98/pc98/if_ed.c index 203163b9a99..739fa52d07e 100644 --- a/sys/pc98/pc98/if_ed.c +++ b/sys/pc98/pc98/if_ed.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_ed.c,v 1.14 1996/12/11 16:55:27 kato Exp $ + * $Id: if_ed.c,v 1.15 1996/12/15 09:14:46 kato Exp $ */ /* @@ -2030,146 +2030,218 @@ ed_probe_CNET98(isa_dev) { struct ed_softc *sc = &ed_softc[isa_dev->id_unit]; - u_int i; - u_char sum; + int i; + u_long j; + u_char cmd,sum; + u_char tmp,tmp_s,tmp_e; - /* - * Setup card RAM area and i/o addresses - * Kernel Virtual to segment C0000-DFFFF????? - */ + sc->vendor = ED_VENDOR_MISC; /* vendor name */ + sc->type_str = "CNET98"; /* board name */ + sc->isa16bit = 0; /* 16bit mode off = 0 */ + sc->cr_proto = ED_CR_RD2; /* */ + sc->asic_addr = isa_dev->id_iobase; /* 0xa3d0,0xb3d0,0xc3d0 */ + sc->nic_addr = isa_dev->id_iobase; /* 0xd3d0,0xe3d0,0xf3d0 */ + sc->is790 = 0; /* special chip */ - sc->isa16bit = 0; /* 16bit mode off = 0 */ - sc->cr_proto = ED_CR_RD2; - sc->vendor = ED_VENDOR_MISC; /* vendor name */ - sc->asic_addr = isa_dev->id_iobase; - sc->nic_addr = sc->asic_addr; /* 0xa3d0 */ - sc->is790 = 0; /* special chip */ sc->mem_start = (caddr_t)isa_dev->id_maddr; sc->mem_end = sc->mem_start + isa_dev->id_msize; sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE); - sc->mem_size = isa_dev->id_msize; /* 16kbyte */ - sc->mem_shared = 1; /* sharedmemory on=1,off=0 */ - sc->txb_cnt = 1; /* tx buffer counter 1 */ - sc->tx_page_start = 0; /* page offset 0 */ - sc->rec_page_start = ED_TXBUF_SIZE; /* page offset 6 */ + sc->mem_size = isa_dev->id_msize; + sc->mem_shared = 1; /* shared memory on */ + sc->txb_cnt = 1; /* tx buffer counter 1 */ + sc->tx_page_start = 0; /* page offset 0 */ + sc->rec_page_start = ED_TXBUF_SIZE; /* page offset 6 */ sc->rec_page_stop = isa_dev->id_msize / ED_PAGE_SIZE; - /* page offset 40 */ - - if (sc->asic_addr == 0xa3d0) { - /* - * reset card to force it into a known state. - */ - outb(ED_CNET98_INIT_ADDR, 0x00); /* Request */ - DELAY(5000); - outb(ED_CNET98_INIT_ADDR, 0x01); /* Cancel */ - DELAY(5000); - /* - * set i/o address and cpu type - */ - sc->asic_addr = (0xf000 & sc->asic_addr) >> 8; - sc->asic_addr = sc->asic_addr & 0xf0; - sc->asic_addr = sc->asic_addr | 0x09; - /* debug printf(" Board status %x \n",sc->asic_addr); */ - outb((ED_CNET98_INIT_ADDR + 2), sc->asic_addr); - DELAY(1000); - sc->asic_addr = sc->nic_addr; - /* - * set window ethernet address area - * board memory base 0x480000 data 256byte - * window base 0xc40000 - * - * FreeBSD address 0xf00c4000 - */ - outb((sc->asic_addr + ED_CNET98_MAP_REG0L),0x00); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG0H),0x48); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG1L),0x00); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG1H),0x41); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG2L),0x00); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG2H),0x42); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG3L),0x00); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG3H),0x43); - DELAY(10); - - outb((sc->asic_addr + ED_CNET98_WIN_REG),0xc4); - DELAY(10); - /* - * CNET98 checksum code - * - * for (sum = 0, i = 0; i < ETHER_ADDR_LEN; ++i) - * sum ^= *((caddr_t)(isa_dev -> id_maddr + i)); - * printf(" checkusum = %x \n",sum); - */ - - /* - * Get station address from on-board ROM - */ - for (i = 0; i < ETHER_ADDR_LEN; ++i) - sc->arpcom.ac_enaddr[i] = *((caddr_t)(isa_dev -> id_maddr + i)); - - outb((sc->asic_addr + ED_CNET98_WIN_REG),0x44); - DELAY(10); - - /* - * set window buffer memory area - * board memory base 0x400000 data 16kbyte - * window base 0xc40000 - * - * FreeBSD address 0xf00c4000 - */ - outb((sc->asic_addr + ED_CNET98_MAP_REG0L),0x00); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG0H),0x40); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG1L),0x00); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG1H),0x41); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG2L),0x00); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG2H),0x42); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG3L),0x00); - DELAY(10); - outb((sc->asic_addr + ED_CNET98_MAP_REG3H),0x43); - DELAY(10); - - outb((sc->asic_addr + ED_CNET98_WIN_REG),0xc4); - DELAY(10); - - /* - * clear interface memory, then sum to make sure its valid - */ - for (i = 0; i < sc->mem_size; ++i) - sc->mem_start[i] = 0x0; - for (sum = 0, i = 0; i < sc->mem_size; ++i) - sum |= sc->mem_start[i]; - if (sum != 0x0) { - printf("ed%d: CNET98 dual port RAM address error\n", - isa_dev->id_unit); - return (0); - } - /* - * interrupt set - * irq 12 set - */ - /* int 5 set */ - outb((sc->asic_addr + ED_CNET98_INT_MASK),0x7e); - DELAY(1000); - outb((sc->asic_addr + ED_CNET98_INT_LEV),0x20); - DELAY(1000); - - return (32); /* 0xa3d0 -- 0xa3df , 0xa7d0 -- 0xa7df */ - - } else { - return(0); /* error no board */ + /* page offset 40 */ + /* + * Check i/o address. + * 0xa3d0, 0xb3d0, 0xc3d0, 0xd3d0, 0xe3d0, 0xf3d0 + */ + if ( ((sc->asic_addr & (u_short) 0x0fff) != 0x03d0) && + ((sc->asic_addr & (u_short) 0xf000) >= 0xa000) ){ + printf("ed%d: Invalid i/o port configuration (0x%x) must be " + "0x?3d0 for CNET98\n", + isa_dev->id_unit, sc->asic_addr); + return (0); } + /* + * Check window area address. + */ + tmp_s = kvtop(sc->mem_start) >> 12; + if ( tmp_s < 0x80 ) { + printf("ed%d: Please change window address(0x%x) \n", + isa_dev->id_unit,sc->mem_start); + return (0); + } + + tmp = sc->asic_addr >> 12; + tmp_s = (tmp_s & (u_char) 0x0f); + tmp_e = tmp_s + 4; + if ( (tmp_s <= tmp) && (tmp < tmp_e ) ){ +printf("ed%d: Please change iobase address(0x%x) or window address(0x%x) \n", + isa_dev->id_unit,isa_dev->id_iobase,kvtop(sc->mem_start)); + return (0); + } + + /* + * Reset card to force it into a known state. + */ + outb(ED_CNET98_INIT_ADDR, 0x00); /* Request */ + DELAY(5000); + outb(ED_CNET98_INIT_ADDR, 0x01); /* Cancel */ + DELAY(5000); + + /* + * Set i/o address and cpu type + * + * AAAAIXXC(8bit) + * AAAA: A15-A12, I: I/O enable, XX: reserved, C: CPU type + */ + tmp = (sc->asic_addr & (u_short) 0xf000) >> 8; + tmp |= (0x08 | 0x01); +#ifdef ED_DEBUG + printf("ed%d: Board status %x \n",isa_dev->id_unit, tmp); +#endif + outb((ED_CNET98_INIT_ADDR + 2), tmp); + DELAY(1000); + + /* + * Set window ethernet address area + * board memory base 0x480000 data 256byte + * FreeBSD address 0xf00xxxxx + */ + outb((sc->asic_addr + ED_CNET98_MAP_REG0L),0x00); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG0H),0x48); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG1L),0x00); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG1H),0x41); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG2L),0x00); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG2H),0x42); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG3L),0x00); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG3H),0x43); + DELAY(10); + + /* + * Enable window memory(16Kbyte) + * bit7:0 disable , 1 enable + */ + cmd = (kvtop(sc->mem_start) >> 12); +#ifdef ED_DEBUG + printf("ed%d: Set window start address %x \n",isa_dev->id_unit,cmd); +#endif + outb((sc->asic_addr + ED_CNET98_WIN_REG),cmd); + DELAY(10); + /* + * CNET98 checksum code + * + * for (sum = 0, i = 0; i < ETHER_ADDR_LEN; ++i) + * sum ^= *((caddr_t)(isa_dev -> id_maddr + i)); + * printf(" checkusum = %x \n",sum); + */ + + /* + * Get station address from on-board ROM + */ + for (i = 0; i < ETHER_ADDR_LEN; ++i) + sc->arpcom.ac_enaddr[i] = *((caddr_t)(isa_dev -> id_maddr + i)); + + /* + * Disable window memory + * bit7:1 enable , 0 disable + */ + cmd = cmd & 0x7f; + outb((sc->asic_addr + ED_CNET98_WIN_REG),cmd); + DELAY(10); + + /* + * Set window buffer memory area + * board memory base 0x400000 data 16kbyte + * FreeBSD address 0xf00xxxxx + */ + outb((sc->asic_addr + ED_CNET98_MAP_REG0L),0x00); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG0H),0x40); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG1L),0x00); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG1H),0x41); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG2L),0x00); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG2H),0x42); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG3L),0x00); + DELAY(10); + outb((sc->asic_addr + ED_CNET98_MAP_REG3H),0x43); + DELAY(10); + + /* + * Enable window memory + * bit7:1 enable , 0 disable + */ + cmd = cmd | 0x80; + outb((sc->asic_addr + ED_CNET98_WIN_REG),cmd); + DELAY(10); + + /* + * Clear interface memory, then sum to make sure its valid + */ + for (j = 0; j < sc->mem_size; ++j) + sc->mem_start[j] = 0x0; + for (sum = 0, j = 0; j < sc->mem_size; ++j) + sum |= sc->mem_start[j]; + if (sum != 0x0) { + printf("ed%d: CNET98 dual port RAM address error\n", + isa_dev->id_unit); + return (0); + } + + /* + * Set interrupt level + */ + switch (isa_dev->id_irq) { + case IRQ12: + outb((sc->asic_addr + ED_CNET98_INT_LEV),ED_CNET98_INT_IRQ12); + break; + case IRQ3: + outb((sc->asic_addr + ED_CNET98_INT_LEV),ED_CNET98_INT_IRQ3); + break; + case IRQ5: + outb((sc->asic_addr + ED_CNET98_INT_LEV),ED_CNET98_INT_IRQ5); + break; + case IRQ6: + outb((sc->asic_addr + ED_CNET98_INT_LEV),ED_CNET98_INT_IRQ6); + break; + case IRQ9: + outb((sc->asic_addr + ED_CNET98_INT_LEV),ED_CNET98_INT_IRQ9); + break; + case IRQ13: + outb((sc->asic_addr + ED_CNET98_INT_LEV),ED_CNET98_INT_IRQ13); + break; + default: +printf("ed%d: Change Interrupt level default value from %d to %d.\n", + isa_dev->id_irq,IRQ5); + isa_dev->id_irq = IRQ5; + outb((sc->asic_addr + ED_CNET98_INT_LEV),ED_CNET98_INT_IRQ5); + break; + } + DELAY(1000); + /* + * Set interrupt mask. + * bit7:1 all interrupt mask + * bit1:1 timer interrupt mask + * bit0:0 NS controler interrupt enable + */ + outb((sc->asic_addr + ED_CNET98_INT_MASK),0x7e); + DELAY(1000); + + return (ED_CNET98_IO_PORTS); } diff --git a/sys/pc98/pc98/if_ed98.h b/sys/pc98/pc98/if_ed98.h index 476d57480d4..d4d5d8be9f9 100644 --- a/sys/pc98/pc98/if_ed98.h +++ b/sys/pc98/pc98/if_ed98.h @@ -279,7 +279,9 @@ static void pc98_set_register __P((struct isa_device *dev, int type)); * C-NET(98) */ #define ED_CNET98_INIT_ADDR 0xaaed /* 0xaaed reset register */ - /* 0xaaef i/o address set */ + /* 0xaaef i/o address set */ +#define ED_CNET98_IO_PORTS 32 + /* offset NIC address */ #define ED_CNET98_MAP_REG0L 1 /* MAPPING register0 Low */ #define ED_CNET98_MAP_REG1L 3 /* MAPPING register1 Low */ @@ -298,6 +300,12 @@ static void pc98_set_register __P((struct isa_device *dev, int type)); #define ED_CNET98_RESERVE1 (0x400 + 11) #define ED_CNET98_RESERVE2 (0x400 + 13) #define ED_CNET98_RESERVE3 (0x400 + 15) +#define ED_CNET98_INT_IRQ3 0x01 /* INT 0 */ +#define ED_CNET98_INT_IRQ5 0x02 /* INT 1 */ +#define ED_CNET98_INT_IRQ6 0x04 /* INT 2 */ +#define ED_CNET98_INT_IRQ9 0x08 /* INT 3 */ +#define ED_CNET98_INT_IRQ12 0x20 /* INT 5 */ +#define ED_CNET98_INT_IRQ13 0x40 /* INT 6 */ /*