Beispiel #1
3
static void receive_packet(uint8_t *buffer, int length)
{
  struct ifnet *ifp = &arpcom.ac_if;
  struct mbuf *m;
  struct ether_header *eh;
  uint32_t computed_crc, net_crc;
  
  if(length < 64) {
    printk("Warning: Ethernet packet too short\n");
    return;
  }

  length -= 4; /* strip CRC */
  net_crc = ((uint32_t)buffer[length])
    | ((uint32_t)buffer[length+1] << 8)
    | ((uint32_t)buffer[length+2] << 16)
    | ((uint32_t)buffer[length+3] << 24);
  length -= 8; /* strip preamble */
  computed_crc = ether_crc32_le(&buffer[8], length) ^ 0xffffffff;
  if(computed_crc == net_crc) {
    MGETHDR(m, M_WAIT, MT_DATA);
    MCLGET(m, M_WAIT);
    length -= sizeof(struct ether_header); /* strip Ethernet header */
    memcpy(m->m_data, &buffer[8+sizeof(struct ether_header)], length);
    m->m_len = m->m_pkthdr.len = length;
    m->m_pkthdr.rcvif = ifp;
    eh = (struct ether_header *)&buffer[8];
    ether_input(ifp, eh, m);
  } else
    printk("Ethernet CRC error: got %08x expected %08x (len=%d)\n",
      net_crc, computed_crc, length);
}
Beispiel #2
0
OM_uint32
gss_verify_mic(OM_uint32 *minor_status,
               const gss_ctx_id_t ctx,
               const gss_buffer_t message_buffer,
               const gss_buffer_t token_buffer,
               gss_qop_t *qop_state)
{
    OM_uint32 maj_stat;
    struct mbuf *m, *mic;

    if (!ctx) {
        *minor_status = 0;
        return (GSS_S_NO_CONTEXT);
    }

    MGET(m, M_WAITOK, MT_DATA);
    if (message_buffer->length > MLEN)
        MCLGET(m, M_WAITOK);
    m_append(m, message_buffer->length, message_buffer->value);

    MGET(mic, M_WAITOK, MT_DATA);
    if (token_buffer->length > MLEN)
        MCLGET(mic, M_WAITOK);
    m_append(mic, token_buffer->length, token_buffer->value);

    maj_stat = KGSS_VERIFY_MIC(ctx, minor_status, m, mic, qop_state);

    m_freem(m);
    m_freem(mic);

    return (maj_stat);
}
Beispiel #3
0
/*
 * Allocate enough mbufs to accommodate the residual count in uio,
 * and setup the uio_iov to point to them.
 *
 * This is used by the various SMB read code paths.  That code is
 * going to do a disk read into this buffer, so we'd like it to be
 * large and contiguous.  Use an external (M_EXT) buffer.
 */
struct mbuf *
smb_mbuf_allocate(struct uio *uio)
{
	mbuf_t	*m = 0;
	int	len = uio->uio_resid;

	MGET(m, M_WAIT, MT_DATA);
	if (len > MCLBYTES) {
		/* Like MCLGET(), but bigger buf. */
		m->m_ext.ext_buf = kmem_zalloc(len, KM_SLEEP);
		m->m_data = m->m_ext.ext_buf;
		m->m_flags |= M_EXT;
		m->m_ext.ext_size = len;
		m->m_ext.ext_ref = smb_mbuf_kmem_ref;
	} else if (len > MLEN) {
		/* Use the kmem cache. */
		MCLGET(m, M_WAIT);
	}
	m->m_len = len;

	uio->uio_iov->iov_base = m->m_data;
	uio->uio_iov->iov_len = m->m_len;
	uio->uio_iovcnt = 1;

	return (m);
}
Beispiel #4
0
/*
 * smb_mbuf_get
 *
 * Allocate mbufs to hold the amount of data specified.
 * A pointer to the head of the mbuf list is returned.
 */
struct mbuf *
smb_mbuf_get(uchar_t *buf, int nbytes)
{
	struct mbuf *mhead = 0;
	struct mbuf *m = 0;
	int count;
	int offset = 0;

	while (nbytes) {
		count = (nbytes > MCLBYTES) ? MCLBYTES : nbytes;
		nbytes -= count;

		if (mhead == 0) {
			MGET(mhead, M_WAIT, MT_DATA);
			m = mhead;
		} else {
			MGET(m->m_next, M_WAIT, MT_DATA);
			m = m->m_next;
		}

		if (count > MLEN) {
			MCLGET(m, M_WAIT);
		}

		m->m_len = count;
		bcopy(buf + offset, m->m_data, count);
		offset += count;
	}
	return (mhead);
}
Beispiel #5
0
/*
 * Create a "control" mbuf containing the specified data
 * with the specified type for presentation on a socket buffer.
 */
