Annotation of sys/arch/mac68k/dev/if_ae.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_ae.c,v 1.34 2007/01/22 13:17:45 martin Exp $ */
2: /* $NetBSD: if_ae.c,v 1.78 2006/09/09 06:25:08 tsutsui Exp $ */
3:
4: /*
5: * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
6: * adapters.
7: *
8: * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
9: *
10: * Copyright (C) 1993, David Greenman. This software may be used, modified,
11: * copied, distributed, and sold, in both source and binary form provided that
12: * the above copyright and these terms are retained. Under no circumstances is
13: * the author responsible for the proper functioning of this software, nor does
14: * the author assume any responsibility for damages incurred with its use.
15: */
16:
17: #include "bpfilter.h"
18:
19: #include <sys/param.h>
20: #include <sys/systm.h>
21: #include <sys/device.h>
22: #include <sys/mbuf.h>
23: #include <sys/socket.h>
24:
25: #include <net/if.h>
26: #include <net/if_dl.h>
27: #include <net/if_types.h>
28:
29: #include <netinet/in.h>
30: #include <netinet/in_systm.h>
31: #include <netinet/in_var.h>
32: #include <netinet/ip.h>
33: #include <netinet/if_ether.h>
34:
35: #include <net/if_media.h>
36:
37: #if NBPFILTER > 0
38: #include <net/bpf.h>
39: #endif
40:
41: #include <machine/bus.h>
42:
43: #include <dev/ic/dp8390reg.h>
44: #include <dev/ic/dp8390var.h>
45: #include <mac68k/dev/if_aevar.h>
46:
47: struct cfdriver ae_cd = {
48: NULL, "ae", DV_IFNET
49: };
50:
51: #define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
52:
53: int
54: ae_size_card_memory(bus_space_tag_t bst, bus_space_handle_t bsh, int ofs)
55: {
56: int i1, i2, i3, i4, i8;
57:
58: /*
59: * banks; also assume it will generally mirror in upper banks
60: * if not installed.
61: */
62: i1 = (8192 * 0);
63: i2 = (8192 * 1);
64: i3 = (8192 * 2);
65: i4 = (8192 * 3);
66: i8 = (8192 * 4);
67:
68: bus_space_write_2(bst, bsh, ofs + i8, 0x8888);
69: bus_space_write_2(bst, bsh, ofs + i4, 0x4444);
70: bus_space_write_2(bst, bsh, ofs + i3, 0x3333);
71: bus_space_write_2(bst, bsh, ofs + i2, 0x2222);
72: bus_space_write_2(bst, bsh, ofs + i1, 0x1111);
73:
74: /*
75: * 1) If the memory range is decoded completely, it does not
76: * matter what we write first: High tags written into
77: * the void are lost.
78: * 2) If the memory range is not decoded completely (banks are
79: * mirrored), high tags are overwritten by lower ones.
80: * 3) Lazy implementation of pathological cases - none found yet.
81: */
82:
83: if (bus_space_read_2(bst, bsh, ofs + i1) == 0x1111 &&
84: bus_space_read_2(bst, bsh, ofs + i2) == 0x2222 &&
85: bus_space_read_2(bst, bsh, ofs + i3) == 0x3333 &&
86: bus_space_read_2(bst, bsh, ofs + i4) == 0x4444 &&
87: bus_space_read_2(bst, bsh, ofs + i8) == 0x8888)
88: return 8192 * 8;
89:
90: if (bus_space_read_2(bst, bsh, ofs + i1) == 0x1111 &&
91: bus_space_read_2(bst, bsh, ofs + i2) == 0x2222 &&
92: bus_space_read_2(bst, bsh, ofs + i3) == 0x3333 &&
93: bus_space_read_2(bst, bsh, ofs + i4) == 0x4444)
94: return 8192 * 4;
95:
96: if ((bus_space_read_2(bst, bsh, ofs + i1) == 0x1111 &&
97: bus_space_read_2(bst, bsh, ofs + i2) == 0x2222) ||
98: (bus_space_read_2(bst, bsh, ofs + i1) == 0x3333 &&
99: bus_space_read_2(bst, bsh, ofs + i2) == 0x4444))
100: return 8192 * 2;
101:
102: if (bus_space_read_2(bst, bsh, ofs + i1) == 0x1111 ||
103: bus_space_read_2(bst, bsh, ofs + i1) == 0x4444)
104: return 8192;
105:
106: return 0;
107: }
108:
109: /*
110: * Zero memory and verify that it is clear. The only difference between
111: * this and the default test_mem function is that the DP8390-based NuBus
112: * cards * apparently require word-wide writes and byte-wide reads, an
113: * `interesting' combination.
114: */
115: int
116: ae_test_mem(struct dp8390_softc *sc)
117: {
118: bus_space_tag_t buft = sc->sc_buft;
119: bus_space_handle_t bufh = sc->sc_bufh;
120: int i;
121:
122: bus_space_set_region_2(buft, bufh, sc->mem_start, 0,
123: sc->mem_size / 2);
124:
125: for (i = 0; i < sc->mem_size; ++i) {
126: if (bus_space_read_1(sc->sc_buft, sc->sc_bufh, i)) {
127: printf(": failed to clear NIC buffer at offset %x - "
128: "check configuration\n", (sc->mem_start + i));
129: return 1;
130: }
131: }
132:
133: return 0;
134: }
135:
136: /*
137: * Copy packet from mbuf to the board memory Currently uses an extra
138: * buffer/extra memory copy, unless the whole packet fits in one mbuf.
139: *
140: * As in the test_mem function, we use word-wide writes.
141: */
142: int
143: ae_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
144: {
145: u_char *data, savebyte[2];
146: int len, wantbyte;
147: u_short totlen = 0;
148:
149: wantbyte = 0;
150:
151: for (; m ; m = m->m_next) {
152: data = mtod(m, u_char *);
153: len = m->m_len;
154: totlen += len;
155: if (len > 0) {
156: /* Finish the last word. */
157: if (wantbyte) {
158: savebyte[1] = *data;
159: bus_space_write_region_2(sc->sc_buft,
160: sc->sc_bufh, buf, (u_int16_t *)savebyte, 1);
161: buf += 2;
162: data++;
163: len--;
164: wantbyte = 0;
165: }
166: /* Output contiguous words. */
167: if (len > 1) {
168: bus_space_write_region_2(
169: sc->sc_buft, sc->sc_bufh,
170: buf, (u_int16_t *)data, len >> 1);
171: buf += len & ~1;
172: data += len & ~1;
173: len &= 1;
174: }
175: /* Save last byte, if necessary. */
176: if (len == 1) {
177: savebyte[0] = *data;
178: wantbyte = 1;
179: }
180: }
181: }
182:
183: len = ETHER_PAD_LEN - totlen;
184: if (wantbyte) {
185: savebyte[1] = 0;
186: bus_space_write_region_2(sc->sc_buft, sc->sc_bufh,
187: buf, (u_int16_t *)savebyte, 1);
188: buf += 2;
189: if (len > 0)
190: totlen++;
191: len--;
192: }
193: /* if sent data is shorter than EHTER_PAD_LEN, put 0 to padding */
194: if (len > 0) {
195: bus_space_set_region_2(sc->sc_buft, sc->sc_bufh, buf, 0,
196: len >> 1);
197: totlen = ETHER_PAD_LEN;
198: }
199: return (totlen);
200: }
CVSweb