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