struct mbuf *
sbcreatecontrol(caddr_t p, int size, int type, int level)
{
	struct cmsghdr *cp;
	struct mbuf *m;

	if (CMSG_SPACE(size) > MCLBYTES) {
		printf("sbcreatecontrol: message too large %d\n", size);
		return NULL;
	}

	if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL)
		return (NULL);
	if (CMSG_SPACE(size) > MLEN) {
		MCLGET(m, M_DONTWAIT);
		if ((m->m_flags & M_EXT) == 0) {
			m_free(m);
			return NULL;
		}
	}
	cp = mtod(m, struct cmsghdr *);
	memset(cp, 0, CMSG_SPACE(size));
	memcpy(CMSG_DATA(cp), p, size);
	m->m_len = CMSG_SPACE(size);
	cp->cmsg_len = CMSG_LEN(size);
	cp->cmsg_level = level;
	cp->cmsg_type = type;
	return (m);
}
Beispiel #6
0
struct mbuf*
dme_alloc_receive_buffer(struct ifnet *ifp, unsigned int frame_length)
{
    struct dme_softc *sc = ifp->if_softc;
    struct mbuf *m;
    int pad;

    MGETHDR(m, M_DONTWAIT, MT_DATA);
    m->m_pkthdr.rcvif = ifp;
    /* Ensure that we always allocate an even number of
     * bytes in order to avoid writing beyond the buffer
     */
    m->m_pkthdr.len = frame_length + (frame_length % sc->sc_data_width);
    pad = ALIGN(sizeof(struct ether_header)) -
          sizeof(struct ether_header);
    /* All our frames have the CRC attached */
    m->m_flags |= M_HASFCS;
    if (m->m_pkthdr.len + pad > MHLEN )
        MCLGET(m, M_DONTWAIT);

    m->m_data += pad;
    m->m_len = frame_length + (frame_length % sc->sc_data_width);

    return m;
}
Beispiel #7
0
static int bsd_setsockopt( cyg_file *fp, int level, int optname,
                           const void *optval, socklen_t optlen)
{
    int error;
    struct mbuf *m = NULL;
    
    if( optlen > MCLBYTES )
        return EINVAL;

    if (optval != NULL) {
        m = m_get(M_WAIT, MT_SOOPTS);
        if (optlen > MLEN) {
            MCLGET(m, M_DONTWAIT);
            if ((m->m_flags & M_EXT) == 0) {
                m_freem(m);
                return (ENOBUFS);
            }
        }
        if (m == NULL)
            return (ENOBUFS);
        error = copyin(optval, mtod(m, caddr_t), optlen);
        if (error) {
            (void) m_free(m);
            return (error);
        }
        m->m_len = optlen;
    }
    
    return (sosetopt((struct socket *)fp->f_data, level, optname, m));
}
Beispiel #8
0
/*
 * DON'T use free_sent_buffers to drop the queue!
 */
static void
alloc_rx_buffers(struct sbsh_softc *sc)
{
	unsigned	cur_rbd = sc->regs->LRDR & 0x7f;
	struct mbuf	*m;

	while (sc->tail_rq != ((sc->head_rq - 1) & (RQLEN - 1))) {
		MGETHDR(m, M_NOWAIT, MT_DATA);
		if (!m) {
			if_printf (&sc->arpcom.ac_if,
				   "unable to get mbuf.\n");
			return;
		}

		if (SBNI16_MAX_FRAME > MHLEN) {
			MCLGET(m, M_NOWAIT);
			if (!(m->m_flags & M_EXT)) {
				m_freem(m);
				if_printf (&sc->arpcom.ac_if,
					   "unable to get mbuf cluster.\n");
				return;
			}
			m->m_pkthdr.len = m->m_len = MCLBYTES;
		}

		m_adj(m, 2);	/* align ip on longword boundaries */

		sc->rq[sc->tail_rq++] = m;
		sc->tail_rq &= (RQLEN - 1);

		sc->rbd[cur_rbd].address = vtophys(mtod(m, vm_offset_t));
		sc->rbd[cur_rbd].length  = 0;
		sc->regs->LRDR = cur_rbd = (cur_rbd + 1) & 0x7f;
	}
}
Beispiel #9
0
OM_uint32
gss_get_mic(OM_uint32 *minor_status,
    const gss_ctx_id_t ctx,
    gss_qop_t qop_req,
    const gss_buffer_t message_buffer,
    gss_buffer_t message_token)
{
	OM_uint32 maj_stat;
	struct mbuf *m, *mic;

	if (!ctx) {
		*minor_status = 0;
		return (GSS_S_NO_CONTEXT);
	}

	MGET(m, M_WAITOK, MT_DATA);
	if (message_buffer->length > MLEN)
		MCLGET(m, M_WAITOK);
	m_append(m, message_buffer->length, message_buffer->value);

	maj_stat = KGSS_GET_MIC(ctx, minor_status, qop_req, m, &mic);

	m_freem(m);
	if (maj_stat == GSS_S_COMPLETE) {
		message_token->length = m_length(mic, NULL);
		message_token->value = malloc(message_token->length,
		    M_GSSAPI, M_WAITOK);
		m_copydata(mic, 0, message_token->length,
		    message_token->value);
		m_freem(mic);
	}

	return (maj_stat);
}
Beispiel #10
0
/*
 * Function:	mcf548x_fec_rx_bd_init
 *
 * Description:	Initialize the receive buffer descriptor ring.
 *
 * Returns:		void
 *
 * Notes:       Space for the buffers of rx BDs is allocated by the rx deamon
 *
 */
