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