1 /* $NetBSD: if_le_ibus.c,v 1.12 2008/01/04 21:53:51 ad Exp $ */
4 * Copyright 1996 The Board of Trustees of The Leland Stanford
5 * Junior University. All Rights Reserved.
7 * Permission to use, copy, modify, and distribute this
8 * software and its documentation for any purpose and without
9 * fee is hereby granted, provided that the above copyright
10 * notice appear in all copies. Stanford University
11 * makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without
13 * express or implied warranty.
15 * This driver was contributed by Jonathan Stone.
19 * LANCE on Decstation kn01/kn220(?) baseboard.
22 #include <sys/cdefs.h>
23 __KERNEL_RCSID(0, "$NetBSD: if_le_ibus.c,v 1.12 2008/01/04 21:53:51 ad Exp $");
27 #include <sys/param.h>
28 #include <sys/socket.h>
29 #include <sys/systm.h>
30 #include <sys/device.h>
33 #include <net/if_ether.h>
34 #include <net/if_media.h>
37 #include <netinet/in.h>
38 #include <netinet/if_inarp.h>
41 #include <dev/ic/lancevar.h>
42 #include <dev/ic/am7990var.h>
44 #include <dev/tc/if_levar.h>
45 #include <pmax/ibus/ibusvar.h>
46 #include <pmax/pmax/kn01.h>
48 static void le_dec_copyfrombuf_gap2(struct lance_softc
*, void *, int, int);
49 static void le_dec_copytobuf_gap2(struct lance_softc
*, void *, int, int);
50 static void le_dec_zerobuf_gap2(struct lance_softc
*, int, int);
53 static int le_pmax_match(device_t
, cfdata_t
, void *);
54 static void le_pmax_attach(device_t
, device_t
, void *);
56 CFATTACH_DECL_NEW(le_pmax
, sizeof(struct le_softc
),
57 le_pmax_match
, le_pmax_attach
, NULL
, NULL
);
60 le_pmax_match(device_t parent
, cfdata_t cf
, void *aux
)
62 struct ibus_attach_args
*d
= aux
;
64 if (strcmp("lance", d
->ia_name
) != 0)
70 le_pmax_attach(device_t parent
, device_t self
, void *aux
)
72 struct le_softc
*lesc
= device_private(self
);
73 struct lance_softc
*sc
= &lesc
->sc_am7990
.lsc
;
75 struct ibus_attach_args
*ia
= aux
;
78 * It's on the baseboard, with a dedicated interrupt line.
81 lesc
->sc_r1
= (struct lereg1
*)(ia
->ia_addr
);
82 sc
->sc_mem
= (void *)MIPS_PHYS_TO_KSEG1(KN01_SYS_LANCE_B_START
);
83 cp
= (uint8_t *)(MIPS_PHYS_TO_KSEG1(KN01_SYS_CLOCK
) + 1);
85 sc
->sc_copytodesc
= le_dec_copytobuf_gap2
;
86 sc
->sc_copyfromdesc
= le_dec_copyfrombuf_gap2
;
87 sc
->sc_copytobuf
= le_dec_copytobuf_gap2
;
88 sc
->sc_copyfrombuf
= le_dec_copyfrombuf_gap2
;
89 sc
->sc_zerobuf
= le_dec_zerobuf_gap2
;
91 dec_le_common_attach(&lesc
->sc_am7990
, cp
);
93 ibus_intr_establish(parent
, (void *)ia
->ia_cookie
, IPL_NET
,
98 * gap2: two bytes of data followed by two bytes of pad.
100 * Buffers must be 4-byte aligned. The code doesn't worry about
101 * doing an extra byte.
105 le_dec_copytobuf_gap2(struct lance_softc
*sc
, void *fromv
, int boff
, int len
)
107 volatile uint8_t *buf
= sc
->sc_mem
;
108 uint8_t *from
= fromv
;
109 volatile uint16_t *bptr
;
112 /* handle unaligned first byte */
113 bptr
= ((volatile uint16_t *)buf
) + (boff
- 1);
114 *bptr
= (*from
++ << 8) | (*bptr
& 0xff);
118 bptr
= ((volatile uint16_t *)buf
) + boff
;
120 *bptr
= (from
[1] << 8) | (from
[0] & 0xff);
126 *bptr
= (uint16_t)*from
;
130 le_dec_copyfrombuf_gap2(struct lance_softc
*sc
, void *tov
, int boff
, int len
)
132 volatile void *buf
= sc
->sc_mem
;
134 volatile uint16_t *bptr
;
138 /* handle unaligned first byte */
139 bptr
= ((volatile uint16_t *)buf
) + (boff
- 1);
140 *to
++ = (*bptr
>> 8) & 0xff;
144 bptr
= ((volatile uint16_t *)buf
) + boff
;
148 *to
++ = (tmp
>> 8) & 0xff;
157 le_dec_zerobuf_gap2(struct lance_softc
*sc
, int boff
, int len
)
159 volatile void *buf
= sc
->sc_mem
;
160 volatile uint16_t *bptr
;
162 if ((unsigned int)boff
& 0x1) {
163 bptr
= ((volatile uint16_t *)buf
) + (boff
- 1);
168 bptr
= ((volatile uint16_t *)buf
) + boff
;