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