static void mcf548x_fec_rx_bd_init(struct mcf548x_enet_struct *sc) {
  int rxBdIndex;
  struct mbuf *m;
  struct ifnet *ifp = &sc->arpcom.ac_if;

  /*
   * Fill RX buffer descriptor ring.
   */
  for( rxBdIndex = 0; rxBdIndex < sc->rxBdCount; rxBdIndex++ ) {
    MGETHDR (m, M_WAIT, MT_DATA);
    MCLGET (m, M_WAIT);

    m->m_pkthdr.rcvif = ifp;
    sc->rxMbuf[rxBdIndex] = m;
    rtems_cache_invalidate_multiple_data_lines(mtod(m,const void *),
					       ETHER_MAX_LEN);
    SET_BD_BUFFER(sc->rxBd+rxBdIndex,mtod(m, void *));
    SET_BD_LENGTH(sc->rxBd+rxBdIndex,ETHER_MAX_LEN);
    SET_BD_STATUS(sc->rxBd+rxBdIndex,
		  MCF548X_FEC_RBD_EMPTY
		  | MCF548X_FEC_RBD_INT
		  | ((rxBdIndex == sc->rxBdCount-1)
		     ? MCF548X_FEC_RBD_WRAP
		     : 0));
  }
}
Beispiel #11
0
struct mbuf* 
wan_mbuf_alloc(int len)
{
	struct mbuf	*m;

	/* XXX handle len > MCLBYTES */
	if (len <= 0 || len > MCLBYTES)
		return (NULL);

	MGETHDR(m, M_DONTWAIT, MT_DATA);

	if (m == NULL || len <= MHLEN)
		return (m);

	m->m_pkthdr.len = len;
	m->m_len = len;
	MCLGET(m, M_DONTWAIT);

	if ((m->m_flags & M_EXT) == 0) {
		m_freem(m);
		return (NULL);
	}

	return (m);
}
Beispiel #12
0
Static int
url_newbuf(struct url_softc *sc, struct url_chain *c, struct mbuf *m)
{
	struct mbuf *m_new = NULL;

	DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));

	if (m == NULL) {
		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
		if (m_new == NULL) {
			printf("%s: no memory for rx list "
			       "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
			return (ENOBUFS);
		}
		MCLGET(m_new, M_DONTWAIT);
		if (!(m_new->m_flags & M_EXT)) {
			printf("%s: no memory for rx list "
			       "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
			m_freem(m_new);
			return (ENOBUFS);
		}
		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
	} else {
		m_new = m;
		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
		m_new->m_data = m_new->m_ext.ext_buf;
	}

	m_adj(m_new, ETHER_ALIGN);
	c->url_mbuf = m_new;

	return (0);
}
Beispiel #13
0
/*
 * Initialize an RX descriptor and attach an MBUF cluster.
 */
int
kue_newbuf(struct kue_softc *sc, struct kue_chain *c, struct mbuf *m)
{
	struct mbuf		*m_new = NULL;

	DPRINTFN(10,("%s: %s: enter\n", sc->kue_dev.dv_xname,__func__));

	if (m == NULL) {
		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
		if (m_new == NULL) {
			printf("%s: no memory for rx list "
			    "-- packet dropped!\n", sc->kue_dev.dv_xname);
			return (ENOBUFS);
		}

		MCLGET(m_new, M_DONTWAIT);
		if (!(m_new->m_flags & M_EXT)) {
			printf("%s: no memory for rx list "
			    "-- packet dropped!\n", sc->kue_dev.dv_xname);
			m_freem(m_new);
			return (ENOBUFS);
		}
		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
	} else {
		m_new = m;
		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
		m_new->m_data = m_new->m_ext.ext_buf;
	}

	c->kue_mbuf = m_new;

	return (0);
}
Beispiel #14
0
static struct mbuf *
repack(struct sbsh_softc *sc, struct mbuf *m)
{
	struct mbuf  *m_new;

	MGETHDR(m_new, M_NOWAIT, MT_DATA);
	if (!m_new) {
		if_printf (&sc->arpcom.ac_if,
			   "unable to get mbuf.\n");
		return (NULL);
	}

	if (m->m_pkthdr.len > MHLEN) {
		MCLGET(m_new, M_NOWAIT);
		if (!(m_new->m_flags & M_EXT)) {
			m_freem(m_new);
			if_printf (&sc->arpcom.ac_if,
				   "unable to get mbuf cluster.\n");
			return (NULL);
		}
	}

	m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t));
	m_new->m_pkthdr.len = m_new->m_len = m->m_pkthdr.len;
	m_freem(m);
	return (m_new);
}
Beispiel #15
0
/*
 * Generate the rpc reply header
 * siz arg. is used to decide if adding a cluster is worthwhile
 */
