Ejemplo n.º 1
0
static struct fw_xfer *
fwmem_xfer_req(
	struct fw_device *fwdev,
	caddr_t sc,
	int spd,
	int slen,
	int rlen,
	void *hand)
{
	struct fw_xfer *xfer;

	xfer = fw_xfer_alloc(M_FWMEM);
	if (xfer == NULL)
		return NULL;

	xfer->fc = fwdev->fc;
	xfer->send.hdr.mode.hdr.dst = FWLOCALBUS | fwdev->dst;
	if (spd < 0)
		xfer->send.spd = fwdev->speed;
	else
		xfer->send.spd = min(spd, fwdev->speed);
	xfer->hand = hand;
	xfer->sc = sc;
	xfer->send.pay_len = slen;
	xfer->recv.pay_len = rlen;

	return xfer;
}
Ejemplo n.º 2
0
/* Async. stream output */
static void
fwe_as_output(struct fwe_softc *fwe, struct ifnet *ifp)
{
	struct mbuf *m;
	struct fw_xfer *xfer;
	struct fw_xferq *xferq;
	struct fw_pkt *fp;
	int i = 0;

	xfer = NULL;
	xferq = fwe->fd.fc->atq;
	while (xferq->queued < xferq->maxq) {
		IF_DEQUEUE(&ifp->if_snd, m);
		if (m == NULL)
			break;
		xfer = fw_xfer_alloc();
		if (xfer == NULL) {
			return;
		}
#if __FreeBSD_version >= 500000
		BPF_MTAP(ifp, m);
#else
		if (ifp->if_bpf != NULL)
			bpf_mtap(ifp, m);
#endif

		xfer->send.off = 0;
		xfer->spd = 2;
		xfer->fc = fwe->fd.fc;
		xfer->retry_req = fw_asybusy;
		xfer->sc = (caddr_t)fwe;
		xfer->act.hand = fwe_output_callback;

		/* keep ip packet alignment for alpha */
		M_PREPEND(m, ALIGN_PAD, M_DONTWAIT);
		fp = (struct fw_pkt *)&xfer->dst; /* XXX */
		xfer->dst = *((int32_t *)&fwe->pkt_hdr);
		fp->mode.stream.len = htons(m->m_pkthdr.len);
		xfer->send.buf = (caddr_t) fp;
		xfer->mbuf = m;
		xfer->send.len = m->m_pkthdr.len + HDR_LEN;

		i++;
		if (fw_asyreq(xfer->fc, -1, xfer) != 0) {
			/* error */
			ifp->if_oerrors ++;
			/* XXX set error code */
			fwe_output_callback(xfer);
		} else {
			ifp->if_opackets ++;
		}
	}
#if 0
	if (i > 1)
		printf("%d queued\n", i);
#endif
	if (xfer != NULL)
		xferq->start(xfer->fc);
}
Ejemplo n.º 3
0
static void
fwe_init(void *arg)
{
	struct fwe_softc *fwe = ((struct fwe_eth_softc *)arg)->fwe;
	struct firewire_comm *fc;
	struct ifnet *ifp = fwe->eth_softc.ifp;
	struct fw_xferq *xferq;
	struct fw_xfer *xfer;
	struct mbuf *m;
	int i;

	FWEDEBUG(ifp, "initializing\n");

	/* XXX keep promiscoud mode */
	ifp->if_flags |= IFF_PROMISC;

	fc = fwe->fd.fc;
	if (fwe->dma_ch < 0) {
		fwe->dma_ch = fw_open_isodma(fc, /* tx */0);
		if (fwe->dma_ch < 0)
			return;
		xferq = fc->ir[fwe->dma_ch];
		xferq->flag |= FWXFERQ_EXTBUF |
				FWXFERQ_HANDLER | FWXFERQ_STREAM;
		fwe->stream_ch = stream_ch;
		fwe->pkt_hdr.mode.stream.chtag = fwe->stream_ch;
		xferq->flag &= ~0xff;
		xferq->flag |= fwe->stream_ch & 0xff;
		/* register fwe_input handler */
		xferq->sc = (caddr_t) fwe;
		xferq->hand = fwe_as_input;
		xferq->bnchunk = rx_queue_len;
		xferq->bnpacket = 1;
		xferq->psize = MCLBYTES;
		xferq->queued = 0;
		xferq->buf = NULL;
		xferq->bulkxfer = (struct fw_bulkxfer *) malloc(
			sizeof(struct fw_bulkxfer) * xferq->bnchunk,
							M_FWE, M_WAITOK);
		if (xferq->bulkxfer == NULL) {
			printf("if_fwe: malloc failed\n");
			return;
		}
		STAILQ_INIT(&xferq->stvalid);
		STAILQ_INIT(&xferq->stfree);
		STAILQ_INIT(&xferq->stdma);
		xferq->stproc = NULL;
		for (i = 0; i < xferq->bnchunk; i ++) {
			m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
			xferq->bulkxfer[i].mbuf = m;
			m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
			STAILQ_INSERT_TAIL(&xferq->stfree,
					&xferq->bulkxfer[i], link);
		}
		STAILQ_INIT(&fwe->xferlist);
		for (i = 0; i < TX_MAX_QUEUE; i++) {
			xfer = fw_xfer_alloc(M_FWE);
			if (xfer == NULL)
				break;
			xfer->send.spd = tx_speed;
			xfer->fc = fwe->fd.fc;
			xfer->sc = (caddr_t)fwe;
			xfer->hand = fwe_output_callback;
			STAILQ_INSERT_TAIL(&fwe->xferlist, xfer, link);
		}
	} else
		xferq = fc->ir[fwe->dma_ch];


	/* start dma */
	if ((xferq->flag & FWXFERQ_RUNNING) == 0)
		fc->irx_enable(fc, fwe->dma_ch);

#if defined(__FreeBSD__)
	ifp->if_drv_flags |= IFF_DRV_RUNNING;
	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
#else
	ifp->if_flags |= IFF_RUNNING;
	ifp->if_flags &= ~IFF_OACTIVE;
#endif

#if 0
	/* attempt to start output */
	fwe_start(ifp);
#endif
}
Ejemplo n.º 4
0
static void
fwip_init(void *arg)
{
	struct fwip_softc *fwip = ((struct fwip_eth_softc *)arg)->fwip;
	struct firewire_comm *fc;
	struct ifnet *ifp = fwip->fw_softc.fwip_ifp;
	struct fw_xferq *xferq;
	struct fw_xfer *xfer;
	struct mbuf *m;
	int i;

	FWIPDEBUG(ifp, "initializing\n");

	fc = fwip->fd.fc;
#define START 0
	if (fwip->dma_ch < 0) {
		fwip->dma_ch = fw_open_isodma(fc, /* tx */0);
		if (fwip->dma_ch < 0)
			return;
		xferq = fc->ir[fwip->dma_ch];
		xferq->flag |= FWXFERQ_EXTBUF |
				FWXFERQ_HANDLER | FWXFERQ_STREAM;
		xferq->flag &= ~0xff;
		xferq->flag |= broadcast_channel & 0xff;
		/* register fwip_input handler */
		xferq->sc = (caddr_t) fwip;
		xferq->hand = fwip_stream_input;
		xferq->bnchunk = rx_queue_len;
		xferq->bnpacket = 1;
		xferq->psize = MCLBYTES;
		xferq->queued = 0;
		xferq->buf = NULL;
		xferq->bulkxfer = (struct fw_bulkxfer *) malloc(
			sizeof(struct fw_bulkxfer) * xferq->bnchunk,
							M_FWIP, M_WAITOK);
		if (xferq->bulkxfer == NULL) {
			printf("if_fwip: malloc failed\n");
			return;
		}
		STAILQ_INIT(&xferq->stvalid);
		STAILQ_INIT(&xferq->stfree);
		STAILQ_INIT(&xferq->stdma);
		xferq->stproc = NULL;
		for (i = 0; i < xferq->bnchunk; i ++) {
			m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
			xferq->bulkxfer[i].mbuf = m;
			m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
			STAILQ_INSERT_TAIL(&xferq->stfree,
					&xferq->bulkxfer[i], link);
		}

		fwip->fwb.start = INET_FIFO;
		fwip->fwb.end = INET_FIFO + 16384; /* S3200 packet size */

		/* pre-allocate xfer */
		STAILQ_INIT(&fwip->fwb.xferlist);
		for (i = 0; i < rx_queue_len; i ++) {
			xfer = fw_xfer_alloc(M_FWIP);
			if (xfer == NULL)
				break;
			m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
			xfer->recv.payload = mtod(m, uint32_t *);
			xfer->recv.pay_len = MCLBYTES;
			xfer->hand = fwip_unicast_input;
			xfer->fc = fc;
			xfer->sc = (caddr_t)fwip;
			xfer->mbuf = m;
			STAILQ_INSERT_TAIL(&fwip->fwb.xferlist, xfer, link);
		}
		fw_bindadd(fc, &fwip->fwb);

		STAILQ_INIT(&fwip->xferlist);
		for (i = 0; i < TX_MAX_QUEUE; i++) {
			xfer = fw_xfer_alloc(M_FWIP);
			if (xfer == NULL)
				break;
			xfer->send.spd = tx_speed;
			xfer->fc = fwip->fd.fc;
			xfer->sc = (caddr_t)fwip;
			xfer->hand = fwip_output_callback;
			STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link);
		}
	} else