|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 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 ! 9: * notice, this list of conditions and the following disclaimer. ! 10: * 2. Redistributions in binary form must reproduce the above copyright ! 11: * notice, this list of conditions and the following disclaimer in the ! 12: * documentation and/or other materials provided with the distribution. ! 13: * 3. All advertising materials mentioning features or use of this software ! 14: * must display the following acknowledgement: ! 15: * This product includes software developed by the University of ! 16: * California, Berkeley and its contributors. ! 17: * 4. Neither the name of the University nor the names of its contributors ! 18: * may be used to endorse or promote products derived from this software ! 19: * without specific prior written permission. ! 20: * ! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 31: * SUCH DAMAGE. ! 32: * ! 33: * @(#)if_vba.c 1.4 (Berkeley) 12/16/90 ! 34: */ ! 35: ! 36: #include "sys/param.h" ! 37: #include "sys/systm.h" ! 38: #include "sys/mbuf.h" ! 39: #include "sys/buf.h" ! 40: #include "sys/cmap.h" ! 41: #include "sys/vmmac.h" ! 42: #include "sys/socket.h" ! 43: ! 44: #include "../include/mtpr.h" ! 45: #include "../include/pte.h" ! 46: ! 47: #include "../vba/vbavar.h" ! 48: ! 49: #include "net/if.h" ! 50: #include "netinet/in.h" ! 51: #include "netinet/if_ether.h" ! 52: ! 53: #include "if_vba.h" ! 54: ! 55: if_vbareserve(ifvba0, n, bufsize, extra, extrasize) ! 56: struct ifvba *ifvba0; ! 57: register int n; ! 58: int bufsize; ! 59: caddr_t *extra; ! 60: int extrasize; ! 61: { ! 62: register caddr_t cp; ! 63: register struct pte *pte; ! 64: register struct ifvba *ifvba = ifvba0; ! 65: struct ifvba *vlim = ifvba + n; ! 66: ! 67: n = roundup(extrasize + (n * bufsize), NBPG); ! 68: cp = (caddr_t)malloc((u_long)n, M_DEVBUF, M_NOWAIT); ! 69: if ((n + kvtophys(cp)) > VB_MAXADDR24) { ! 70: free(cp, M_DEVBUF); ! 71: cp = 0; ! 72: } ! 73: if (cp == 0) { ! 74: printf("No memory for device buffer(s)\n"); ! 75: return (0); ! 76: } ! 77: /* ! 78: * Make raw buffer pages uncacheable. ! 79: */ ! 80: pte = kvtopte(cp); ! 81: for (n = btoc(n); n--; pte++) ! 82: pte->pg_nc = 1; ! 83: mtpr(TBIA, 0); ! 84: if (extra) { ! 85: *extra = cp; ! 86: cp += extrasize; ! 87: } ! 88: for (; ifvba < vlim; ifvba++) { ! 89: ifvba->iff_buffer = cp; ! 90: ifvba->iff_physaddr = kvtophys(cp); ! 91: cp += bufsize; ! 92: } ! 93: return (1); ! 94: } ! 95: /* ! 96: * Routine to copy from VERSAbus memory into mbufs. ! 97: * ! 98: * Warning: This makes the fairly safe assumption that ! 99: * mbufs have even lengths. ! 100: */ ! 101: struct mbuf * ! 102: if_vbaget(rxbuf, totlen, off, ifp, flags) ! 103: caddr_t rxbuf; ! 104: int totlen, off, flags; ! 105: struct ifnet *ifp; ! 106: { ! 107: register caddr_t cp; ! 108: register struct mbuf *m; ! 109: struct mbuf *top = 0, **mp = ⊤ ! 110: int len; ! 111: caddr_t packet_end; ! 112: ! 113: rxbuf += sizeof (struct ether_header); ! 114: cp = rxbuf; ! 115: packet_end = cp + totlen; ! 116: if (off) { ! 117: off += 2 * sizeof(u_short); ! 118: totlen -= 2 *sizeof(u_short); ! 119: cp = rxbuf + off; ! 120: } ! 121: ! 122: MGETHDR(m, M_DONTWAIT, MT_DATA); ! 123: if (m == 0) ! 124: return (0); ! 125: m->m_pkthdr.rcvif = ifp; ! 126: m->m_pkthdr.len = totlen; ! 127: m->m_len = MHLEN; ! 128: ! 129: while (totlen > 0) { ! 130: if (top) { ! 131: MGET(m, M_DONTWAIT, MT_DATA); ! 132: if (m == 0) { ! 133: m_freem(top); ! 134: return (0); ! 135: } ! 136: m->m_len = MLEN; ! 137: } ! 138: len = min(totlen, (packet_end - cp)); ! 139: if (len >= MINCLSIZE) { ! 140: MCLGET(m, M_DONTWAIT); ! 141: if (m->m_flags & M_EXT) ! 142: m->m_len = len = min(len, MCLBYTES); ! 143: else ! 144: len = m->m_len; ! 145: } else { ! 146: /* ! 147: * Place initial small packet/header at end of mbuf. ! 148: */ ! 149: if (len < m->m_len) { ! 150: if (top == 0 && len + max_linkhdr <= m->m_len) ! 151: m->m_data += max_linkhdr; ! 152: m->m_len = len; ! 153: } else ! 154: len = m->m_len; ! 155: } ! 156: if (flags) ! 157: if_vba16copy(cp, mtod(m, caddr_t), (u_int)len); ! 158: else ! 159: bcopy(cp, mtod(m, caddr_t), (u_int)len); ! 160: ! 161: *mp = m; ! 162: mp = &m->m_next; ! 163: totlen -= len; ! 164: cp += len; ! 165: if (cp == packet_end) ! 166: cp = rxbuf; ! 167: } ! 168: return (top); ! 169: } ! 170: ! 171: if_vbaput(ifu, m0, flags) ! 172: caddr_t ifu; ! 173: struct mbuf *m0; ! 174: { ! 175: register struct mbuf *m = m0; ! 176: register caddr_t cp = ifu; ! 177: ! 178: while (m) { ! 179: if (flags) ! 180: if_vba16copy(mtod(m, caddr_t), cp, (u_int)m->m_len); ! 181: else ! 182: bcopy(mtod(m, caddr_t), cp, (u_int)m->m_len); ! 183: cp += m->m_len; ! 184: MFREE(m, m0); ! 185: m = m0; ! 186: } ! 187: if ((int)cp & 1) ! 188: *cp++ = 0; ! 189: return (cp - ifu); ! 190: } ! 191: ! 192: if_vba16copy(from, to, cnt) ! 193: register caddr_t from, to; ! 194: register unsigned cnt; ! 195: { ! 196: register c; ! 197: register short *f, *t; ! 198: ! 199: if (((int)from&01) && ((int)to&01)) { ! 200: /* source & dest at odd addresses */ ! 201: *to++ = *from++; ! 202: --cnt; ! 203: } ! 204: if (cnt > 1 && (((int)to&01) == 0) && (((int)from&01) == 0)) { ! 205: t = (short *)to; ! 206: f = (short *)from; ! 207: for (c = cnt>>1; c; --c) /* even address copy */ ! 208: *t++ = *f++; ! 209: cnt &= 1; ! 210: if (cnt) { /* odd len */ ! 211: from = (caddr_t)f; ! 212: to = (caddr_t)t; ! 213: *to = *from; ! 214: } ! 215: } ! 216: while ((int)cnt-- > 0) /* one of the address(es) must be odd */ ! 217: *to++ = *from++; ! 218: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.