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