Improve probe routine for CONTEC C-NET(98) card. I/O port and memory

window addresses don't need to be set as default values.

Submitted by:	Yoshimasa Ohnishi <ohnishi@isc.kyutech.ac.jp>
This commit is contained in:
kato 1996-12-21 14:32:35 +00:00
parent f831af1d64
commit 15127256af
2 changed files with 215 additions and 135 deletions

View File

@ -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);
}

View File

@ -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 */
/*