home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / tahoe / if / if_vba.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  5.4 KB  |  219 lines

  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, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)if_vba.c    1.4 (Berkeley) 12/16/90
  34.  */
  35.  
  36. #include "sys/param.h"
  37. #include "sys/systm.h"
  38. #include "sys/mbuf.h"
  39. #include "sys/buf.h"
  40. #include "sys/cmap.h"
  41. #include "sys/vmmac.h"
  42. #include "sys/socket.h"
  43.  
  44. #include "../include/mtpr.h"
  45. #include "../include/pte.h"
  46.  
  47. #include "../vba/vbavar.h"
  48.  
  49. #include "net/if.h"
  50. #include "netinet/in.h"
  51. #include "netinet/if_ether.h"
  52.  
  53. #include "if_vba.h"
  54.  
  55. if_vbareserve(ifvba0, n, bufsize, extra, extrasize)
  56. struct ifvba *ifvba0;
  57. register int n;
  58. int bufsize;
  59. caddr_t *extra;
  60. int extrasize;
  61. {
  62.     register caddr_t cp;
  63.     register struct pte *pte;
  64.     register struct ifvba *ifvba = ifvba0;
  65.     struct ifvba *vlim  = ifvba + n;
  66.  
  67.     n = roundup(extrasize + (n * bufsize), NBPG);
  68.     cp = (caddr_t)malloc((u_long)n, M_DEVBUF, M_NOWAIT);
  69.     if ((n + kvtophys(cp)) > VB_MAXADDR24) {
  70.         free(cp, M_DEVBUF);
  71.         cp = 0;
  72.     }
  73.     if (cp == 0) {
  74.         printf("No memory for device buffer(s)\n");
  75.         return (0);
  76.     }
  77.     /*
  78.      * Make raw buffer pages uncacheable.
  79.      */
  80.     pte = kvtopte(cp);
  81.     for (n = btoc(n); n--; pte++)
  82.         pte->pg_nc = 1;
  83.     mtpr(TBIA, 0);
  84.     if (extra) {
  85.         *extra = cp;
  86.         cp += extrasize;
  87.     }
  88.     for (; ifvba < vlim; ifvba++) {
  89.         ifvba->iff_buffer = cp;
  90.         ifvba->iff_physaddr = kvtophys(cp);
  91.         cp += bufsize;
  92.     }
  93.     return (1);
  94. }
  95. /*
  96.  * Routine to copy from VERSAbus memory into mbufs.
  97.  *
  98.  * Warning: This makes the fairly safe assumption that
  99.  * mbufs have even lengths.
  100.  */
  101. struct mbuf *
  102. if_vbaget(rxbuf, totlen, off, ifp, flags)
  103.     caddr_t rxbuf;
  104.     int totlen, off, flags;
  105.     struct ifnet *ifp;
  106. {
  107.     register caddr_t cp;
  108.     register struct mbuf *m;
  109.     struct mbuf *top = 0, **mp = ⊤
  110.     int len;
  111.     caddr_t packet_end;
  112.  
  113.     rxbuf += sizeof (struct ether_header);
  114.     cp = rxbuf;
  115.     packet_end = cp + totlen;
  116.     if (off) {
  117.         off += 2 * sizeof(u_short);
  118.         totlen -= 2 *sizeof(u_short);
  119.         cp = rxbuf + off;
  120.     }
  121.  
  122.     MGETHDR(m, M_DONTWAIT, MT_DATA);
  123.     if (m == 0)
  124.         return (0);
  125.     m->m_pkthdr.rcvif = ifp;
  126.     m->m_pkthdr.len = totlen;
  127.     m->m_len = MHLEN;
  128.  
  129.     while (totlen > 0) {
  130.         if (top) {
  131.             MGET(m, M_DONTWAIT, MT_DATA);
  132.             if (m == 0) {
  133.                 m_freem(top);
  134.                 return (0);
  135.             }
  136.             m->m_len = MLEN;
  137.         }
  138.         len = min(totlen, (packet_end - cp));
  139.         if (len >= MINCLSIZE) {
  140.             MCLGET(m, M_DONTWAIT);
  141.             if (m->m_flags & M_EXT)
  142.                 m->m_len = len = min(len, MCLBYTES);
  143.             else
  144.                 len = m->m_len;
  145.         } else {
  146.             /*
  147.              * Place initial small packet/header at end of mbuf.
  148.              */
  149.             if (len < m->m_len) {
  150.                 if (top == 0 && len + max_linkhdr <= m->m_len)
  151.                     m->m_data += max_linkhdr;
  152.                 m->m_len = len;
  153.             } else
  154.                 len = m->m_len;
  155.         }
  156.         if (flags)
  157.             if_vba16copy(cp, mtod(m, caddr_t), (u_int)len);
  158.         else
  159.             bcopy(cp, mtod(m, caddr_t), (u_int)len);
  160.  
  161.         *mp = m;
  162.         mp = &m->m_next;
  163.         totlen -= len;
  164.         cp += len;
  165.         if (cp == packet_end)
  166.             cp = rxbuf;
  167.     }
  168.     return (top);
  169. }
  170.  
  171. if_vbaput(ifu, m0, flags)
  172. caddr_t ifu;
  173. struct mbuf *m0;
  174. {
  175.     register struct mbuf *m = m0;
  176.     register caddr_t cp = ifu;
  177.  
  178.     while (m) {
  179.         if (flags)
  180.             if_vba16copy(mtod(m, caddr_t), cp, (u_int)m->m_len);
  181.         else
  182.             bcopy(mtod(m, caddr_t), cp, (u_int)m->m_len);
  183.         cp += m->m_len;
  184.         MFREE(m, m0);
  185.         m = m0;
  186.     }
  187.     if ((int)cp & 1)
  188.         *cp++ = 0;
  189.     return (cp - ifu);
  190. }
  191.  
  192. if_vba16copy(from, to, cnt)
  193.     register caddr_t from, to;
  194.     register unsigned cnt;
  195. {
  196.     register c;
  197.     register short *f, *t;
  198.  
  199.     if (((int)from&01) && ((int)to&01)) {
  200.         /* source & dest at odd addresses */
  201.         *to++ = *from++;
  202.         --cnt;
  203.     }
  204.     if (cnt > 1 && (((int)to&01) == 0) && (((int)from&01) == 0)) {
  205.         t = (short *)to;
  206.         f = (short *)from;
  207.         for (c = cnt>>1; c; --c)    /* even address copy */
  208.             *t++ = *f++;
  209.         cnt &= 1;
  210.         if (cnt) {            /* odd len */
  211.             from = (caddr_t)f;
  212.             to = (caddr_t)t;
  213.             *to = *from;
  214.         }
  215.     }
  216.     while ((int)cnt-- > 0)    /* one of the address(es) must be odd */
  217.         *to++ = *from++;
  218. }
  219.