Deleted Added
full compact
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 ---