struct mbuf *
nfs_rephead(int siz, struct nfsrv_descript *nd, int err,
    struct mbuf **mbp, caddr_t *bposp)
{
	u_int32_t *tl;
	struct mbuf *mreq;
	caddr_t bpos;
	struct mbuf *mb;

	if (err == EBADRPC)
		return (NULL);

	nd->nd_repstat = err;
	if (err && (nd->nd_flag & ND_NFSV3) == 0)	/* XXX recheck */
		siz = 0;

	MGET(mreq, M_WAITOK, MT_DATA);

	/*
	 * If this is a big reply, use a cluster
	 */
	mreq->m_len = 0;
	if (siz >= MINCLSIZE) {
		MCLGET(mreq, M_WAITOK);
	}
	mb = mreq;
	bpos = mtod(mb, caddr_t);

	if (err != NFSERR_RETVOID) {
		tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
		if (err)
			*tl = txdr_unsigned(nfsrv_errmap(nd, err));
		else
			*tl = 0;
	}
Beispiel #16
0
unsigned char* Ecos_MemPool_Alloc (
	unsigned long Length,
	int Type)
{
    struct mbuf *pMBuf = NULL;

	switch (Type)
	{        
                case MemPool_TYPE_Header:
                        MGETHDR(pMBuf, M_DONTWAIT, MT_DATA);
                        break;
		case MemPool_TYPE_CLUSTER:
			MGETHDR(pMBuf, M_DONTWAIT, MT_DATA);
			if (pMBuf== NULL)
				return NULL;
			MCLGET(pMBuf, M_DONTWAIT);
			if ((pMBuf->m_flags & M_EXT) == 0)
                        {
				m_freem(pMBuf);
                                return NULL;
                        }
                        break;
                default:
                        DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknown Type %d\n", __FUNCTION__, Type));
                        break;
	}
    
    return pMBuf;
}
Beispiel #17
0
/* Add a receive buffer to the indiciated descriptor. */
int
bce_add_rxbuf(struct bce_softc *sc, int idx)
{
	struct mbuf    *m;
	int             error;

	MGETHDR(m, M_DONTWAIT, MT_DATA);
	if (m == NULL)
		return (ENOBUFS);

	MCLGET(m, M_DONTWAIT);
	if ((m->m_flags & M_EXT) == 0) {
		m_freem(m);
		return (ENOBUFS);
	}
	if (sc->bce_cdata.bce_rx_chain[idx] != NULL)
		bus_dmamap_unload(sc->bce_dmatag,
		    sc->bce_cdata.bce_rx_map[idx]);

	sc->bce_cdata.bce_rx_chain[idx] = m;

	error = bus_dmamap_load(sc->bce_dmatag, sc->bce_cdata.bce_rx_map[idx],
	    m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
	    BUS_DMA_READ | BUS_DMA_NOWAIT);
	if (error)
		return (error);

	bus_dmamap_sync(sc->bce_dmatag, sc->bce_cdata.bce_rx_map[idx], 0,
	    sc->bce_cdata.bce_rx_map[idx]->dm_mapsize, BUS_DMASYNC_PREREAD);

	BCE_INIT_RXDESC(sc, idx);

	return (0);

}
/*
 * Add a receive buffer to the indicated descriptor.
 */
int
ni_add_rxbuf(struct ni_softc *sc, struct ni_dg *data, int idx)
{
	struct ni_bbd *bd = &bbd[idx];
	struct mbuf *m;

	MGETHDR(m, M_DONTWAIT, MT_DATA);
	if (m == NULL)
		return (ENOBUFS);

	MCLGET(m, M_DONTWAIT);
	if ((m->m_flags & M_EXT) == 0) {
		m_freem(m);
		return (ENOBUFS);
	}

	m->m_data += 2;
	bd->nb_len = (m->m_ext.ext_size - 2);
	bd->nb_pte = (long)kvtopte(m->m_ext.ext_buf);
	bd->nb_status = 2 | NIBD_VALID;
	bd->nb_key = 1;

	data->bufs[0]._offset = 0;
	data->bufs[0]._len = bd->nb_len;
	data->bufs[0]._index = idx;
	data->nd_cmdref = (long)m;

	return (0);
}
/*
 * m_pullup2() works like m_pullup, save that len can be <= MCLBYTES.
 * m_pullup2() only works on values of len such that MHLEN < len <= MCLBYTES,
 * it calls m_pullup() for values <= MHLEN.  It also only coagulates the
 * reqested number of bytes.  (For those of us who expect unwieldly option
 * headers.
 *
 * KEBE SAYS:  Remember that dtom() calls with data in clusters does not work!
 */
struct mbuf *   
m_pullup2(struct mbuf *n, int len)       
{
	struct mbuf *m;
	int count;

	if (len <= MHLEN)
		return m_pullup(n, len);
	if ((n->m_flags & M_EXT) != 0 &&
	    n->m_data + len < &n->m_data[MCLBYTES] && n->m_next) {
		if (n->m_len >= len)
			return (n);
		m = n;
		n = n->m_next;
		len -= m->m_len;
	} else {
		if (len > MCLBYTES)
			goto bad;
		MGET(m, M_DONTWAIT, n->m_type);
		if (m == NULL)
			goto bad;
		MCLGET(m, M_DONTWAIT);
		if ((m->m_flags & M_EXT) == 0)
			goto bad;
		m->m_len = 0;
		if (n->m_flags & M_PKTHDR) {
			/* Too many adverse side effects. */
			/* M_MOVE_PKTHDR(m, n); */
			m->m_flags = (n->m_flags & M_COPYFLAGS) |
			    M_EXT | M_CLUSTER;
			M_MOVE_HDR(m, n);
			/* n->m_data is cool. */
		}
	}

	do {
		count = min(len, n->m_len);
		bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
		    (unsigned)count);
		len -= count;
		m->m_len += count;
		n->m_len -= count;
		if (n->m_len)
			n->m_data += count;
		else
			n = m_free(n);
	} while (len > 0 && n);
	if (len > 0) {
		(void)m_free(m);
		goto bad;
	}
	m->m_next = n;

