Annotation of sys/arch/mac68k/dev/if_ae.c, Revision 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