SCCS-vsn: sys/vax/if/if_uba.c 6.5
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
- * @(#)if_uba.c 6.4 (Berkeley) %G%
+ * @(#)if_uba.c 6.5 (Berkeley) %G%
*/
#include "../machine/pte.h"
*/
#include "../machine/pte.h"
* data into mbufs. When full cluster sized units are present
* on the interface on cluster boundaries we can get them more
* easily by remapping, and take advantage of this here.
* data into mbufs. When full cluster sized units are present
* on the interface on cluster boundaries we can get them more
* easily by remapping, and take advantage of this here.
+ * Prepend a pointer to the interface structure,
+ * so that protocols can determine where incoming packets arrived.
-if_rubaget(ifu, totlen, off0)
+if_rubaget(ifu, totlen, off0, ifp)
register struct ifuba *ifu;
int totlen, off0;
register struct ifuba *ifu;
int totlen, off0;
{
struct mbuf *top, **mp, *m;
int off = off0, len;
{
struct mbuf *top, **mp, *m;
int off = off0, len;
cp = ifu->ifu_r.ifrw_addr + ifu->ifu_hlen + off;
} else
len = totlen;
cp = ifu->ifu_r.ifrw_addr + ifu->ifu_hlen + off;
} else
len = totlen;
struct mbuf *p;
struct pte *cpte, *ppte;
int x, *ip, i;
struct mbuf *p;
struct pte *cpte, *ppte;
int x, *ip, i;
+ /*
+ * If doing the first mbuf and
+ * the interface pointer hasn't been put in,
+ * put it in a separate mbuf to preserve alignment.
+ */
+ if (ifp) {
+ len = 0;
+ goto nopage;
+ }
MCLGET(p, 1);
if (p == 0)
goto nopage;
MCLGET(p, 1);
if (p == 0)
goto nopage;
- len = m->m_len = CLBYTES;
+ len = m->m_len = min(len, CLBYTES);
m->m_off = (int)p - (int)m;
if (!claligned(cp))
goto copy;
m->m_off = (int)p - (int)m;
if (!claligned(cp))
goto copy;
- m->m_len = MIN(MLEN, len);
+ if (ifp) {
+ /*
+ * Leave room for ifp.
+ */
+ m->m_len = MIN(MLEN - sizeof(ifp), len);
+ m->m_off += sizeof(ifp);
+ } else
+ m->m_len = MIN(MLEN, len);
copy:
bcopy(cp, mtod(m, caddr_t), (unsigned)m->m_len);
cp += m->m_len;
copy:
bcopy(cp, mtod(m, caddr_t), (unsigned)m->m_len);
cp += m->m_len;
}
} else
totlen -= m->m_len;
}
} else
totlen -= m->m_len;
+ if (ifp) {
+ /*
+ * Prepend interface pointer to first mbuf.
+ */
+ m->m_len += sizeof(ifp);
+ m->m_off -= sizeof(ifp);
+ *(mtod(m, struct ifnet **)) = ifp;
+ ifp = (struct ifnet *)0;
+ }
cp = ifu->ifu_w.ifrw_addr;
while (m) {
dp = mtod(m, char *);
cp = ifu->ifu_w.ifrw_addr;
while (m) {
dp = mtod(m, char *);
- if (claligned(cp) && claligned(dp) && m->m_len == CLBYTES) {
+ if (claligned(cp) && claligned(dp) &&
+ (m->m_len == CLBYTES || m->m_next == (struct mbuf *)0)) {
struct pte *pte; int *ip;
pte = &Mbmap[mtocl(dp)*CLSIZE];
x = btop(cp - ifu->ifu_w.ifrw_addr);
struct pte *pte; int *ip;
pte = &Mbmap[mtocl(dp)*CLSIZE];
x = btop(cp - ifu->ifu_w.ifrw_addr);