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); }
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); }
/* * 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); }
/* * 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); }
/* * 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); }
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; }
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)); }
/* * 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; } }
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); }
/* * 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)); } }
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); }
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); }
/* * 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); }
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); }
/* * 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; }
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; }
/* 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); }
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; }
/* * 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 = ⊤ 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 = ⊤ 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; }
/* * 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); }
/*---------------------------------------------------------------------------* * 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); }
/* * 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); }
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; }
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; }
/* 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 ); }
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 {