1 /* 2 ** File: ne.c Jun. 08, 2000 3 ** 4 ** Driver for the NE*000 ethernet cards and derivates. 5 ** This file contains only the ne specific code, 6 ** the rest is in 8390.c Code specific for ISA bus only 7 ** 8 ** Created: March 15, 1994 by Philip Homburg <philip@cs.vu.nl> 9 ** PchId: ne2000.c,v 1.4 1996/01/19 23:30:34 philip Exp 10 ** 11 ** Modified: Jun. 08, 2000 by Giovanni Falzoni <gfalzoni@inwind.it> 12 ** Adapted to interface new main network task. 13 */ 14 15 #include <minix/drivers.h> 16 #include <minix/netdriver.h> 17 #include "dp.h" 18 19 #if (ENABLE_NE2000 == 1) 20 21 #include "8390.h" 22 #include "ne.h" 23 24 /* 25 ** Name: ne_reset 26 ** Function: Resets the board and checks if reset cycle completes 27 */ 28 static int ne_reset(dpeth_t * dep) 29 { 30 int count = 0; 31 32 /* Reset the ethernet card */ 33 outb_ne(dep, NE_RESET, inb_ne(dep, NE_RESET)); 34 do { 35 if (++count > 10) return FALSE; /* 20 mSecs. timeout */ 36 micro_delay(2000); 37 } while ((inb_ne(dep, DP_ISR) & ISR_RST) == 0); 38 return TRUE; 39 } 40 41 /* 42 ** Name: ne_close 43 ** Function: Stops the board by resetting it and masking interrupts. 44 */ 45 static void ne_close(dpeth_t * dep) 46 { 47 48 (void)ne_reset(dep); 49 outb_ne(dep, DP_ISR, 0xFF); 50 sys_irqdisable(&dep->de_hook); 51 } 52 53 /* 54 ** Name: ne_init 55 ** Function: Initialize the board making it ready to work. 56 */ 57 static void ne_init(dpeth_t * dep) 58 { 59 unsigned int ix; 60 61 dep->de_data_port = dep->de_base_port + NE_DATA; 62 if (dep->de_16bit) { 63 dep->de_ramsize = NE2000_SIZE; 64 dep->de_offset_page = NE2000_START / DP_PAGESIZE; 65 } else { 66 dep->de_ramsize = NE1000_SIZE; 67 dep->de_offset_page = NE1000_START / DP_PAGESIZE; 68 } 69 70 /* Allocates two send buffers from onboard RAM */ 71 dep->de_sendq_nr = SENDQ_NR; 72 for (ix = 0; ix < SENDQ_NR; ix += 1) { 73 dep->de_sendq[ix].sq_sendpage = dep->de_offset_page + ix * SENDQ_PAGES; 74 } 75 76 /* Remaining onboard RAM allocated for receiving */ 77 dep->de_startpage = dep->de_offset_page + ix * SENDQ_PAGES; 78 dep->de_stoppage = dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE; 79 80 /* Can't override the default IRQ. */ 81 dep->de_irq &= NOT(DEI_DEFAULT); 82 83 ns_init(dep); /* Initialize DP controller */ 84 85 printf("%s: NE%d000 (%dkB RAM) at %X:%d - ", 86 netdriver_name(), 87 dep->de_16bit ? 2 : 1, 88 dep->de_ramsize / 1024, 89 dep->de_base_port, dep->de_irq); 90 for (ix = 0; ix < SA_ADDR_LEN; ix += 1) 91 printf("%02X%c", dep->de_address.na_addr[ix], 92 ix < SA_ADDR_LEN - 1 ? ':' : '\n'); 93 } 94 95 /* 96 ** Name: ne_probe 97 ** Function: Probe for the presence of a NE*000 card by testing 98 ** whether the board is reachable through the dp8390. 99 ** Note that the NE1000 is an 8bit card and has a memory 100 ** region distict from the 16bit NE2000. 101 */ 102 int ne_probe(dpeth_t * dep) 103 { 104 unsigned int ix, wd, loc1, loc2; 105 char EPROM[32]; 106 static const struct { 107 unsigned char offset; 108 unsigned char value; 109 } InitSeq[] = 110 { 111 { /* Selects page 0. */ 112 DP_CR, (CR_NO_DMA | CR_PS_P0 | CR_STP), 113 }, 114 { /* Set byte-wide access and 8 bytes burst mode. */ 115 DP_DCR, (DCR_8BYTES | DCR_BMS), 116 }, 117 { /* Clears the count registers. */ 118 DP_RBCR0, 0x00, }, { DP_RBCR1, 0x00, 119 }, 120 { /* Mask completion irq. */ 121 DP_IMR, 0x00, }, { DP_ISR, 0xFF, 122 }, 123 { /* Set receiver to monitor */ 124 DP_RCR, RCR_MON, 125 }, 126 { /* and transmitter to loopback mode. */ 127 DP_TCR, TCR_INTERNAL, 128 }, 129 { /* Transmit 32 bytes */ 130 DP_RBCR0, 32, }, { DP_RBCR1, 0, 131 }, 132 { /* DMA starting at 0x0000. */ 133 DP_RSAR0, 0x00, }, { DP_RSAR1, 0x00, 134 }, 135 { /* Start board (reads) */ 136 DP_CR, (CR_PS_P0 | CR_DM_RR | CR_STA), 137 }, 138 }; 139 140 dep->de_dp8390_port = dep->de_base_port + NE_DP8390; 141 142 if ((loc1 = inb_ne(dep, NE_DP8390)) == 0xFF) return FALSE; 143 144 /* Check if the dp8390 is really there */ 145 outb_ne(dep, DP_CR, CR_STP | CR_NO_DMA | CR_PS_P1); 146 loc2 = inb_ne(dep, DP_MAR5); /* Saves one byte of the address */ 147 outb_ne(dep, DP_MAR5, 0xFF); /* Write 0xFF to it (same offset as DP_CNTR0) */ 148 outb_ne(dep, DP_CR, CR_NO_DMA | CR_PS_P0); /* Back to page 0 */ 149 inb_ne(dep, DP_CNTR0); /* Reading counter resets it */ 150 if (inb_ne(dep, DP_CNTR0) != 0) { 151 outb_ne(dep, NE_DP8390, loc1); /* Try to restore modified bytes */ 152 outb_ne(dep, DP_TCR, loc2); 153 return FALSE; 154 } 155 156 /* Try to reset the board */ 157 if (ne_reset(dep) == FALSE) return FALSE; 158 159 /* Checks whether the board is 8/16bits and a real NE*000 or clone */ 160 for (ix = 0; ix < sizeof(InitSeq)/sizeof(InitSeq[0]); ix += 1) { 161 outb_ne(dep, InitSeq[ix].offset, InitSeq[ix].value); 162 } 163 for (ix = 0, wd = 1; ix < 32; ix += 2) { 164 EPROM[ix + 0] = inb_ne(dep, NE_DATA); 165 EPROM[ix + 1] = inb_ne(dep, NE_DATA); 166 /* NE2000s and clones read same value for even and odd addresses */ 167 if (EPROM[ix + 0] != EPROM[ix + 1]) wd = 0; 168 } 169 if (wd == 1) { /* Normalize EPROM contents for NE2000 */ 170 for (ix = 0; ix < 16; ix += 1) EPROM[ix] = EPROM[ix * 2]; 171 } 172 /* Real NE*000 and good clones have '0x57' at locations 14 and 15 */ 173 if (EPROM[14] != 0x57 || EPROM[15] != 0x57) return FALSE; 174 175 /* Setup the ethernet address. */ 176 for (ix = 0; ix < SA_ADDR_LEN; ix += 1) { 177 dep->de_address.na_addr[ix] = EPROM[ix]; 178 } 179 dep->de_16bit = wd; 180 dep->de_linmem = 0; /* Uses Programmed I/O only */ 181 dep->de_prog_IO = 1; 182 dep->de_initf = ne_init; 183 dep->de_stopf = ne_close; 184 return TRUE; 185 } 186 187 #endif /* ENABLE_NE2000 */ 188 189 /** ne.c **/ 190