	return (m);
bad:
	m_freem(n);
	MPFail++;
	return (NULL);
}
Beispiel #20
0
int
cpsw_new_rxbuf(struct cpsw_softc * const sc, const u_int i)
{
	struct cpsw_ring_data * const rdp = sc->sc_rdp;
	const u_int h = RXDESC_PREV(i);
	struct cpsw_cpdma_bd bd;
	struct mbuf *m;
	int error = ENOBUFS;

	MGETHDR(m, M_DONTWAIT, MT_DATA);
	if (m == NULL) {
		goto reuse;
	}

	MCLGET(m, M_DONTWAIT);
	if ((m->m_flags & M_EXT) == 0) {
		m_freem(m);
		goto reuse;
	}

	/* We have a new buffer, prepare it for the ring. */

	if (rdp->rx_mb[i] != NULL)
		bus_dmamap_unload(sc->sc_bdt, rdp->rx_dm[i]);

	m->m_len = m->m_pkthdr.len = MCLBYTES;

	rdp->rx_mb[i] = m;

	error = bus_dmamap_load_mbuf(sc->sc_bdt, rdp->rx_dm[i], rdp->rx_mb[i],
	    BUS_DMA_READ|BUS_DMA_NOWAIT);
	if (error) {
		printf("can't load rx DMA map %d: %d\n", i, error);
	}

	bus_dmamap_sync(sc->sc_bdt, rdp->rx_dm[i],
	    0, rdp->rx_dm[i]->dm_mapsize, BUS_DMASYNC_PREREAD);

	error = 0;

reuse:
	/* (re-)setup the descriptor */
	bd.next = 0;
	bd.bufptr = rdp->rx_dm[i]->dm_segs[0].ds_addr;
	bd.bufoff = 0;
	bd.buflen = MIN(0x7ff, rdp->rx_dm[i]->dm_segs[0].ds_len);
	bd.pktlen = 0;
	bd.flags = CPDMA_BD_OWNER;

	cpsw_set_rxdesc(sc, i, &bd);
	/* and link onto ring */
	cpsw_set_rxdesc_next(sc, h, cpsw_rxdesc_paddr(sc, i));

	return error;
}
Beispiel #21
0
/*
 * Pull read data off a interface.
 * Len is length of data, with local net header stripped.
 */
