if_ed.c (141548) | if_ed.c (141586) |
---|---|
1/*- 2 * Copyright (c) 1995, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1995, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/dev/ed/if_ed.c 141548 2005-02-08 23:57:43Z imp $"); | 29__FBSDID("$FreeBSD: head/sys/dev/ed/if_ed.c 141586 2005-02-09 20:03:40Z imp $"); |
30 31/* 32 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet 33 * adapters. By David Greenman, 29-April-1993 34 * 35 * Currently supports the Western Digital/SMC 8003 and 8013 series, 36 * the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000, 37 * and a variety of similar clones. --- 25 unchanged lines hidden (view full) --- 63 64#ifndef ED_NO_MIIBUS 65#include <dev/mii/mii.h> 66#include <dev/mii/miivar.h> 67#endif 68 69#include <net/bpf.h> 70 | 30 31/* 32 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet 33 * adapters. By David Greenman, 29-April-1993 34 * 35 * Currently supports the Western Digital/SMC 8003 and 8013 series, 36 * the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000, 37 * and a variety of similar clones. --- 25 unchanged lines hidden (view full) --- 63 64#ifndef ED_NO_MIIBUS 65#include <dev/mii/mii.h> 66#include <dev/mii/miivar.h> 67#endif 68 69#include <net/bpf.h> 70 |
71#include <machine/md_var.h> 72 | |
73#include <dev/ed/if_edreg.h> 74#include <dev/ed/if_edvar.h> 75 76devclass_t ed_devclass; 77 78static void ed_init(void *); 79static int ed_ioctl(struct ifnet *, u_long, caddr_t); 80static void ed_start(struct ifnet *); --- 5 unchanged lines hidden (view full) --- 86 87static void ed_ds_getmcaf(struct ed_softc *, uint32_t *); 88 89static void ed_get_packet(struct ed_softc *, char *, u_short); 90 91static __inline void ed_rint(struct ed_softc *); 92static __inline void ed_xmit(struct ed_softc *); 93static __inline char *ed_ring_copy(struct ed_softc *, char *, char *, u_short); | 71#include <dev/ed/if_edreg.h> 72#include <dev/ed/if_edvar.h> 73 74devclass_t ed_devclass; 75 76static void ed_init(void *); 77static int ed_ioctl(struct ifnet *, u_long, caddr_t); 78static void ed_start(struct ifnet *); --- 5 unchanged lines hidden (view full) --- 84 85static void ed_ds_getmcaf(struct ed_softc *, uint32_t *); 86 87static void ed_get_packet(struct ed_softc *, char *, u_short); 88 89static __inline void ed_rint(struct ed_softc *); 90static __inline void ed_xmit(struct ed_softc *); 91static __inline char *ed_ring_copy(struct ed_softc *, char *, char *, u_short); |
94static void ed_hpp_set_physical_link(struct ed_softc *); 95static void ed_hpp_readmem(struct ed_softc *, long, uint8_t *, uint16_t); 96static void ed_hpp_writemem(struct ed_softc *, uint8_t *, uint16_t, 97 uint16_t); 98static u_short ed_hpp_write_mbufs(struct ed_softc *, struct mbuf *, int); 99 | |
100static u_short ed_pio_write_mbufs(struct ed_softc *, struct mbuf *, long); 101 102static void ed_setrcr(struct ed_softc *); 103 104/* | 92static u_short ed_pio_write_mbufs(struct ed_softc *, struct mbuf *, long); 93 94static void ed_setrcr(struct ed_softc *); 95 96/* |
105 * Interrupt conversion table for WD/SMC ASIC/83C584 106 */ 107static uint16_t ed_intr_val[] = { 108 9, 109 3, 110 5, 111 7, 112 10, 113 11, 114 15, 115 4 116}; 117 118/* 119 * Interrupt conversion table for 83C790 120 */ 121static uint16_t ed_790_intr_val[] = { 122 0, 123 9, 124 3, 125 5, 126 7, 127 10, 128 11, 129 15 130}; 131 132/* 133 * Interrupt conversion table for the HP PC LAN+ 134 */ 135 136static uint16_t ed_hpp_intr_val[] = { 137 0, /* 0 */ 138 0, /* 1 */ 139 0, /* 2 */ 140 3, /* 3 */ 141 4, /* 4 */ 142 5, /* 5 */ 143 6, /* 6 */ 144 7, /* 7 */ 145 0, /* 8 */ 146 9, /* 9 */ 147 10, /* 10 */ 148 11, /* 11 */ 149 12, /* 12 */ 150 0, /* 13 */ 151 0, /* 14 */ 152 15 /* 15 */ 153}; 154 155/* | |
156 * Generic probe routine for testing for the existance of a DS8390. 157 * Must be called after the NIC has just been reset. This routine 158 * works by looking at certain register values that are guaranteed 159 * to be initialized a certain way after power-up or reset. Seems 160 * not to currently work on the 83C690. 161 * 162 * Specifically: 163 * --- 20 unchanged lines hidden (view full) --- 184 return (0); 185 if ((ed_nic_inb(sc, ED_P0_ISR) & ED_ISR_RST) != ED_ISR_RST) 186 return (0); 187 188 return (1); 189} 190 191/* | 97 * Generic probe routine for testing for the existance of a DS8390. 98 * Must be called after the NIC has just been reset. This routine 99 * works by looking at certain register values that are guaranteed 100 * to be initialized a certain way after power-up or reset. Seems 101 * not to currently work on the 83C690. 102 * 103 * Specifically: 104 * --- 20 unchanged lines hidden (view full) --- 125 return (0); 126 if ((ed_nic_inb(sc, ED_P0_ISR) & ED_ISR_RST) != ED_ISR_RST) 127 return (0); 128 129 return (1); 130} 131 132/* |
192 * Probe and vendor-specific initialization routine for SMC/WD80x3 boards 193 */ 194int 195ed_probe_WD80x3_generic(device_t dev, int flags, uint16_t *intr_vals[]) 196{ 197 struct ed_softc *sc = device_get_softc(dev); 198 int error; 199 int i; 200 u_int memsize, maddr; 201 u_char iptr, isa16bit, sum, totalsum; 202 u_long conf_maddr, conf_msize, irq, junk; 203 204 sc->chip_type = ED_CHIP_TYPE_DP8390; 205 206 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_TOSH_ETHER) { 207 totalsum = ED_WD_ROM_CHECKSUM_TOTAL_TOSH_ETHER; 208 ed_asic_outb(sc, ED_WD_MSR, ED_WD_MSR_POW); 209 DELAY(10000); 210 } 211 else 212 totalsum = ED_WD_ROM_CHECKSUM_TOTAL; 213 214 /* 215 * Attempt to do a checksum over the station address PROM. If it 216 * fails, it's probably not a SMC/WD board. There is a problem with 217 * this, though: some clone WD boards don't pass the checksum test. 218 * Danpex boards for one. 219 */ 220 for (sum = 0, i = 0; i < 8; ++i) 221 sum += ed_asic_inb(sc, ED_WD_PROM + i); 222 223 if (sum != totalsum) { 224 225 /* 226 * Checksum is invalid. This often happens with cheap WD8003E 227 * clones. In this case, the checksum byte (the eighth byte) 228 * seems to always be zero. 229 */ 230 if (ed_asic_inb(sc, ED_WD_CARD_ID) != ED_TYPE_WD8003E || 231 ed_asic_inb(sc, ED_WD_PROM + 7) != 0) 232 return (ENXIO); 233 } 234 /* reset card to force it into a known state. */ 235 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_TOSH_ETHER) 236 ed_asic_outb(sc, ED_WD_MSR, ED_WD_MSR_RST | ED_WD_MSR_POW); 237 else 238 ed_asic_outb(sc, ED_WD_MSR, ED_WD_MSR_RST); 239 240 DELAY(100); 241 ed_asic_outb(sc, ED_WD_MSR, ed_asic_inb(sc, ED_WD_MSR) & ~ED_WD_MSR_RST); 242 /* wait in the case this card is reading its EEROM */ 243 DELAY(5000); 244 245 sc->vendor = ED_VENDOR_WD_SMC; 246 sc->type = ed_asic_inb(sc, ED_WD_CARD_ID); 247 248 /* 249 * Set initial values for width/size. 250 */ 251 memsize = 8192; 252 isa16bit = 0; 253 switch (sc->type) { 254 case ED_TYPE_WD8003S: 255 sc->type_str = "WD8003S"; 256 break; 257 case ED_TYPE_WD8003E: 258 sc->type_str = "WD8003E"; 259 break; 260 case ED_TYPE_WD8003EB: 261 sc->type_str = "WD8003EB"; 262 break; 263 case ED_TYPE_WD8003W: 264 sc->type_str = "WD8003W"; 265 break; 266 case ED_TYPE_WD8013EBT: 267 sc->type_str = "WD8013EBT"; 268 memsize = 16384; 269 isa16bit = 1; 270 break; 271 case ED_TYPE_WD8013W: 272 sc->type_str = "WD8013W"; 273 memsize = 16384; 274 isa16bit = 1; 275 break; 276 case ED_TYPE_WD8013EP: /* also WD8003EP */ 277 if (ed_asic_inb(sc, ED_WD_ICR) & ED_WD_ICR_16BIT) { 278 isa16bit = 1; 279 memsize = 16384; 280 sc->type_str = "WD8013EP"; 281 } else { 282 sc->type_str = "WD8003EP"; 283 } 284 break; 285 case ED_TYPE_WD8013WC: 286 sc->type_str = "WD8013WC"; 287 memsize = 16384; 288 isa16bit = 1; 289 break; 290 case ED_TYPE_WD8013EBP: 291 sc->type_str = "WD8013EBP"; 292 memsize = 16384; 293 isa16bit = 1; 294 break; 295 case ED_TYPE_WD8013EPC: 296 sc->type_str = "WD8013EPC"; 297 memsize = 16384; 298 isa16bit = 1; 299 break; 300 case ED_TYPE_SMC8216C: /* 8216 has 16K shared mem -- 8416 has 8K */ 301 case ED_TYPE_SMC8216T: 302 if (sc->type == ED_TYPE_SMC8216C) { 303 sc->type_str = "SMC8216/SMC8216C"; 304 } else { 305 sc->type_str = "SMC8216T"; 306 } 307 308 ed_asic_outb(sc, ED_WD790_HWR, 309 ed_asic_inb(sc, ED_WD790_HWR) | ED_WD790_HWR_SWH); 310 switch (ed_asic_inb(sc, ED_WD790_RAR) & ED_WD790_RAR_SZ64) { 311 case ED_WD790_RAR_SZ64: 312 memsize = 65536; 313 break; 314 case ED_WD790_RAR_SZ32: 315 memsize = 32768; 316 break; 317 case ED_WD790_RAR_SZ16: 318 memsize = 16384; 319 break; 320 case ED_WD790_RAR_SZ8: 321 /* 8216 has 16K shared mem -- 8416 has 8K */ 322 if (sc->type == ED_TYPE_SMC8216C) { 323 sc->type_str = "SMC8416C/SMC8416BT"; 324 } else { 325 sc->type_str = "SMC8416T"; 326 } 327 memsize = 8192; 328 break; 329 } 330 ed_asic_outb(sc, ED_WD790_HWR, 331 ed_asic_inb(sc, ED_WD790_HWR) & ~ED_WD790_HWR_SWH); 332 333 isa16bit = 1; 334 sc->chip_type = ED_CHIP_TYPE_WD790; 335 break; 336 case ED_TYPE_TOSHIBA1: 337 sc->type_str = "Toshiba1"; 338 memsize = 32768; 339 isa16bit = 1; 340 break; 341 case ED_TYPE_TOSHIBA4: 342 sc->type_str = "Toshiba4"; 343 memsize = 32768; 344 isa16bit = 1; 345 break; 346 default: 347 sc->type_str = ""; 348 break; 349 } 350 351 /* 352 * Make some adjustments to initial values depending on what is found 353 * in the ICR. 354 */ 355 if (isa16bit && (sc->type != ED_TYPE_WD8013EBT) 356 && (sc->type != ED_TYPE_TOSHIBA1) && (sc->type != ED_TYPE_TOSHIBA4) 357 && ((ed_asic_inb(sc, ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) { 358 isa16bit = 0; 359 memsize = 8192; 360 } 361 362 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, 363 &conf_maddr, &conf_msize); 364 if (error) 365 return (error); 366 367#ifdef ED_DEBUG 368 printf("type = %x type_str=%s isa16bit=%d memsize=%d id_msize=%lu\n", 369 sc->type, sc->type_str, isa16bit, memsize, conf_msize); 370 for (i = 0; i < 8; i++) 371 printf("%x -> %x\n", i, ed_asic_inb(sc, i)); 372#endif 373 374 /* 375 * Allow the user to override the autoconfiguration 376 */ 377 if (conf_msize > 1) 378 memsize = conf_msize; 379 380 maddr = conf_maddr; 381 if (maddr < 0xa0000 || maddr + memsize > 0x1000000) { 382 device_printf(dev, "Invalid ISA memory address range configured: 0x%x - 0x%x\n", 383 maddr, maddr + memsize); 384 return (ENXIO); 385 } 386 387 /* 388 * (note that if the user specifies both of the following flags that 389 * '8bit' mode intentionally has precedence) 390 */ 391 if (flags & ED_FLAGS_FORCE_16BIT_MODE) 392 isa16bit = 1; 393 if (flags & ED_FLAGS_FORCE_8BIT_MODE) 394 isa16bit = 0; 395 396 /* 397 * If possible, get the assigned interrupt number from the card and 398 * use it. 399 */ 400 if ((sc->type & ED_WD_SOFTCONFIG) && 401 (sc->chip_type != ED_CHIP_TYPE_WD790)) { 402 403 /* 404 * Assemble together the encoded interrupt number. 405 */ 406 iptr = (ed_asic_inb(sc, ED_WD_ICR) & ED_WD_ICR_IR2) | 407 ((ed_asic_inb(sc, ED_WD_IRR) & 408 (ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5); 409 410 /* 411 * If no interrupt specified (or "?"), use what the board tells us. 412 */ 413 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 414 &irq, &junk); 415 if (error && intr_vals[0] != NULL) { 416 error = bus_set_resource(dev, SYS_RES_IRQ, 0, 417 intr_vals[0][iptr], 1); 418 } 419 if (error) 420 return (error); 421 422 /* 423 * Enable the interrupt. 424 */ 425 ed_asic_outb(sc, ED_WD_IRR, 426 ed_asic_inb(sc, ED_WD_IRR) | ED_WD_IRR_IEN); 427 } 428 if (sc->chip_type == ED_CHIP_TYPE_WD790) { 429 ed_asic_outb(sc, ED_WD790_HWR, 430 ed_asic_inb(sc, ED_WD790_HWR) | ED_WD790_HWR_SWH); 431 iptr = (((ed_asic_inb(sc, ED_WD790_GCR) & ED_WD790_GCR_IR2) >> 4) | 432 (ed_asic_inb(sc, ED_WD790_GCR) & 433 (ED_WD790_GCR_IR1 | ED_WD790_GCR_IR0)) >> 2); 434 ed_asic_outb(sc, ED_WD790_HWR, 435 ed_asic_inb(sc, ED_WD790_HWR) & ~ED_WD790_HWR_SWH); 436 437 /* 438 * If no interrupt specified (or "?"), use what the board tells us. 439 */ 440 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 441 &irq, &junk); 442 if (error && intr_vals[1] != NULL) { 443 error = bus_set_resource(dev, SYS_RES_IRQ, 0, 444 intr_vals[1][iptr], 1); 445 } 446 if (error) 447 return (error); 448 449 /* 450 * Enable interrupts. 451 */ 452 ed_asic_outb(sc, ED_WD790_ICR, 453 ed_asic_inb(sc, ED_WD790_ICR) | ED_WD790_ICR_EIL); 454 } 455 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 456 &irq, &junk); 457 if (error) { 458 device_printf(dev, "%s cards don't support auto-detected/assigned interrupts.\n", 459 sc->type_str); 460 return (ENXIO); 461 } 462 sc->isa16bit = isa16bit; 463 sc->mem_shared = 1; 464 465 error = ed_alloc_memory(dev, 0, memsize); 466 if (error) { 467 printf("*** ed_alloc_memory() failed! (%d)\n", error); 468 return (error); 469 } 470 sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res); 471 472 /* 473 * allocate one xmit buffer if < 16k, two buffers otherwise 474 */ 475 if ((memsize < 16384) || 476 (flags & ED_FLAGS_NO_MULTI_BUFFERING)) { 477 sc->txb_cnt = 1; 478 } else { 479 sc->txb_cnt = 2; 480 } 481 sc->tx_page_start = ED_WD_PAGE_OFFSET; 482 sc->rec_page_start = ED_WD_PAGE_OFFSET + ED_TXBUF_SIZE * sc->txb_cnt; 483 sc->rec_page_stop = ED_WD_PAGE_OFFSET + memsize / ED_PAGE_SIZE; 484 sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * sc->rec_page_start); 485 sc->mem_size = memsize; 486 sc->mem_end = sc->mem_start + memsize; 487 488 /* 489 * Get station address from on-board ROM 490 */ 491 for (i = 0; i < ETHER_ADDR_LEN; ++i) 492 sc->arpcom.ac_enaddr[i] = ed_asic_inb(sc, ED_WD_PROM + i); 493 494 /* 495 * Set upper address bits and 8/16 bit access to shared memory. 496 */ 497 if (isa16bit) { 498 if (sc->chip_type == ED_CHIP_TYPE_WD790) { 499 sc->wd_laar_proto = ed_asic_inb(sc, ED_WD_LAAR); 500 } else { 501 sc->wd_laar_proto = ED_WD_LAAR_L16EN | 502 ((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI); 503 } 504 /* 505 * Enable 16bit access 506 */ 507 ed_asic_outb(sc, ED_WD_LAAR, sc->wd_laar_proto | 508 ED_WD_LAAR_M16EN); 509 } else { 510 if (((sc->type & ED_WD_SOFTCONFIG) || 511 (sc->type == ED_TYPE_TOSHIBA1) || 512 (sc->type == ED_TYPE_TOSHIBA4) || 513 (sc->type == ED_TYPE_WD8013EBT)) && 514 (sc->chip_type != ED_CHIP_TYPE_WD790)) { 515 sc->wd_laar_proto = (kvtop(sc->mem_start) >> 19) & 516 ED_WD_LAAR_ADDRHI; 517 ed_asic_outb(sc, ED_WD_LAAR, sc->wd_laar_proto); 518 } 519 } 520 521 /* 522 * Set address and enable interface shared memory. 523 */ 524 if (sc->chip_type != ED_CHIP_TYPE_WD790) { 525 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_TOSH_ETHER) { 526 ed_asic_outb(sc, ED_WD_MSR + 1, 527 ((kvtop(sc->mem_start) >> 8) & 0xe0) | 4); 528 ed_asic_outb(sc, ED_WD_MSR + 2, 529 ((kvtop(sc->mem_start) >> 16) & 0x0f)); 530 ed_asic_outb(sc, ED_WD_MSR, 531 ED_WD_MSR_MENB | ED_WD_MSR_POW); 532 } else { 533 ed_asic_outb(sc, ED_WD_MSR, 534 ((kvtop(sc->mem_start) >> 13) & 535 ED_WD_MSR_ADDR) | ED_WD_MSR_MENB); 536 } 537 sc->cr_proto = ED_CR_RD2; 538 } else { 539 ed_asic_outb(sc, ED_WD_MSR, ED_WD_MSR_MENB); 540 ed_asic_outb(sc, ED_WD790_HWR, (ed_asic_inb(sc, ED_WD790_HWR) | ED_WD790_HWR_SWH)); 541 ed_asic_outb(sc, ED_WD790_RAR, ((kvtop(sc->mem_start) >> 13) & 0x0f) | 542 ((kvtop(sc->mem_start) >> 11) & 0x40) | 543 (ed_asic_inb(sc, ED_WD790_RAR) & 0xb0)); 544 ed_asic_outb(sc, ED_WD790_HWR, (ed_asic_inb(sc, ED_WD790_HWR) & ~ED_WD790_HWR_SWH)); 545 sc->cr_proto = 0; 546 } 547 548#if 0 549 printf("starting memory performance test at 0x%x, size %d...\n", 550 sc->mem_start, memsize*16384); 551 for (i = 0; i < 16384; i++) 552 bzero(sc->mem_start, memsize); 553 printf("***DONE***\n"); 554#endif 555 556 /* 557 * Now zero memory and verify that it is clear 558 */ 559 bzero(sc->mem_start, memsize); 560 561 for (i = 0; i < memsize; ++i) { 562 if (sc->mem_start[i]) { 563 device_printf(dev, "failed to clear shared memory at %jx - check configuration\n", 564 (uintmax_t)kvtop(sc->mem_start + i)); 565 566 /* 567 * Disable 16 bit access to shared memory 568 */ 569 if (isa16bit) { 570 if (sc->chip_type == ED_CHIP_TYPE_WD790) { 571 ed_asic_outb(sc, ED_WD_MSR, 0x00); 572 } 573 ed_asic_outb(sc, ED_WD_LAAR, sc->wd_laar_proto & 574 ~ED_WD_LAAR_M16EN); 575 } 576 return (ENXIO); 577 } 578 } 579 580 /* 581 * Disable 16bit access to shared memory - we leave it 582 * disabled so that 1) machines reboot properly when the board 583 * is set 16 bit mode and there are conflicting 8bit 584 * devices/ROMS in the same 128k address space as this boards 585 * shared memory. and 2) so that other 8 bit devices with 586 * shared memory can be used in this 128k region, too. 587 */ 588 if (isa16bit) { 589 if (sc->chip_type == ED_CHIP_TYPE_WD790) { 590 ed_asic_outb(sc, ED_WD_MSR, 0x00); 591 } 592 ed_asic_outb(sc, ED_WD_LAAR, sc->wd_laar_proto & 593 ~ED_WD_LAAR_M16EN); 594 } 595 return (0); 596} 597 598int 599ed_probe_WD80x3(device_t dev, int port_rid, int flags) 600{ 601 struct ed_softc *sc = device_get_softc(dev); 602 int error; 603 static uint16_t *intr_vals[] = {ed_intr_val, ed_790_intr_val}; 604 605 error = ed_alloc_port(dev, port_rid, ED_WD_IO_PORTS); 606 if (error) 607 return (error); 608 609 sc->asic_offset = ED_WD_ASIC_OFFSET; 610 sc->nic_offset = ED_WD_NIC_OFFSET; 611 612 return ed_probe_WD80x3_generic(dev, flags, intr_vals); 613} 614 615/* 616 * Probe and vendor-specific initialization routine for 3Com 3c503 boards 617 */ 618int 619ed_probe_3Com(device_t dev, int port_rid, int flags) 620{ 621 struct ed_softc *sc = device_get_softc(dev); 622 int error; 623 int i; 624 u_int memsize; 625 u_char isa16bit; 626 u_long conf_maddr, conf_msize, irq, junk; 627 628 error = ed_alloc_port(dev, 0, ED_3COM_IO_PORTS); 629 if (error) 630 return (error); 631 632 sc->asic_offset = ED_3COM_ASIC_OFFSET; 633 sc->nic_offset = ED_3COM_NIC_OFFSET; 634 635 /* 636 * Verify that the kernel configured I/O address matches the board 637 * configured address 638 */ 639 switch (ed_asic_inb(sc, ED_3COM_BCFR)) { 640 case ED_3COM_BCFR_300: 641 if (rman_get_start(sc->port_res) != 0x300) 642 return (ENXIO); 643 break; 644 case ED_3COM_BCFR_310: 645 if (rman_get_start(sc->port_res) != 0x310) 646 return (ENXIO); 647 break; 648 case ED_3COM_BCFR_330: 649 if (rman_get_start(sc->port_res) != 0x330) 650 return (ENXIO); 651 break; 652 case ED_3COM_BCFR_350: 653 if (rman_get_start(sc->port_res) != 0x350) 654 return (ENXIO); 655 break; 656 case ED_3COM_BCFR_250: 657 if (rman_get_start(sc->port_res) != 0x250) 658 return (ENXIO); 659 break; 660 case ED_3COM_BCFR_280: 661 if (rman_get_start(sc->port_res) != 0x280) 662 return (ENXIO); 663 break; 664 case ED_3COM_BCFR_2A0: 665 if (rman_get_start(sc->port_res) != 0x2a0) 666 return (ENXIO); 667 break; 668 case ED_3COM_BCFR_2E0: 669 if (rman_get_start(sc->port_res) != 0x2e0) 670 return (ENXIO); 671 break; 672 default: 673 return (ENXIO); 674 } 675 676 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, 677 &conf_maddr, &conf_msize); 678 if (error) 679 return (error); 680 681 /* 682 * Verify that the kernel shared memory address matches the board 683 * configured address. 684 */ 685 switch (ed_asic_inb(sc, ED_3COM_PCFR)) { 686 case ED_3COM_PCFR_DC000: 687 if (conf_maddr != 0xdc000) 688 return (ENXIO); 689 break; 690 case ED_3COM_PCFR_D8000: 691 if (conf_maddr != 0xd8000) 692 return (ENXIO); 693 break; 694 case ED_3COM_PCFR_CC000: 695 if (conf_maddr != 0xcc000) 696 return (ENXIO); 697 break; 698 case ED_3COM_PCFR_C8000: 699 if (conf_maddr != 0xc8000) 700 return (ENXIO); 701 break; 702 default: 703 return (ENXIO); 704 } 705 706 707 /* 708 * Reset NIC and ASIC. Enable on-board transceiver throughout reset 709 * sequence because it'll lock up if the cable isn't connected if we 710 * don't. 711 */ 712 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_RST | ED_3COM_CR_XSEL); 713 714 /* 715 * Wait for a while, then un-reset it 716 */ 717 DELAY(50); 718 719 /* 720 * The 3Com ASIC defaults to rather strange settings for the CR after 721 * a reset - it's important to set it again after the following outb 722 * (this is done when we map the PROM below). 723 */ 724 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); 725 726 /* 727 * Wait a bit for the NIC to recover from the reset 728 */ 729 DELAY(5000); 730 731 sc->vendor = ED_VENDOR_3COM; 732 sc->type_str = "3c503"; 733 sc->mem_shared = 1; 734 sc->cr_proto = ED_CR_RD2; 735 736 /* 737 * Hmmm...a 16bit 3Com board has 16k of memory, but only an 8k window 738 * to it. 739 */ 740 memsize = 8192; 741 742 /* 743 * Get station address from on-board ROM 744 */ 745 746 /* 747 * First, map ethernet address PROM over the top of where the NIC 748 * registers normally appear. 749 */ 750 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_EALO | ED_3COM_CR_XSEL); 751 752 for (i = 0; i < ETHER_ADDR_LEN; ++i) 753 sc->arpcom.ac_enaddr[i] = ed_nic_inb(sc, i); 754 755 /* 756 * Unmap PROM - select NIC registers. The proper setting of the 757 * tranceiver is set in ed_init so that the attach code is given a 758 * chance to set the default based on a compile-time config option 759 */ 760 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); 761 762 /* 763 * Determine if this is an 8bit or 16bit board 764 */ 765 766 /* 767 * select page 0 registers 768 */ 769 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 770 771 /* 772 * Attempt to clear WTS bit. If it doesn't clear, then this is a 16bit 773 * board. 774 */ 775 ed_nic_outb(sc, ED_P0_DCR, 0); 776 777 /* 778 * select page 2 registers 779 */ 780 ed_nic_outb(sc, ED_P0_CR, ED_CR_PAGE_2 | ED_CR_RD2 | ED_CR_STP); 781 782 /* 783 * The 3c503 forces the WTS bit to a one if this is a 16bit board 784 */ 785 if (ed_nic_inb(sc, ED_P2_DCR) & ED_DCR_WTS) 786 isa16bit = 1; 787 else 788 isa16bit = 0; 789 790 /* 791 * select page 0 registers 792 */ 793 ed_nic_outb(sc, ED_P2_CR, ED_CR_RD2 | ED_CR_STP); 794 795 error = ed_alloc_memory(dev, 0, memsize); 796 if (error) 797 return (error); 798 799 sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res); 800 sc->mem_size = memsize; 801 sc->mem_end = sc->mem_start + memsize; 802 803 /* 804 * We have an entire 8k window to put the transmit buffers on the 805 * 16bit boards. But since the 16bit 3c503's shared memory is only 806 * fast enough to overlap the loading of one full-size packet, trying 807 * to load more than 2 buffers can actually leave the transmitter idle 808 * during the load. So 2 seems the best value. (Although a mix of 809 * variable-sized packets might change this assumption. Nonetheless, 810 * we optimize for linear transfers of same-size packets.) 811 */ 812 if (isa16bit) { 813 if (flags & ED_FLAGS_NO_MULTI_BUFFERING) 814 sc->txb_cnt = 1; 815 else 816 sc->txb_cnt = 2; 817 818 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_16BIT; 819 sc->rec_page_start = ED_3COM_RX_PAGE_OFFSET_16BIT; 820 sc->rec_page_stop = memsize / ED_PAGE_SIZE + 821 ED_3COM_RX_PAGE_OFFSET_16BIT; 822 sc->mem_ring = sc->mem_start; 823 } else { 824 sc->txb_cnt = 1; 825 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_8BIT; 826 sc->rec_page_start = ED_TXBUF_SIZE + ED_3COM_TX_PAGE_OFFSET_8BIT; 827 sc->rec_page_stop = memsize / ED_PAGE_SIZE + 828 ED_3COM_TX_PAGE_OFFSET_8BIT; 829 sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE); 830 } 831 832 sc->isa16bit = isa16bit; 833 834 /* 835 * Initialize GA page start/stop registers. Probably only needed if 836 * doing DMA, but what the hell. 837 */ 838 ed_asic_outb(sc, ED_3COM_PSTR, sc->rec_page_start); 839 ed_asic_outb(sc, ED_3COM_PSPR, sc->rec_page_stop); 840 841 /* 842 * Set IRQ. 3c503 only allows a choice of irq 2-5. 843 */ 844 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk); 845 if (error) 846 return (error); 847 848 switch (irq) { 849 case 2: 850 case 9: 851 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2); 852 break; 853 case 3: 854 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ3); 855 break; 856 case 4: 857 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ4); 858 break; 859 case 5: 860 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5); 861 break; 862 default: 863 device_printf(dev, "Invalid irq configuration (%ld) must be 3-5,9 for 3c503\n", 864 irq); 865 return (ENXIO); 866 } 867 868 /* 869 * Initialize GA configuration register. Set bank and enable shared 870 * mem. 871 */ 872 ed_asic_outb(sc, ED_3COM_GACFR, ED_3COM_GACFR_RSEL | 873 ED_3COM_GACFR_MBS0); 874 875 /* 876 * Initialize "Vector Pointer" registers. These gawd-awful things are 877 * compared to 20 bits of the address on ISA, and if they match, the 878 * shared memory is disabled. We set them to 0xffff0...allegedly the 879 * reset vector. 880 */ 881 ed_asic_outb(sc, ED_3COM_VPTR2, 0xff); 882 ed_asic_outb(sc, ED_3COM_VPTR1, 0xff); 883 ed_asic_outb(sc, ED_3COM_VPTR0, 0x00); 884 885 /* 886 * Zero memory and verify that it is clear 887 */ 888 bzero(sc->mem_start, memsize); 889 890 for (i = 0; i < memsize; ++i) 891 if (sc->mem_start[i]) { 892 device_printf(dev, "failed to clear shared memory at %jx - check configuration\n", 893 (uintmax_t)kvtop(sc->mem_start + i)); 894 return (ENXIO); 895 } 896 return (0); 897} 898 899/* 900 * Probe and vendor-specific initialization routine for SIC boards 901 */ 902int 903ed_probe_SIC(device_t dev, int port_rid, int flags) 904{ 905 struct ed_softc *sc = device_get_softc(dev); 906 int error; 907 int i; 908 u_int memsize; 909 u_long conf_maddr, conf_msize; 910 u_char sum; 911 912 error = ed_alloc_port(dev, 0, ED_SIC_IO_PORTS); 913 if (error) 914 return (error); 915 916 sc->asic_offset = ED_SIC_ASIC_OFFSET; 917 sc->nic_offset = ED_SIC_NIC_OFFSET; 918 919 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, 920 &conf_maddr, &conf_msize); 921 if (error) 922 return (error); 923 924 memsize = 16384; 925 if (conf_msize > 1) 926 memsize = conf_msize; 927 928 error = ed_alloc_memory(dev, 0, memsize); 929 if (error) 930 return (error); 931 932 sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res); 933 sc->mem_size = memsize; 934 935 /* Reset card to force it into a known state. */ 936 ed_asic_outb(sc, 0, 0x00); 937 DELAY(100); 938 939 /* 940 * Here we check the card ROM, if the checksum passes, and the 941 * type code and ethernet address check out, then we know we have 942 * an SIC card. 943 */ 944 ed_asic_outb(sc, 0, 0x81); 945 DELAY(100); 946 947 sum = sc->mem_start[6]; 948 for (i = 0; i < ETHER_ADDR_LEN; i++) { 949 sum ^= (sc->arpcom.ac_enaddr[i] = sc->mem_start[i]); 950 } 951#ifdef ED_DEBUG 952 device_printf(dev, "ed_probe_sic: got address %6D\n", 953 sc->arpcom.ac_enaddr, ":"); 954#endif 955 if (sum != 0) { 956 return (ENXIO); 957 } 958 if ((sc->arpcom.ac_enaddr[0] | sc->arpcom.ac_enaddr[1] | 959 sc->arpcom.ac_enaddr[2]) == 0) { 960 return (ENXIO); 961 } 962 963 sc->vendor = ED_VENDOR_SIC; 964 sc->type_str = "SIC"; 965 sc->isa16bit = 0; 966 sc->cr_proto = 0; 967 968 /* 969 * SIC RAM page 0x0000-0x3fff(or 0x7fff) 970 */ 971 ed_asic_outb(sc, 0, 0x80); 972 DELAY(100); 973 974 /* 975 * Now zero memory and verify that it is clear 976 */ 977 bzero(sc->mem_start, sc->mem_size); 978 979 for (i = 0; i < sc->mem_size; i++) { 980 if (sc->mem_start[i]) { 981 device_printf(dev, "failed to clear shared memory " 982 "at %jx - check configuration\n", 983 (uintmax_t)kvtop(sc->mem_start + i)); 984 985 return (ENXIO); 986 } 987 } 988 989 sc->mem_shared = 1; 990 sc->mem_end = sc->mem_start + sc->mem_size; 991 992 /* 993 * allocate one xmit buffer if < 16k, two buffers otherwise 994 */ 995 if ((sc->mem_size < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) { 996 sc->txb_cnt = 1; 997 } else { 998 sc->txb_cnt = 2; 999 } 1000 sc->tx_page_start = 0; 1001 1002 sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE * sc->txb_cnt; 1003 sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE; 1004 1005 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 1006 1007 return (0); 1008} 1009 1010/* 1011 * Probe and vendor-specific initialization routine for NE1000/2000 boards 1012 */ 1013int 1014ed_probe_Novell_generic(device_t dev, int flags) 1015{ 1016 struct ed_softc *sc = device_get_softc(dev); 1017 u_int memsize, n; 1018 u_char romdata[16], tmp; 1019 static char test_pattern[32] = "THIS is A memory TEST pattern"; 1020 char test_buffer[32]; 1021 1022 /* XXX - do Novell-specific probe here */ 1023 1024 /* Reset the board */ 1025 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) { 1026 ed_asic_outb(sc, ED_NOVELL_RESET, 0); 1027 DELAY(200); 1028 } 1029 tmp = ed_asic_inb(sc, ED_NOVELL_RESET); 1030 1031 /* 1032 * I don't know if this is necessary; probably cruft leftover from 1033 * Clarkson packet driver code. Doesn't do a thing on the boards I've 1034 * tested. -DG [note that an outb(0x84, 0) seems to work here, and is 1035 * non-invasive...but some boards don't seem to reset and I don't have 1036 * complete documentation on what the 'right' thing to do is...so we 1037 * do the invasive thing for now. Yuck.] 1038 */ 1039 ed_asic_outb(sc, ED_NOVELL_RESET, tmp); 1040 DELAY(5000); 1041 1042 /* 1043 * This is needed because some NE clones apparently don't reset the 1044 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1045 * - this makes the probe invasive! ...Done against my better 1046 * judgement. -DLG 1047 */ 1048 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1049 1050 DELAY(5000); 1051 1052 /* Make sure that we really have an 8390 based board */ 1053 if (!ed_probe_generic8390(sc)) 1054 return (ENXIO); 1055 1056 sc->vendor = ED_VENDOR_NOVELL; 1057 sc->mem_shared = 0; 1058 sc->cr_proto = ED_CR_RD2; 1059 1060 /* 1061 * Test the ability to read and write to the NIC memory. This has the 1062 * side affect of determining if this is an NE1000 or an NE2000. 1063 */ 1064 1065 /* 1066 * This prevents packets from being stored in the NIC memory when the 1067 * readmem routine turns on the start bit in the CR. 1068 */ 1069 ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON); 1070 1071 /* Temporarily initialize DCR for byte operations */ 1072 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); 1073 1074 ed_nic_outb(sc, ED_P0_PSTART, 8192 / ED_PAGE_SIZE); 1075 ed_nic_outb(sc, ED_P0_PSTOP, 16384 / ED_PAGE_SIZE); 1076 1077 sc->isa16bit = 0; 1078 1079 /* 1080 * Write a test pattern in byte mode. If this fails, then there 1081 * probably isn't any memory at 8k - which likely means that the board 1082 * is an NE2000. 1083 */ 1084 ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern)); 1085 ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern)); 1086 1087 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) { 1088 sc->type = ED_TYPE_NE1000; 1089 sc->type_str = "NE1000"; 1090 } else { 1091 1092 /* neither an NE1000 nor a Linksys - try NE2000 */ 1093 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); 1094 ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE); 1095 ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE); 1096 1097 sc->isa16bit = 1; 1098 1099 /* 1100 * Write a test pattern in word mode. If this also fails, then 1101 * we don't know what this board is. 1102 */ 1103 ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern)); 1104 ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern)); 1105 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) { 1106 sc->type = ED_TYPE_NE2000; 1107 sc->type_str = "NE2000"; 1108 } else { 1109 return (ENXIO); 1110 } 1111 } 1112 1113 1114 /* 8k of memory plus an additional 8k if 16bit */ 1115 memsize = 8192 + sc->isa16bit * 8192; 1116 1117#if 0 /* probably not useful - NE boards only come two ways */ 1118 /* allow kernel config file overrides */ 1119 if (isa_dev->id_msize) 1120 memsize = isa_dev->id_msize; 1121#endif 1122 1123 sc->mem_size = memsize; 1124 1125 /* NIC memory doesn't start at zero on an NE board */ 1126 /* The start address is tied to the bus width */ 1127 sc->mem_start = (char *) 8192 + sc->isa16bit * 8192; 1128 sc->mem_end = sc->mem_start + memsize; 1129 sc->tx_page_start = memsize / ED_PAGE_SIZE; 1130 1131 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) { 1132 int x, i, msize = 0; 1133 long mstart = 0; 1134 char pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE]; 1135 1136 for (i = 0; i < ED_PAGE_SIZE; i++) 1137 pbuf0[i] = 0; 1138 1139 /* Clear all the memory. */ 1140 for (x = 1; x < 256; x++) 1141 ed_pio_writemem(sc, pbuf0, x * 256, ED_PAGE_SIZE); 1142 1143 /* Search for the start of RAM. */ 1144 for (x = 1; x < 256; x++) { 1145 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 1146 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) { 1147 for (i = 0; i < ED_PAGE_SIZE; i++) 1148 pbuf[i] = 255 - x; 1149 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE); 1150 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 1151 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) { 1152 mstart = x * ED_PAGE_SIZE; 1153 msize = ED_PAGE_SIZE; 1154 break; 1155 } 1156 } 1157 } 1158 1159 if (mstart == 0) { 1160 device_printf(dev, "Cannot find start of RAM.\n"); 1161 return (ENXIO); 1162 } 1163 /* Search for the start of RAM. */ 1164 for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) { 1165 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 1166 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) { 1167 for (i = 0; i < ED_PAGE_SIZE; i++) 1168 pbuf[i] = 255 - x; 1169 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE); 1170 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 1171 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) 1172 msize += ED_PAGE_SIZE; 1173 else { 1174 break; 1175 } 1176 } else { 1177 break; 1178 } 1179 } 1180 1181 if (msize == 0) { 1182 device_printf(dev, "Cannot find any RAM, start : %ld, x = %d.\n", mstart, x); 1183 return (ENXIO); 1184 } 1185 device_printf(dev, "RAM start at %ld, size : %d.\n", mstart, msize); 1186 1187 sc->mem_size = msize; 1188 sc->mem_start = (caddr_t)(uintptr_t) mstart; 1189 sc->mem_end = (caddr_t)(uintptr_t) (msize + mstart); 1190 sc->tx_page_start = mstart / ED_PAGE_SIZE; 1191 } 1192 1193 /* 1194 * Use one xmit buffer if < 16k, two buffers otherwise (if not told 1195 * otherwise). 1196 */ 1197 if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) 1198 sc->txb_cnt = 1; 1199 else 1200 sc->txb_cnt = 2; 1201 1202 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; 1203 sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE; 1204 1205 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 1206 1207 ed_pio_readmem(sc, 0, romdata, 16); 1208 for (n = 0; n < ETHER_ADDR_LEN; n++) 1209 sc->arpcom.ac_enaddr[n] = romdata[n * (sc->isa16bit + 1)]; 1210 1211 if ((ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) && 1212 (sc->arpcom.ac_enaddr[2] == 0x86)) { 1213 sc->type_str = "Gateway AT"; 1214 } 1215 1216 /* clear any pending interrupts that might have occurred above */ 1217 ed_nic_outb(sc, ED_P0_ISR, 0xff); 1218 1219 return (0); 1220} 1221 1222int 1223ed_probe_Novell(device_t dev, int port_rid, int flags) 1224{ 1225 struct ed_softc *sc = device_get_softc(dev); 1226 int error; 1227 1228 error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS); 1229 if (error) 1230 return (error); 1231 1232 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1233 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1234 1235 return ed_probe_Novell_generic(dev, flags); 1236} 1237 1238#define ED_HPP_TEST_SIZE 16 1239 1240/* 1241 * Probe and vendor specific initialization for the HP PC Lan+ Cards. 1242 * (HP Part nos: 27247B and 27252A). 1243 * 1244 * The card has an asic wrapper around a DS8390 core. The asic handles 1245 * host accesses and offers both standard register IO and memory mapped 1246 * IO. Memory mapped I/O allows better performance at the expense of greater 1247 * chance of an incompatibility with existing ISA cards. 1248 * 1249 * The card has a few caveats: it isn't tolerant of byte wide accesses, only 1250 * short (16 bit) or word (32 bit) accesses are allowed. Some card revisions 1251 * don't allow 32 bit accesses; these are indicated by a bit in the software 1252 * ID register (see if_edreg.h). 1253 * 1254 * Other caveats are: we should read the MAC address only when the card 1255 * is inactive. 1256 * 1257 * For more information; please consult the CRYNWR packet driver. 1258 * 1259 * The AUI port is turned on using the "link2" option on the ifconfig 1260 * command line. 1261 */ 1262int 1263ed_probe_HP_pclanp(device_t dev, int port_rid, int flags) 1264{ 1265 struct ed_softc *sc = device_get_softc(dev); 1266 int error; 1267 int n; /* temp var */ 1268 int memsize; /* mem on board */ 1269 u_char checksum; /* checksum of board address */ 1270 u_char irq; /* board configured IRQ */ 1271 uint8_t test_pattern[ED_HPP_TEST_SIZE]; /* read/write areas for */ 1272 uint8_t test_buffer[ED_HPP_TEST_SIZE]; /* probing card */ 1273 u_long conf_maddr, conf_msize, conf_irq, junk; 1274 1275 error = ed_alloc_port(dev, 0, ED_HPP_IO_PORTS); 1276 if (error) 1277 return (error); 1278 1279 /* Fill in basic information */ 1280 sc->asic_offset = ED_HPP_ASIC_OFFSET; 1281 sc->nic_offset = ED_HPP_NIC_OFFSET; 1282 1283 sc->chip_type = ED_CHIP_TYPE_DP8390; 1284 sc->isa16bit = 0; /* the 8390 core needs to be in byte mode */ 1285 1286 /* 1287 * Look for the HP PCLAN+ signature: "0x50,0x48,0x00,0x53" 1288 */ 1289 1290 if ((ed_asic_inb(sc, ED_HPP_ID) != 0x50) || 1291 (ed_asic_inb(sc, ED_HPP_ID + 1) != 0x48) || 1292 ((ed_asic_inb(sc, ED_HPP_ID + 2) & 0xF0) != 0) || 1293 (ed_asic_inb(sc, ED_HPP_ID + 3) != 0x53)) 1294 return ENXIO; 1295 1296 /* 1297 * Read the MAC address and verify checksum on the address. 1298 */ 1299 1300 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_MAC); 1301 for (n = 0, checksum = 0; n < ETHER_ADDR_LEN; n++) 1302 checksum += (sc->arpcom.ac_enaddr[n] = 1303 ed_asic_inb(sc, ED_HPP_MAC_ADDR + n)); 1304 1305 checksum += ed_asic_inb(sc, ED_HPP_MAC_ADDR + ETHER_ADDR_LEN); 1306 1307 if (checksum != 0xFF) 1308 return ENXIO; 1309 1310 /* 1311 * Verify that the software model number is 0. 1312 */ 1313 1314 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_ID); 1315 if (((sc->hpp_id = ed_asic_inw(sc, ED_HPP_PAGE_4)) & 1316 ED_HPP_ID_SOFT_MODEL_MASK) != 0x0000) 1317 return ENXIO; 1318 1319 /* 1320 * Read in and save the current options configured on card. 1321 */ 1322 1323 sc->hpp_options = ed_asic_inw(sc, ED_HPP_OPTION); 1324 1325 sc->hpp_options |= (ED_HPP_OPTION_NIC_RESET | 1326 ED_HPP_OPTION_CHIP_RESET | 1327 ED_HPP_OPTION_ENABLE_IRQ); 1328 1329 /* 1330 * Reset the chip. This requires writing to the option register 1331 * so take care to preserve the other bits. 1332 */ 1333 1334 ed_asic_outw(sc, ED_HPP_OPTION, 1335 (sc->hpp_options & ~(ED_HPP_OPTION_NIC_RESET | 1336 ED_HPP_OPTION_CHIP_RESET))); 1337 1338 DELAY(5000); /* wait for chip reset to complete */ 1339 1340 ed_asic_outw(sc, ED_HPP_OPTION, 1341 (sc->hpp_options | (ED_HPP_OPTION_NIC_RESET | 1342 ED_HPP_OPTION_CHIP_RESET | 1343 ED_HPP_OPTION_ENABLE_IRQ))); 1344 1345 DELAY(5000); 1346 1347 if (!(ed_nic_inb(sc, ED_P0_ISR) & ED_ISR_RST)) 1348 return ENXIO; /* reset did not complete */ 1349 1350 /* 1351 * Read out configuration information. 1352 */ 1353 1354 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_HW); 1355 1356 irq = ed_asic_inb(sc, ED_HPP_HW_IRQ); 1357 1358 /* 1359 * Check for impossible IRQ. 1360 */ 1361 1362 if (irq >= (sizeof(ed_hpp_intr_val) / sizeof(ed_hpp_intr_val[0]))) 1363 return ENXIO; 1364 1365 /* 1366 * If the kernel IRQ was specified with a '?' use the cards idea 1367 * of the IRQ. If the kernel IRQ was explicitly specified, it 1368 * should match that of the hardware. 1369 */ 1370 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1371 &conf_irq, &junk); 1372 if (error) { 1373 bus_set_resource(dev, SYS_RES_IRQ, 0, 1374 ed_hpp_intr_val[irq], 1); 1375 } else { 1376 if (conf_irq != ed_hpp_intr_val[irq]) 1377 return (ENXIO); 1378 } 1379 1380 /* 1381 * Fill in softconfig info. 1382 */ 1383 1384 sc->vendor = ED_VENDOR_HP; 1385 sc->type = ED_TYPE_HP_PCLANPLUS; 1386 sc->type_str = "HP-PCLAN+"; 1387 1388 sc->mem_shared = 0; /* we DON'T have dual ported RAM */ 1389 sc->mem_start = 0; /* we use offsets inside the card RAM */ 1390 1391 sc->hpp_mem_start = NULL;/* no memory mapped I/O by default */ 1392 1393 /* 1394 * The board has 32KB of memory. Is there a way to determine 1395 * this programmatically? 1396 */ 1397 1398 memsize = 32768; 1399 1400 /* 1401 * Check if memory mapping of the I/O registers possible. 1402 */ 1403 1404 if (sc->hpp_options & ED_HPP_OPTION_MEM_ENABLE) 1405 { 1406 u_long mem_addr; 1407 1408 /* 1409 * determine the memory address from the board. 1410 */ 1411 1412 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_HW); 1413 mem_addr = (ed_asic_inw(sc, ED_HPP_HW_MEM_MAP) << 8); 1414 1415 /* 1416 * Check that the kernel specified start of memory and 1417 * hardware's idea of it match. 1418 */ 1419 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, 1420 &conf_maddr, &conf_msize); 1421 if (error) 1422 return (error); 1423 1424 if (mem_addr != conf_maddr) 1425 return ENXIO; 1426 1427 error = ed_alloc_memory(dev, 0, memsize); 1428 if (error) 1429 return (error); 1430 1431 sc->hpp_mem_start = rman_get_virtual(sc->mem_res); 1432 } 1433 1434 /* 1435 * Fill in the rest of the soft config structure. 1436 */ 1437 1438 /* 1439 * The transmit page index. 1440 */ 1441 1442 sc->tx_page_start = ED_HPP_TX_PAGE_OFFSET; 1443 1444 if (device_get_flags(dev) & ED_FLAGS_NO_MULTI_BUFFERING) 1445 sc->txb_cnt = 1; 1446 else 1447 sc->txb_cnt = 2; 1448 1449 /* 1450 * Memory description 1451 */ 1452 1453 sc->mem_size = memsize; 1454 sc->mem_ring = sc->mem_start + 1455 (sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE); 1456 sc->mem_end = sc->mem_start + sc->mem_size; 1457 1458 /* 1459 * Receive area starts after the transmit area and 1460 * continues till the end of memory. 1461 */ 1462 1463 sc->rec_page_start = sc->tx_page_start + 1464 (sc->txb_cnt * ED_TXBUF_SIZE); 1465 sc->rec_page_stop = (sc->mem_size / ED_PAGE_SIZE); 1466 1467 1468 sc->cr_proto = 0; /* value works */ 1469 1470 /* 1471 * Set the wrap registers for string I/O reads. 1472 */ 1473 1474 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_HW); 1475 ed_asic_outw(sc, ED_HPP_HW_WRAP, 1476 ((sc->rec_page_start / ED_PAGE_SIZE) | 1477 (((sc->rec_page_stop / ED_PAGE_SIZE) - 1) << 8))); 1478 1479 /* 1480 * Reset the register page to normal operation. 1481 */ 1482 1483 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_PERF); 1484 1485 /* 1486 * Verify that we can read/write from adapter memory. 1487 * Create test pattern. 1488 */ 1489 1490 for (n = 0; n < ED_HPP_TEST_SIZE; n++) 1491 { 1492 test_pattern[n] = (n*n) ^ ~n; 1493 } 1494 1495#undef ED_HPP_TEST_SIZE 1496 1497 /* 1498 * Check that the memory is accessible thru the I/O ports. 1499 * Write out the contents of "test_pattern", read back 1500 * into "test_buffer" and compare the two for any 1501 * mismatch. 1502 */ 1503 1504 for (n = 0; n < (32768 / ED_PAGE_SIZE); n ++) { 1505 1506 ed_hpp_writemem(sc, test_pattern, (n * ED_PAGE_SIZE), 1507 sizeof(test_pattern)); 1508 ed_hpp_readmem(sc, (n * ED_PAGE_SIZE), 1509 test_buffer, sizeof(test_pattern)); 1510 1511 if (bcmp(test_pattern, test_buffer, 1512 sizeof(test_pattern))) 1513 return ENXIO; 1514 } 1515 1516 return (0); 1517 1518} 1519 1520/* 1521 * HP PC Lan+ : Set the physical link to use AUI or TP/TL. 1522 */ 1523 1524static void 1525ed_hpp_set_physical_link(struct ed_softc *sc) 1526{ 1527 struct ifnet *ifp = &sc->arpcom.ac_if; 1528 int lan_page; 1529 1530 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_LAN); 1531 lan_page = ed_asic_inw(sc, ED_HPP_PAGE_0); 1532 1533 if (ifp->if_flags & IFF_ALTPHYS) { 1534 1535 /* 1536 * Use the AUI port. 1537 */ 1538 1539 lan_page |= ED_HPP_LAN_AUI; 1540 1541 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_LAN); 1542 ed_asic_outw(sc, ED_HPP_PAGE_0, lan_page); 1543 1544 1545 } else { 1546 1547 /* 1548 * Use the ThinLan interface 1549 */ 1550 1551 lan_page &= ~ED_HPP_LAN_AUI; 1552 1553 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_LAN); 1554 ed_asic_outw(sc, ED_HPP_PAGE_0, lan_page); 1555 1556 } 1557 1558 /* 1559 * Wait for the lan card to re-initialize itself 1560 */ 1561 1562 DELAY(150000); /* wait 150 ms */ 1563 1564 /* 1565 * Restore normal pages. 1566 */ 1567 1568 ed_asic_outw(sc, ED_HPP_PAGING, ED_HPP_PAGE_PERF); 1569 1570} 1571 1572/* | |
1573 * Allocate a port resource with the given resource id. 1574 */ 1575int 1576ed_alloc_port(device_t dev, int rid, int size) 1577{ 1578 struct ed_softc *sc = device_get_softc(dev); 1579 struct resource *res; 1580 1581 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, | 133 * Allocate a port resource with the given resource id. 134 */ 135int 136ed_alloc_port(device_t dev, int rid, int size) 137{ 138 struct ed_softc *sc = device_get_softc(dev); 139 struct resource *res; 140 141 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, |
1582 0ul, ~0ul, size, RF_ACTIVE); | 142 0ul, ~0ul, size, RF_ACTIVE); |
1583 if (res) { 1584 sc->port_rid = rid; 1585 sc->port_res = res; 1586 sc->port_used = size; 1587 return (0); 1588 } else { 1589 return (ENOENT); 1590 } --- 4 unchanged lines hidden (view full) --- 1595 */ 1596int 1597ed_alloc_memory(device_t dev, int rid, int size) 1598{ 1599 struct ed_softc *sc = device_get_softc(dev); 1600 struct resource *res; 1601 1602 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, | 143 if (res) { 144 sc->port_rid = rid; 145 sc->port_res = res; 146 sc->port_used = size; 147 return (0); 148 } else { 149 return (ENOENT); 150 } --- 4 unchanged lines hidden (view full) --- 155 */ 156int 157ed_alloc_memory(device_t dev, int rid, int size) 158{ 159 struct ed_softc *sc = device_get_softc(dev); 160 struct resource *res; 161 162 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, |
1603 0ul, ~0ul, size, RF_ACTIVE); | 163 0ul, ~0ul, size, RF_ACTIVE); |
1604 if (res) { 1605 sc->mem_rid = rid; 1606 sc->mem_res = res; 1607 sc->mem_used = size; 1608 return (0); 1609 } else { 1610 return (ENOENT); 1611 } 1612} 1613 1614/* 1615 * Allocate an irq resource with the given resource id. 1616 */ 1617int 1618ed_alloc_irq(device_t dev, int rid, int flags) 1619{ 1620 struct ed_softc *sc = device_get_softc(dev); 1621 struct resource *res; 1622 | 164 if (res) { 165 sc->mem_rid = rid; 166 sc->mem_res = res; 167 sc->mem_used = size; 168 return (0); 169 } else { 170 return (ENOENT); 171 } 172} 173 174/* 175 * Allocate an irq resource with the given resource id. 176 */ 177int 178ed_alloc_irq(device_t dev, int rid, int flags) 179{ 180 struct ed_softc *sc = device_get_softc(dev); 181 struct resource *res; 182 |
1623 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 1624 (RF_ACTIVE | flags)); | 183 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | flags); |
1625 if (res) { 1626 sc->irq_rid = rid; 1627 sc->irq_res = res; 1628 return (0); 1629 } else { 1630 return (ENOENT); 1631 } 1632} --- 90 unchanged lines hidden (view full) --- 1723 /* device attach does transition from UNCONFIGURED to IDLE state */ 1724 1725 if (bootverbose || 1) { 1726 if (sc->type_str && (*sc->type_str != 0)) 1727 device_printf(dev, "type %s ", sc->type_str); 1728 else 1729 device_printf(dev, "type unknown (0x%x) ", sc->type); 1730 | 184 if (res) { 185 sc->irq_rid = rid; 186 sc->irq_res = res; 187 return (0); 188 } else { 189 return (ENOENT); 190 } 191} --- 90 unchanged lines hidden (view full) --- 282 /* device attach does transition from UNCONFIGURED to IDLE state */ 283 284 if (bootverbose || 1) { 285 if (sc->type_str && (*sc->type_str != 0)) 286 device_printf(dev, "type %s ", sc->type_str); 287 else 288 device_printf(dev, "type unknown (0x%x) ", sc->type); 289 |
290#ifdef ED_HPP |
|
1731 if (sc->vendor == ED_VENDOR_HP) 1732 printf("(%s %s IO)", 1733 (sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS) ? 1734 "16-bit" : "32-bit", 1735 sc->hpp_mem_start ? "memory mapped" : "regular"); 1736 else | 291 if (sc->vendor == ED_VENDOR_HP) 292 printf("(%s %s IO)", 293 (sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS) ? 294 "16-bit" : "32-bit", 295 sc->hpp_mem_start ? "memory mapped" : "regular"); 296 else |
297#endif |
|
1737 printf("%s ", sc->isa16bit ? "(16 bit)" : "(8 bit)"); 1738 1739 printf("%s\n", (((sc->vendor == ED_VENDOR_3COM) || 1740 (sc->vendor == ED_VENDOR_HP)) && 1741 (ifp->if_flags & IFF_ALTPHYS)) ? 1742 " tranceiver disabled" : ""); 1743 } 1744 return (0); --- 922 unchanged lines hidden (view full) --- 2667 * disables the tranceiver if set. 2668 */ 2669 if (sc->vendor == ED_VENDOR_3COM) { 2670 if (ifp->if_flags & IFF_ALTPHYS) { 2671 ed_asic_outb(sc, ED_3COM_CR, 0); 2672 } else { 2673 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); 2674 } | 298 printf("%s ", sc->isa16bit ? "(16 bit)" : "(8 bit)"); 299 300 printf("%s\n", (((sc->vendor == ED_VENDOR_3COM) || 301 (sc->vendor == ED_VENDOR_HP)) && 302 (ifp->if_flags & IFF_ALTPHYS)) ? 303 " tranceiver disabled" : ""); 304 } 305 return (0); --- 922 unchanged lines hidden (view full) --- 1228 * disables the tranceiver if set. 1229 */ 1230 if (sc->vendor == ED_VENDOR_3COM) { 1231 if (ifp->if_flags & IFF_ALTPHYS) { 1232 ed_asic_outb(sc, ED_3COM_CR, 0); 1233 } else { 1234 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); 1235 } |
2675 } else if (sc->vendor == ED_VENDOR_HP) | 1236 } 1237#ifdef ED_HPP 1238 else if (sc->vendor == ED_VENDOR_HP) |
2676 ed_hpp_set_physical_link(sc); | 1239 ed_hpp_set_physical_link(sc); |
1240#endif |
|
2677 break; 2678 2679 case SIOCADDMULTI: 2680 case SIOCDELMULTI: 2681 /* 2682 * Multicast list has changed; set the hardware filter 2683 * accordingly. 2684 */ --- 113 unchanged lines hidden (view full) --- 2798 * address, copy 'amount' from NIC to host using Programmed I/O. 2799 * The 'amount' is rounded up to a word - okay as long as mbufs 2800 * are word sized. 2801 * This routine is currently Novell-specific. 2802 */ 2803void 2804ed_pio_readmem(struct ed_softc *sc, long src, uint8_t *dst, uint16_t amount) 2805{ | 1241 break; 1242 1243 case SIOCADDMULTI: 1244 case SIOCDELMULTI: 1245 /* 1246 * Multicast list has changed; set the hardware filter 1247 * accordingly. 1248 */ --- 113 unchanged lines hidden (view full) --- 1362 * address, copy 'amount' from NIC to host using Programmed I/O. 1363 * The 'amount' is rounded up to a word - okay as long as mbufs 1364 * are word sized. 1365 * This routine is currently Novell-specific. 1366 */ 1367void 1368ed_pio_readmem(struct ed_softc *sc, long src, uint8_t *dst, uint16_t amount) 1369{ |
1370#ifdef ED_HPP |
|
2806 /* HP PC Lan+ cards need special handling */ 2807 if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS) { 2808 ed_hpp_readmem(sc, src, dst, amount); 2809 return; 2810 } | 1371 /* HP PC Lan+ cards need special handling */ 1372 if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS) { 1373 ed_hpp_readmem(sc, src, dst, amount); 1374 return; 1375 } |
1376#endif |
|
2811 2812 /* Regular Novell cards */ 2813 /* select page 0 registers */ 2814 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STA); 2815 2816 /* round up to a word */ 2817 if (amount & 1) 2818 ++amount; --- 65 unchanged lines hidden (view full) --- 2884static u_short 2885ed_pio_write_mbufs(struct ed_softc *sc, struct mbuf *m, long dst) 2886{ 2887 struct ifnet *ifp = (struct ifnet *)sc; 2888 unsigned short total_len, dma_len; 2889 struct mbuf *mp; 2890 int maxwait = 200; /* about 240us */ 2891 | 1377 1378 /* Regular Novell cards */ 1379 /* select page 0 registers */ 1380 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STA); 1381 1382 /* round up to a word */ 1383 if (amount & 1) 1384 ++amount; --- 65 unchanged lines hidden (view full) --- 1450static u_short 1451ed_pio_write_mbufs(struct ed_softc *sc, struct mbuf *m, long dst) 1452{ 1453 struct ifnet *ifp = (struct ifnet *)sc; 1454 unsigned short total_len, dma_len; 1455 struct mbuf *mp; 1456 int maxwait = 200; /* about 240us */ 1457 |
1458#ifdef ED_HPP |
|
2892 /* HP PC Lan+ cards need special handling */ | 1459 /* HP PC Lan+ cards need special handling */ |
2893 if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS) { | 1460 if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS) |
2894 return ed_hpp_write_mbufs(sc, m, dst); | 1461 return ed_hpp_write_mbufs(sc, m, dst); |
2895 } | 1462#endif |
2896 2897 /* Regular Novell cards */ 2898 /* First, count up the total number of bytes to copy */ 2899 for (total_len = 0, mp = m; mp; mp = mp->m_next) 2900 total_len += mp->m_len; 2901 2902 dma_len = total_len; 2903 if (sc->isa16bit && (dma_len & 1)) --- 86 unchanged lines hidden (view full) --- 2990 log(LOG_WARNING, "%s: remote transmit DMA failed to complete\n", 2991 ifp->if_xname); 2992 ed_reset(ifp); 2993 return(0); 2994 } 2995 return (total_len); 2996} 2997 | 1463 1464 /* Regular Novell cards */ 1465 /* First, count up the total number of bytes to copy */ 1466 for (total_len = 0, mp = m; mp; mp = mp->m_next) 1467 total_len += mp->m_len; 1468 1469 dma_len = total_len; 1470 if (sc->isa16bit && (dma_len & 1)) --- 86 unchanged lines hidden (view full) --- 1557 log(LOG_WARNING, "%s: remote transmit DMA failed to complete\n", 1558 ifp->if_xname); 1559 ed_reset(ifp); 1560 return(0); 1561 } 1562 return (total_len); 1563} 1564 |
2998/* 2999 * Support routines to handle the HP PC Lan+ card. 3000 */ 3001 3002/* 3003 * HP PC Lan+: Read from NIC memory, using either PIO or memory mapped 3004 * IO. 3005 */ 3006 3007static void 3008ed_hpp_readmem(struct ed_softc *sc, long src, uint8_t *dst, uint16_t amount) 3009{ 3010 3011 int use_32bit_access = !(sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS); 3012 3013 3014 /* Program the source address in RAM */ 3015 ed_asic_outw(sc, ED_HPP_PAGE_2, src); 3016 3017 /* 3018 * The HP PC Lan+ card supports word reads as well as 3019 * a memory mapped i/o port that is aliased to every 3020 * even address on the board. 3021 */ 3022 3023 if (sc->hpp_mem_start) { 3024 3025 /* Enable memory mapped access. */ 3026 ed_asic_outw(sc, ED_HPP_OPTION, sc->hpp_options & 3027 ~(ED_HPP_OPTION_MEM_DISABLE | 3028 ED_HPP_OPTION_BOOT_ROM_ENB)); 3029 3030 if (use_32bit_access && (amount > 3)) { 3031 uint32_t *dl = (uint32_t *) dst; 3032 volatile uint32_t *const sl = 3033 (uint32_t *) sc->hpp_mem_start; 3034 uint32_t *const fence = dl + (amount >> 2); 3035 3036 /* Copy out NIC data. We could probably write this 3037 as a `movsl'. The currently generated code is lousy. 3038 */ 3039 3040 while (dl < fence) 3041 *dl++ = *sl; 3042 3043 dst += (amount & ~3); 3044 amount &= 3; 3045 3046 } 3047 3048 /* Finish off any words left, as a series of short reads */ 3049 if (amount > 1) { 3050 u_short *d = (u_short *) dst; 3051 volatile u_short *const s = 3052 (u_short *) sc->hpp_mem_start; 3053 u_short *const fence = d + (amount >> 1); 3054 3055 /* Copy out NIC data. */ 3056 3057 while (d < fence) 3058 *d++ = *s; 3059 3060 dst += (amount & ~1); 3061 amount &= 1; 3062 } 3063 3064 /* 3065 * read in a byte; however we need to always read 16 bits 3066 * at a time or the hardware gets into a funny state 3067 */ 3068 3069 if (amount == 1) { 3070 /* need to read in a short and copy LSB */ 3071 volatile u_short *const s = 3072 (volatile u_short *) sc->hpp_mem_start; 3073 3074 *dst = (*s) & 0xFF; 3075 } 3076 3077 /* Restore Boot ROM access. */ 3078 3079 ed_asic_outw(sc, ED_HPP_OPTION, sc->hpp_options); 3080 3081 3082 } else { 3083 /* Read in data using the I/O port */ 3084 if (use_32bit_access && (amount > 3)) { 3085 ed_asic_insl(sc, ED_HPP_PAGE_4, dst, amount >> 2); 3086 dst += (amount & ~3); 3087 amount &= 3; 3088 } 3089 if (amount > 1) { 3090 ed_asic_insw(sc, ED_HPP_PAGE_4, dst, amount >> 1); 3091 dst += (amount & ~1); 3092 amount &= 1; 3093 } 3094 if (amount == 1) { /* read in a short and keep the LSB */ 3095 *dst = ed_asic_inw(sc, ED_HPP_PAGE_4) & 0xFF; 3096 } 3097 } 3098} 3099 3100/* 3101 * HP PC Lan+: Write to NIC memory, using either PIO or memory mapped 3102 * IO. 3103 * Only used in the probe routine to test the memory. 'len' must 3104 * be even. 3105 */ 3106static void 3107ed_hpp_writemem(struct ed_softc *sc, uint8_t *src, uint16_t dst, uint16_t len) 3108{ 3109 /* reset remote DMA complete flag */ 3110 ed_nic_outb(sc, ED_P0_ISR, ED_ISR_RDC); 3111 3112 /* program the write address in RAM */ 3113 ed_asic_outw(sc, ED_HPP_PAGE_0, dst); 3114 3115 if (sc->hpp_mem_start) { 3116 u_short *s = (u_short *) src; 3117 volatile u_short *d = (u_short *) sc->hpp_mem_start; 3118 u_short *const fence = s + (len >> 1); 3119 3120 /* 3121 * Enable memory mapped access. 3122 */ 3123 3124 ed_asic_outw(sc, ED_HPP_OPTION, sc->hpp_options & 3125 ~(ED_HPP_OPTION_MEM_DISABLE | 3126 ED_HPP_OPTION_BOOT_ROM_ENB)); 3127 3128 /* 3129 * Copy to NIC memory. 3130 */ 3131 3132 while (s < fence) 3133 *d = *s++; 3134 3135 /* 3136 * Restore Boot ROM access. 3137 */ 3138 3139 ed_asic_outw(sc, ED_HPP_OPTION, sc->hpp_options); 3140 3141 } else { 3142 /* write data using I/O writes */ 3143 ed_asic_outsw(sc, ED_HPP_PAGE_4, src, len / 2); 3144 } 3145} 3146 3147/* 3148 * Write to HP PC Lan+ NIC memory. Access to the NIC can be by using 3149 * outsw() or via the memory mapped interface to the same register. 3150 * Writes have to be in word units; byte accesses won't work and may cause 3151 * the NIC to behave weirdly. Long word accesses are permitted if the ASIC 3152 * allows it. 3153 */ 3154 3155static u_short 3156ed_hpp_write_mbufs(struct ed_softc *sc, struct mbuf *m, int dst) 3157{ 3158 int len, wantbyte; 3159 unsigned short total_len; 3160 unsigned char savebyte[2]; 3161 volatile u_short * const d = 3162 (volatile u_short *) sc->hpp_mem_start; 3163 int use_32bit_accesses = !(sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS); 3164 3165 /* select page 0 registers */ 3166 ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_STA); 3167 3168 /* reset remote DMA complete flag */ 3169 ed_nic_outb(sc, ED_P0_ISR, ED_ISR_RDC); 3170 3171 /* program the write address in RAM */ 3172 ed_asic_outw(sc, ED_HPP_PAGE_0, dst); 3173 3174 if (sc->hpp_mem_start) /* enable memory mapped I/O */ 3175 ed_asic_outw(sc, ED_HPP_OPTION, sc->hpp_options & 3176 ~(ED_HPP_OPTION_MEM_DISABLE | 3177 ED_HPP_OPTION_BOOT_ROM_ENB)); 3178 3179 wantbyte = 0; 3180 total_len = 0; 3181 3182 if (sc->hpp_mem_start) { /* Memory mapped I/O port */ 3183 while (m) { 3184 total_len += (len = m->m_len); 3185 if (len) { 3186 caddr_t data = mtod(m, caddr_t); 3187 /* finish the last word of the previous mbuf */ 3188 if (wantbyte) { 3189 savebyte[1] = *data; 3190 *d = *((u_short *) savebyte); 3191 data++; len--; wantbyte = 0; 3192 } 3193 /* output contiguous words */ 3194 if ((len > 3) && (use_32bit_accesses)) { 3195 volatile uint32_t *const dl = 3196 (volatile uint32_t *) d; 3197 uint32_t *sl = (uint32_t *) data; 3198 uint32_t *fence = sl + (len >> 2); 3199 3200 while (sl < fence) 3201 *dl = *sl++; 3202 3203 data += (len & ~3); 3204 len &= 3; 3205 } 3206 /* finish off remain 16 bit writes */ 3207 if (len > 1) { 3208 u_short *s = (u_short *) data; 3209 u_short *fence = s + (len >> 1); 3210 3211 while (s < fence) 3212 *d = *s++; 3213 3214 data += (len & ~1); 3215 len &= 1; 3216 } 3217 /* save last byte if needed */ 3218 if ((wantbyte = (len == 1)) != 0) 3219 savebyte[0] = *data; 3220 } 3221 m = m->m_next; /* to next mbuf */ 3222 } 3223 if (wantbyte) /* write last byte */ 3224 *d = *((u_short *) savebyte); 3225 } else { 3226 /* use programmed I/O */ 3227 while (m) { 3228 total_len += (len = m->m_len); 3229 if (len) { 3230 caddr_t data = mtod(m, caddr_t); 3231 /* finish the last word of the previous mbuf */ 3232 if (wantbyte) { 3233 savebyte[1] = *data; 3234 ed_asic_outw(sc, ED_HPP_PAGE_4, 3235 *((u_short *)savebyte)); 3236 data++; 3237 len--; 3238 wantbyte = 0; 3239 } 3240 /* output contiguous words */ 3241 if ((len > 3) && use_32bit_accesses) { 3242 ed_asic_outsl(sc, ED_HPP_PAGE_4, 3243 data, len >> 2); 3244 data += (len & ~3); 3245 len &= 3; 3246 } 3247 /* finish off remaining 16 bit accesses */ 3248 if (len > 1) { 3249 ed_asic_outsw(sc, ED_HPP_PAGE_4, 3250 data, len >> 1); 3251 data += (len & ~1); 3252 len &= 1; 3253 } 3254 if ((wantbyte = (len == 1)) != 0) 3255 savebyte[0] = *data; 3256 3257 } /* if len != 0 */ 3258 m = m->m_next; 3259 } 3260 if (wantbyte) /* spit last byte */ 3261 ed_asic_outw(sc, ED_HPP_PAGE_4, *(u_short *)savebyte); 3262 3263 } 3264 3265 if (sc->hpp_mem_start) /* turn off memory mapped i/o */ 3266 ed_asic_outw(sc, ED_HPP_OPTION, sc->hpp_options); 3267 3268 return (total_len); 3269} 3270 | |
3271#ifndef ED_NO_MIIBUS 3272/* 3273 * MII bus support routines. 3274 */ 3275int 3276ed_miibus_readreg(device_t dev, int phy, int reg) 3277{ 3278 struct ed_softc *sc; --- 181 unchanged lines hidden (view full) --- 3460 continue; 3461 index = ether_crc32_be(LLADDR((struct sockaddr_dl *) 3462 ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 3463 af[index >> 3] |= 1 << (index & 7); 3464 } 3465} 3466 3467int | 1565#ifndef ED_NO_MIIBUS 1566/* 1567 * MII bus support routines. 1568 */ 1569int 1570ed_miibus_readreg(device_t dev, int phy, int reg) 1571{ 1572 struct ed_softc *sc; --- 181 unchanged lines hidden (view full) --- 1754 continue; 1755 index = ether_crc32_be(LLADDR((struct sockaddr_dl *) 1756 ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 1757 af[index >> 3] |= 1 << (index & 7); 1758 } 1759} 1760 1761int |
1762ed_isa_mem_ok(device_t dev, u_long pmem, u_int memsize) 1763{ 1764 if (pmem < 0xa0000 || pmem + memsize > 0x1000000) { 1765 device_printf(dev, "Invalid ISA memory address range " 1766 "configured: 0x%lx - 0x%lx\n", pmem, pmem + memsize); 1767 return (ENXIO); 1768 } 1769 return (0); 1770} 1771 1772int |
|
3468ed_clear_memory(device_t dev) 3469{ 3470 struct ed_softc *sc = device_get_softc(dev); 3471 int i; 3472 3473 /* 3474 * Now zero memory and verify that it is clear 3475 */ --- 12 unchanged lines hidden --- | 1773ed_clear_memory(device_t dev) 1774{ 1775 struct ed_softc *sc = device_get_softc(dev); 1776 int i; 1777 1778 /* 1779 * Now zero memory and verify that it is clear 1780 */ --- 12 unchanged lines hidden --- |