1 /* 2 wdeth.c 3 4 Created: March 14, 1994 by Philip Homburg 5 */ 6 7 #include <minix/drivers.h> 8 #include <minix/netdriver.h> 9 10 #include <net/gen/ether.h> 11 #include <net/gen/eth_io.h> 12 #include "assert.h" 13 14 #include "local.h" 15 #include "dp8390.h" 16 #include "wdeth.h" 17 18 #if ENABLE_WDETH 19 20 #define WET_ETHERNET 0x01 /* Ethernet transceiver */ 21 #define WET_STARLAN 0x02 /* Starlan transceiver */ 22 #define WET_INTERF_CHIP 0x04 /* has a WD83C583 interface chip */ 23 #define WET_BRD_16BIT 0x08 /* 16 bit board */ 24 #define WET_SLT_16BIT 0x10 /* 16 bit slot */ 25 #define WET_790 0x20 /* '790 chip */ 26 27 static int we_int_table[8]= { 9, 3, 5, 7, 10, 11, 15, 4 }; 28 static int we_790int_table[8]= { 0, 9, 3, 5, 7, 10, 11, 15 }; 29 30 static void we_init(dpeth_t *dep); 31 static void we_stop(dpeth_t *dep); 32 static int we_aliasing(dpeth_t *dep); 33 static int we_interface_chip(dpeth_t *dep); 34 static int we_16bitboard(dpeth_t *dep); 35 static int we_16bitslot(dpeth_t *dep); 36 static int we_ultra(dpeth_t *dep); 37 38 /*===========================================================================* 39 * wdeth_probe * 40 *===========================================================================*/ 41 int wdeth_probe(dep) 42 dpeth_t *dep; 43 { 44 int sum; 45 46 if (dep->de_linmem == 0) 47 return 0; /* No shared memory, so no WD board */ 48 49 sum = inb_we(dep, EPL_EA0) + inb_we(dep, EPL_EA1) + 50 inb_we(dep, EPL_EA2) + inb_we(dep, EPL_EA3) + 51 inb_we(dep, EPL_EA4) + inb_we(dep, EPL_EA5) + 52 inb_we(dep, EPL_TLB) + inb_we(dep, EPL_CHKSUM); 53 if ((sum & 0xFF) != 0xFF) 54 return 0; /* No ethernet board at this address */ 55 56 dep->de_initf= we_init; 57 dep->de_stopf= we_stop; 58 dep->de_prog_IO= 0; 59 return 1; 60 } 61 62 /*===========================================================================* 63 * we_init * 64 *===========================================================================*/ 65 static void we_init(dep) 66 dpeth_t *dep; 67 { 68 int i, int_indx, int_nr; 69 int tlb, rambit, revision; 70 int icr, irr, hwr, b, gcr; 71 int we_type; 72 int sendq_nr; 73 74 dep->de_address.ea_addr[0] = inb_we(dep, EPL_EA0); 75 dep->de_address.ea_addr[1] = inb_we(dep, EPL_EA1); 76 dep->de_address.ea_addr[2] = inb_we(dep, EPL_EA2); 77 dep->de_address.ea_addr[3] = inb_we(dep, EPL_EA3); 78 dep->de_address.ea_addr[4] = inb_we(dep, EPL_EA4); 79 dep->de_address.ea_addr[5] = inb_we(dep, EPL_EA5); 80 81 dep->de_dp8390_port= dep->de_base_port + EPL_DP8390; 82 83 dep->de_16bit= 0; 84 85 we_type= 0; 86 we_type |= WET_ETHERNET; /* assume ethernet */ 87 if (we_ultra(dep)) 88 we_type |= WET_790; 89 if (!we_aliasing(dep)) 90 { 91 if (we_interface_chip(dep)) 92 we_type |= WET_INTERF_CHIP; 93 if (we_16bitboard(dep)) 94 { 95 we_type |= WET_BRD_16BIT; 96 if (we_16bitslot(dep)) 97 we_type |= WET_SLT_16BIT; 98 } 99 } 100 if (we_type & WET_SLT_16BIT) 101 dep->de_16bit= 1; 102 103 /* look at the on board ram size. */ 104 tlb= inb_we(dep, EPL_TLB); 105 revision= tlb & E_TLB_REV; 106 rambit= tlb & E_TLB_RAM; 107 108 if (dep->de_ramsize != 0) 109 { 110 /* size set from boot environment. */ 111 } 112 else if (revision < 2) 113 { 114 dep->de_ramsize= 0x2000; /* 8K */ 115 if (we_type & WET_BRD_16BIT) 116 dep->de_ramsize= 0x4000; /* 16K */ 117 else if ((we_type & WET_INTERF_CHIP) && 118 inb_we(dep, EPL_ICR) & E_ICR_MEMBIT) 119 { 120 dep->de_ramsize= 0x8000; /* 32K */ 121 } 122 } 123 else 124 { 125 if (we_type & WET_BRD_16BIT) 126 { 127 /* 32K or 16K */ 128 dep->de_ramsize= rambit ? 0x8000 : 0x4000; 129 } 130 else 131 { 132 /* 32K or 8K */ 133 dep->de_ramsize= rambit ? 0x8000 : 0x2000; 134 } 135 } 136 137 if (we_type & WET_790) 138 { 139 outb_we(dep, EPL_MSR, E_MSR_RESET); 140 if ((we_type & (WET_BRD_16BIT|WET_SLT_16BIT)) == 141 (WET_BRD_16BIT|WET_SLT_16BIT)) 142 { 143 outb_we(dep, EPL_LAAR, E_LAAR_LAN16E | E_LAAR_MEM16E); 144 } 145 } 146 else if (we_type & WET_BRD_16BIT) 147 { 148 if (we_type & WET_SLT_16BIT) 149 { 150 outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_SOFTINT | 151 E_LAAR_LAN16E | E_LAAR_MEM16E); 152 } 153 else 154 { 155 outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_SOFTINT | 156 E_LAAR_LAN16E); 157 } 158 } 159 160 if (we_type & WET_790) 161 { 162 outb_we(dep, EPL_MSR, E_MSR_MENABLE); 163 hwr= inb_we(dep, EPL_790_HWR); 164 outb_we(dep, EPL_790_HWR, hwr | E_790_HWR_SWH); 165 b= inb_we(dep, EPL_790_B); 166 outb_we(dep, EPL_790_B, ((dep->de_linmem >> 13) & 0x0f) | 167 ((dep->de_linmem >> 11) & 0x40) | (b & 0xb0)); 168 outb_we(dep, EPL_790_HWR, hwr & ~E_790_HWR_SWH); 169 } 170 else 171 { 172 outb_we(dep, EPL_MSR, E_MSR_RESET); 173 outb_we(dep, EPL_MSR, E_MSR_MENABLE | 174 ((dep->de_linmem >> 13) & E_MSR_MEMADDR)); 175 } 176 177 if ((we_type & WET_INTERF_CHIP) && !(we_type & WET_790)) 178 { 179 icr= inb_we(dep, EPL_ICR); 180 irr= inb_we(dep, EPL_IRR); 181 int_indx= (icr & E_ICR_IR2) | 182 ((irr & (E_IRR_IR0|E_IRR_IR1)) >> 5); 183 int_nr= we_int_table[int_indx]; 184 #if DEBUG 185 { printf("%s: encoded irq= %d\n", dep->de_name, int_nr); } 186 #endif 187 if (dep->de_irq & DEI_DEFAULT) dep->de_irq= int_nr; 188 189 outb_we(dep, EPL_IRR, irr | E_IRR_IEN); 190 } 191 if (we_type & WET_790) 192 { 193 hwr= inb_we(dep, EPL_790_HWR); 194 outb_we(dep, EPL_790_HWR, hwr | E_790_HWR_SWH); 195 196 gcr= inb_we(dep, EPL_790_GCR); 197 198 outb_we(dep, EPL_790_HWR, hwr & ~E_790_HWR_SWH); 199 200 int_indx= ((gcr & E_790_GCR_IR2) >> 4) | 201 ((gcr & (E_790_GCR_IR1|E_790_GCR_IR0)) >> 2); 202 int_nr= we_790int_table[int_indx]; 203 #if DEBUG 204 { printf("%s: encoded irq= %d\n", dep->de_name, int_nr); } 205 #endif 206 if (dep->de_irq & DEI_DEFAULT) dep->de_irq= int_nr; 207 208 icr= inb_we(dep, EPL_790_ICR); 209 outb_we(dep, EPL_790_ICR, icr | E_790_ICR_EIL); 210 } 211 212 /* Strip the "default flag." */ 213 dep->de_irq &= ~DEI_DEFAULT; 214 215 if (!debug) 216 { 217 printf("%s: WD80%d3 at %X:%d:%lX\n", 218 dep->de_name, we_type & WET_BRD_16BIT ? 1 : 0, 219 dep->de_base_port, dep->de_irq, dep->de_linmem); 220 } 221 else 222 { 223 printf("%s: Western Digital %s%s card %s%s at I/O " 224 "address 0x%X, memory address 0x%lX, " 225 "memory size 0x%X, irq %d\n", 226 dep->de_name, 227 we_type & WET_BRD_16BIT ? "16-bit " : "", 228 we_type & WET_ETHERNET ? "Ethernet" : 229 we_type & WET_STARLAN ? "Starlan" : "Network", 230 we_type & WET_INTERF_CHIP ? "with an interface chip " : "", 231 we_type & WET_SLT_16BIT ? "in a 16-bit slot " : "", 232 dep->de_base_port, dep->de_linmem, dep->de_ramsize, 233 dep->de_irq); 234 } 235 236 dep->de_offset_page= 0; /* Shared memory starts at 0 */ 237 238 /* Allocate one send buffer (1.5KB) per 8KB of on board memory. */ 239 sendq_nr= dep->de_ramsize / 0x2000; 240 if (sendq_nr < 1) 241 sendq_nr= 1; 242 else if (sendq_nr > SENDQ_NR) 243 sendq_nr= SENDQ_NR; 244 dep->de_sendq_nr= sendq_nr; 245 for (i= 0; i<sendq_nr; i++) 246 dep->de_sendq[i].sq_sendpage= i*SENDQ_PAGES; 247 248 dep->de_startpage= i*SENDQ_PAGES; 249 dep->de_stoppage= dep->de_ramsize / DP_PAGESIZE; 250 } 251 252 /*===========================================================================* 253 * we_stop * 254 *===========================================================================*/ 255 static void we_stop(dep) 256 dpeth_t *dep; 257 { 258 if (dep->de_16bit) 259 outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_LAN16E); 260 outb_we(dep, EPL_MSR, E_MSR_RESET); 261 outb_we(dep, EPL_MSR, 0); 262 } 263 264 /*===========================================================================* 265 * we_aliasing * 266 *===========================================================================*/ 267 static int we_aliasing(dep) 268 dpeth_t *dep; 269 { 270 /* Determine whether wd8003 hardware performs register aliasing. This implies 271 * an old WD8003E board. */ 272 273 if (inb_we(dep, EPL_REG1) != inb_we(dep, EPL_EA1)) 274 return 0; 275 if (inb_we(dep, EPL_REG2) != inb_we(dep, EPL_EA2)) 276 return 0; 277 if (inb_we(dep, EPL_REG3) != inb_we(dep, EPL_EA3)) 278 return 0; 279 if (inb_we(dep, EPL_REG4) != inb_we(dep, EPL_EA4)) 280 return 0; 281 if (inb_we(dep, EPL_REG7) != inb_we(dep, EPL_CHKSUM)) 282 return 0; 283 return 1; 284 } 285 286 /*===========================================================================* 287 * we_interface_chip * 288 *===========================================================================*/ 289 static int we_interface_chip(dep) 290 dpeth_t *dep; 291 { 292 /* Determine if the board has an interface chip. */ 293 294 outb_we(dep, EPL_GP2, 0x35); 295 if (inb_we(dep, EPL_GP2) != 0x35) 296 return 0; 297 outb_we(dep, EPL_GP2, 0x3A); 298 if (inb_we(dep, EPL_GP2) != 0x3A) 299 return 0; 300 return 1; 301 } 302 303 /*===========================================================================* 304 * we_16bitboard * 305 *===========================================================================*/ 306 static int we_16bitboard(dep) 307 dpeth_t *dep; 308 { 309 /* Determine whether the board is capable of doing 16 bit memory moves. 310 * If the 16 bit enable bit is unchangable by software we'll assume an 311 * 8 bit board. 312 */ 313 int icr; 314 u8_t tlb; 315 316 icr= inb_we(dep, EPL_ICR); 317 318 outb_we(dep, EPL_ICR, icr ^ E_ICR_16BIT); 319 if (inb_we(dep, EPL_ICR) == icr) 320 { 321 tlb= inb_we(dep, EPL_TLB); 322 #if DEBUG 323 printf("%s: tlb= 0x%x\n", dep->de_name, tlb); 324 #endif 325 return tlb == E_TLB_EB || tlb == E_TLB_E || 326 tlb == E_TLB_SMCE || tlb == E_TLB_SMC8216T || 327 tlb == E_TLB_SMC8216C; 328 } 329 outb_we(dep, EPL_ICR, icr); 330 return (icr & E_ICR_16BIT); 331 } 332 333 /*===========================================================================* 334 * we_16bitslot * 335 *===========================================================================*/ 336 static int we_16bitslot(dep) 337 dpeth_t *dep; 338 { 339 /* Determine if the 16 bit board in plugged into a 16 bit slot. */ 340 return !!(inb_we(dep, EPL_ICR) & E_ICR_16BIT); 341 } 342 343 /*===========================================================================* 344 * we_ultra * 345 *===========================================================================*/ 346 static int we_ultra(dep) 347 dpeth_t *dep; 348 { 349 /* Determine if we has an '790 chip. */ 350 u8_t tlb; 351 352 tlb= inb_we(dep, EPL_TLB); 353 return tlb == E_TLB_SMC8216T || tlb == E_TLB_SMC8216C; 354 } 355 356 #endif /* ENABLE_WDETH */ 357 358 /* 359 * $PchId: wdeth.c,v 1.10 2003/09/10 19:31:50 philip Exp $ 360 */ 361