static struct mbuf *
elget(caddr_t buf, int totlen, struct ifnet *ifp)
{
        struct mbuf *top, **mp, *m;
        int len;
        caddr_t cp;
        char *epkt;

        cp = buf;
        epkt = cp + totlen;

        MGETHDR(m, MB_DONTWAIT, MT_DATA);
        if (m == 0)
                return (0);
        m->m_pkthdr.len = totlen;
        m->m_len = MHLEN;
        top = 0;
        mp = &top;
        while (totlen > 0) {
                if (top) {
                        MGET(m, MB_DONTWAIT, MT_DATA);
                        if (m == 0) {
                                m_freem(top);
                                return (0);
                        }
                        m->m_len = MLEN;
                }
                len = min(totlen, epkt - cp);
                if (len >= MINCLSIZE) {
                        MCLGET(m, MB_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;
                }
                bcopy(cp, mtod(m, caddr_t), (unsigned)len);
                cp += len;
                *mp = m;
                mp = &m->m_next;
                totlen -= len;
                if (cp == epkt)
                        cp = buf;
        }
        return (top);
}
/*
 * munge the received packet into an mbuf chain
 */
static inline struct mbuf *
sonic_get(struct sn_softc *sc, void *pkt, int datalen)
{
	struct	mbuf *m, *top, **mp;
	int	len;

	MGETHDR(m, M_DONTWAIT, MT_DATA);
	if (m == 0)
		return 0;
	m->m_pkthdr.rcvif = &sc->sc_if;
	m->m_pkthdr.len = datalen;
	len = MHLEN;
	top = 0;
	mp = &top;

	while (datalen > 0) {
		if (top) {
			MGET(m, M_DONTWAIT, MT_DATA);
			if (m == 0) {
				m_freem(top);
				return 0;
			}
			len = MLEN;
		}
		if (datalen >= MINCLSIZE) {
			MCLGET(m, M_DONTWAIT);
			if ((m->m_flags & M_EXT) == 0) {
				if (top) m_freem(top);
				return 0;
			}
			len = MCLBYTES;
		}

		if (mp == &top) {
			char *newdata = (char *)
			    ALIGN((char *)m->m_data + 
				sizeof(struct ether_header)) -
			    sizeof(struct ether_header);
			len -= newdata - m->m_data; 
			m->m_data = newdata;
		}

		m->m_len = len = min(datalen, len);

		memcpy(mtod(m, void *), pkt, (unsigned) len);
		pkt = (char *)pkt + len;
		datalen -= len;
		*mp = m;
		mp = &m->m_next;
	}

	return top;
}
Beispiel #23
0
/*
 * Pull read data off a interface.  Len is length of data, with local net
 * header stripped.  We copy the data into mbufs.  When full cluster sized
 * units are present we copy into clusters.
 */
struct mbuf *
elget(struct el_softc *sc, int totlen)
{
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	bus_space_tag_t iot = sc->sc_iot;
	bus_space_handle_t ioh = sc->sc_ioh;
	struct mbuf *m, *m0, *newm;
	int len;

	MGETHDR(m0, M_DONTWAIT, MT_DATA);
	if (m0 == 0)
		return (0);
	m0->m_pkthdr.rcvif = ifp;
	m0->m_pkthdr.len = totlen;
	len = MHLEN;
	m = m0;

	bus_space_write_1(iot, ioh, EL_GPBL, 0);
	bus_space_write_1(iot, ioh, EL_GPBH, 0);

	while (totlen > 0) {
		if (totlen >= MINCLSIZE) {
			MCLGET(m, M_DONTWAIT);
			if ((m->m_flags & M_EXT) == 0)
				goto bad;
			len = MCLBYTES;
		}

		m->m_len = len = min(totlen, len);
		bus_space_read_multi_1(iot, ioh, EL_BUF, mtod(m, u_int8_t *), len);

		totlen -= len;
		if (totlen > 0) {
			MGET(newm, M_DONTWAIT, MT_DATA);
			if (newm == 0)
				goto bad;
			len = MLEN;
			m = m->m_next = newm;
		}
	}

	bus_space_write_1(iot, ioh, EL_RBC, 0);
	bus_space_write_1(iot, ioh, EL_AC, EL_AC_RX);

	return (m0);

bad:
	m_freem(m0);
	return (0);
}
Beispiel #24
0
/*---------------------------------------------------------------------------*
 *	allocate D-channel mbuf space
 *---------------------------------------------------------------------------*/
struct mbuf*
i4b_Dgetmbuf(int len)
{
	struct mbuf *m;

	if(len > MCLBYTES)	/* if length > max extension size */
	{

#ifdef I4B_MBUF_DEBUG
		printf("i4b_getmbuf: error - len(%d) > MCLBYTES(%d)\n",
					len, MCLBYTES);
#endif
		
		return(NULL);
	}

	MGETHDR(m, M_DONTWAIT, MT_I4B_D);	/* get mbuf with pkthdr */

	/* did we actually get the mbuf ? */

	if(!m)	
	{

#ifdef I4B_MBUF_DEBUG
		printf("i4b_getbuf: error - MGETHDR failed!\n");
#endif

		return(NULL);
	}

	if(len >= MHLEN)
	{
		MCLGET(m, M_DONTWAIT);

		if(!(m->m_flags & M_EXT))
		{
			m_freem(m);

#ifdef I4B_MBUF_DEBUG
			printf("i4b_getbuf: error - MCLGET failed, len(%d)\n", len);
#endif
			
			return (NULL);
		}
	}

	m->m_len = len;

	return(m);
}
Beispiel #25
0
/*
 * Retreive packet from shared memory and send to the next level up via
 * ether_input().
 */
static void
ed_get_packet(struct ed_softc *sc, bus_size_t buf, u_short len)
{
	struct ifnet *ifp = sc->ifp;
	struct ether_header *eh;
	struct mbuf *m;

	/* Allocate a header mbuf */
	MGETHDR(m, M_NOWAIT, MT_DATA);
	if (m == NULL)
		return;
	m->m_pkthdr.rcvif = ifp;
	m->m_pkthdr.len = m->m_len = len;

	/*
	 * We always put the received packet in a single buffer -
	 * either with just an mbuf header or in a cluster attached
	 * to the header. The +2 is to compensate for the alignment
	 * fixup below.
	 */
	if ((len + 2) > MHLEN) {
		/* Attach an mbuf cluster */
		MCLGET(m, M_NOWAIT);

		/* Insist on getting a cluster */
		if ((m->m_flags & M_EXT) == 0) {
			m_freem(m);
			return;
		}
	}

	/*
	 * The +2 is to longword align the start of the real packet.
	 * This is important for NFS.
	 */
	m->m_data += 2;
	eh = mtod(m, struct ether_header *);

	/*
	 * Get packet, including link layer address, from interface.
	 */
	ed_ring_copy(sc, buf, (char *)eh, len);

	m->m_pkthdr.len = m->m_len = len;

	ED_UNLOCK(sc);
	(*ifp->if_input)(ifp, m);
	ED_LOCK(sc);
}
Beispiel #26
0
int
mveth_tx(struct mv64340_private *mp, char *data, int len, int nbufs)
{
int rval = -1,l;
char        *p;
struct mbuf *m;
char 	*emsg = 0;

	rtems_bsdnet_semaphore_obtain();
	MGETHDR(m, M_WAIT, MT_DATA);
	if ( !m ) {
		emsg="Unable to allocate header\n";
		goto bail;
	}
	MCLGET(m, M_WAIT);
	if ( !(m->m_flags & M_EXT) ) {
		m_freem(m);
		emsg="Unable to allocate cluster\n";
		goto bail;
	}
	p = mtod(m, char *);
	l = 0;
	switch (nbufs) {
		case 3:
		default:
			emsg="nbufs arg must be 1..3\n";
			goto bail;

		case 1:
			l += sizeof(BcHeader);
			memcpy(p, &BcHeader, sizeof(BcHeader));
			p += sizeof(BcHeader);

		case 2:
			memcpy(p,data,len);
			l += len;
			m->m_len = m->m_pkthdr.len = l;
			if ( 2 == nbufs ) {
    			M_PREPEND(m, sizeof (BcHeader), M_WAIT);
				if (!m) {
					emsg = "Unable to prepend\n";
					goto bail;
				}
				p = mtod(m, char*);
				memcpy(p,&BcHeader,sizeof(BcHeader));
				l += sizeof(BcHeader);
			}
		break;
	}
Beispiel #27
0
struct mbuf *
getmcl()
{
    struct mbuf *m;

    MGETHDR(m, M_DONTWAIT, MT_DATA);
    if (m == NULL)
        return 0;
    MCLGET(m, M_DONTWAIT);
    if ((m->m_flags & M_EXT) == 0) {
        m_freem(m);
        return 0;
    }
    return m;
}
Beispiel #28
0
/* ARGSUSED */
int
sys_setsockopt(struct proc *p, void *v, register_t *retval)
{
	struct sys_setsockopt_args /* {
		syscallarg(int) s;
		syscallarg(int) level;
		syscallarg(int) name;
		syscallarg(const void *) val;
		syscallarg(socklen_t) valsize;
	} */ *uap = v;
	struct file *fp;
	struct mbuf *m = NULL;
	int error;

	if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
		return (error);
	if (SCARG(uap, valsize) > MCLBYTES) {
		error = EINVAL;
		goto bad;
	}
	if (SCARG(uap, val)) {
		m = m_get(M_WAIT, MT_SOOPTS);
		if (SCARG(uap, valsize) > MLEN) {
			MCLGET(m, M_DONTWAIT);
			if ((m->m_flags & M_EXT) == 0) {
				error = ENOBUFS;
				goto bad;
			}
		}
		if (m == NULL) {
			error = ENOBUFS;
			goto bad;
		}
		error = copyin(SCARG(uap, val), mtod(m, caddr_t),
		    SCARG(uap, valsize));
		if (error) {
			goto bad;
		}
		m->m_len = SCARG(uap, valsize);
	}
	error = sosetopt(fp->f_data, SCARG(uap, level), SCARG(uap, name), m);
	m = NULL;
bad:
	if (m)
		m_freem(m);
	FRELE(fp, p);
	return (error);
}
/*
 * Line specific (tty) write routine.
 */
int
pppwrite(struct rtems_termios_tty *tty, rtems_libio_rw_args_t *rw_args)
{
    struct sockaddr               dst;
    int                           n;
    int                           len;
    int                           maximum    = rw_args->count;
    char                         *out_buffer = rw_args->buffer; 
    register struct ppp_softc    *sc         = (struct ppp_softc *)tty->t_sc;
    struct mbuf                  *m;
    struct mbuf                  *m0;
    struct mbuf                 **mp;

    rtems_bsdnet_semaphore_obtain();
    for (mp = &m0; maximum; mp = &m->m_next) {
	MGET(m, M_WAIT, MT_DATA);
	if ((*mp = m) == NULL) {
	    m_freem(m0);
	    return (ENOBUFS);
	}
	m->m_len = 0;
	if (maximum >= MCLBYTES / 2) {
	    MCLGET(m, M_DONTWAIT);
        }
	len = M_TRAILINGSPACE(m);
	if (len > maximum) {
          memcpy(mtod(m, u_char *),out_buffer,maximum);
          m->m_len = maximum;
          maximum  = 0;
        }
        else {
          memcpy(mtod(m, u_char *),out_buffer,len);
          m->m_len    = len;
          maximum    -= len;
          out_buffer += len;
        }
    }

    dst.sa_family = AF_UNSPEC;
    bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
    m0->m_data += PPP_HDRLEN;
    m0->m_len  -= PPP_HDRLEN;

    n = pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0);
    rtems_bsdnet_semaphore_release();

    return ( n );
}
Beispiel #30
0
static int
epe_intr(void *arg)
{
	struct epe_softc *sc = (struct epe_softc *)arg;
	struct ifnet * ifp = &sc->sc_ec.ec_if;
	uint32_t ndq = 0, irq, *cur;

	irq = EPE_READ(IntStsC);
begin:
	cur = (uint32_t *)(EPE_READ(RXStsQCurAdd) -
		sc->ctrlpage_dsaddr + (char*)sc->ctrlpage);
	CTRLPAGE_DMASYNC(TX_QLEN * 3 * sizeof(uint32_t),
		RX_QLEN * 4 * sizeof(uint32_t), 
		BUS_DMASYNC_PREREAD);
	while (sc->RXStsQ_cur != cur) {
		if ((sc->RXStsQ_cur[0] & (RXStsQ_RWE|RXStsQ_RFP|RXStsQ_EOB)) == 
			(RXStsQ_RWE|RXStsQ_RFP|RXStsQ_EOB)) {
			uint32_t bi = (sc->RXStsQ_cur[1] >> 16) & 0x7fff;
			uint32_t fl = sc->RXStsQ_cur[1] & 0xffff;
			struct mbuf *m;

			MGETHDR(m, M_DONTWAIT, MT_DATA);
			if (m != NULL) MCLGET(m, M_DONTWAIT);
			if (m != NULL && (m->m_flags & M_EXT)) {
				bus_dmamap_unload(sc->sc_dmat, 
					sc->rxq[bi].m_dmamap);
				sc->rxq[bi].m->m_pkthdr.rcvif = ifp;
				sc->rxq[bi].m->m_pkthdr.len = 
					sc->rxq[bi].m->m_len = fl;
				bpf_mtap(ifp, sc->rxq[bi].m);
                                (*ifp->if_input)(ifp, sc->rxq[bi].m);
				sc->rxq[bi].m = m;
				bus_dmamap_load(sc->sc_dmat, 
					sc->rxq[bi].m_dmamap, 
					m->m_ext.ext_buf, MCLBYTES,
					NULL, BUS_DMA_NOWAIT);
				sc->RXDQ[bi * 2] = 
					sc->rxq[bi].m_dmamap->dm_segs[0].ds_addr;
			} else {
				/* Drop packets until we can get replacement
				 * empty mbufs for the RXDQ.
				 */
				if (m != NULL) {
					m_freem(m);
				}
				ifp->if_ierrors++;
			} 
		} else {