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 = ⊤ 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