home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)if_vba.c 1.4 (Berkeley) 12/16/90
- */
-
- #include "sys/param.h"
- #include "sys/systm.h"
- #include "sys/mbuf.h"
- #include "sys/buf.h"
- #include "sys/cmap.h"
- #include "sys/vmmac.h"
- #include "sys/socket.h"
-
- #include "../include/mtpr.h"
- #include "../include/pte.h"
-
- #include "../vba/vbavar.h"
-
- #include "net/if.h"
- #include "netinet/in.h"
- #include "netinet/if_ether.h"
-
- #include "if_vba.h"
-
- if_vbareserve(ifvba0, n, bufsize, extra, extrasize)
- struct ifvba *ifvba0;
- register int n;
- int bufsize;
- caddr_t *extra;
- int extrasize;
- {
- register caddr_t cp;
- register struct pte *pte;
- register struct ifvba *ifvba = ifvba0;
- struct ifvba *vlim = ifvba + n;
-
- n = roundup(extrasize + (n * bufsize), NBPG);
- cp = (caddr_t)malloc((u_long)n, M_DEVBUF, M_NOWAIT);
- if ((n + kvtophys(cp)) > VB_MAXADDR24) {
- free(cp, M_DEVBUF);
- cp = 0;
- }
- if (cp == 0) {
- printf("No memory for device buffer(s)\n");
- return (0);
- }
- /*
- * Make raw buffer pages uncacheable.
- */
- pte = kvtopte(cp);
- for (n = btoc(n); n--; pte++)
- pte->pg_nc = 1;
- mtpr(TBIA, 0);
- if (extra) {
- *extra = cp;
- cp += extrasize;
- }
- for (; ifvba < vlim; ifvba++) {
- ifvba->iff_buffer = cp;
- ifvba->iff_physaddr = kvtophys(cp);
- cp += bufsize;
- }
- return (1);
- }
- /*
- * Routine to copy from VERSAbus memory into mbufs.
- *
- * Warning: This makes the fairly safe assumption that
- * mbufs have even lengths.
- */
- struct mbuf *
- if_vbaget(rxbuf, totlen, off, ifp, flags)
- caddr_t rxbuf;
- int totlen, off, flags;
- struct ifnet *ifp;
- {
- register caddr_t cp;
- register struct mbuf *m;
- struct mbuf *top = 0, **mp = ⊤
- int len;
- caddr_t packet_end;
-
- rxbuf += sizeof (struct ether_header);
- cp = rxbuf;
- packet_end = cp + totlen;
- if (off) {
- off += 2 * sizeof(u_short);
- totlen -= 2 *sizeof(u_short);
- cp = rxbuf + off;
- }
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == 0)
- return (0);
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = totlen;
- m->m_len = MHLEN;
-
- while (totlen > 0) {
- if (top) {
- MGET(m, M_DONTWAIT, MT_DATA);
- if (m == 0) {
- m_freem(top);
- return (0);
- }
- m->m_len = MLEN;
- }
- len = min(totlen, (packet_end - cp));
- if (len >= MINCLSIZE) {
- MCLGET(m, M_DONTWAIT);
- if (m->m_flags & M_EXT)
- m->m_len = len = min(len, MCLBYTES);
- else
- len = m->m_len;
- } else {
- /*
- * Place initial small packet/header at end of mbuf.
- */
- if (len < m->m_len) {
- if (top == 0 && len + max_linkhdr <= m->m_len)
- m->m_data += max_linkhdr;
- m->m_len = len;
- } else
- len = m->m_len;
- }
- if (flags)
- if_vba16copy(cp, mtod(m, caddr_t), (u_int)len);
- else
- bcopy(cp, mtod(m, caddr_t), (u_int)len);
-
- *mp = m;
- mp = &m->m_next;
- totlen -= len;
- cp += len;
- if (cp == packet_end)
- cp = rxbuf;
- }
- return (top);
- }
-
- if_vbaput(ifu, m0, flags)
- caddr_t ifu;
- struct mbuf *m0;
- {
- register struct mbuf *m = m0;
- register caddr_t cp = ifu;
-
- while (m) {
- if (flags)
- if_vba16copy(mtod(m, caddr_t), cp, (u_int)m->m_len);
- else
- bcopy(mtod(m, caddr_t), cp, (u_int)m->m_len);
- cp += m->m_len;
- MFREE(m, m0);
- m = m0;
- }
- if ((int)cp & 1)
- *cp++ = 0;
- return (cp - ifu);
- }
-
- if_vba16copy(from, to, cnt)
- register caddr_t from, to;
- register unsigned cnt;
- {
- register c;
- register short *f, *t;
-
- if (((int)from&01) && ((int)to&01)) {
- /* source & dest at odd addresses */
- *to++ = *from++;
- --cnt;
- }
- if (cnt > 1 && (((int)to&01) == 0) && (((int)from&01) == 0)) {
- t = (short *)to;
- f = (short *)from;
- for (c = cnt>>1; c; --c) /* even address copy */
- *t++ = *f++;
- cnt &= 1;
- if (cnt) { /* odd len */
- from = (caddr_t)f;
- to = (caddr_t)t;
- *to = *from;
- }
- }
- while ((int)cnt-- > 0) /* one of the address(es) must be odd */
- *to++ = *from++;
- }
-