|
|
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.