Ejemplo n.º 1
0
static int
fwip_attach(device_t dev)
{
	struct fwip_softc *fwip;
	struct ifnet *ifp;
	int unit, s;
	struct fw_hwaddr *hwaddr;

	fwip = ((struct fwip_softc *)device_get_softc(dev));
	unit = device_get_unit(dev);
	ifp = fwip->fw_softc.fwip_ifp = if_alloc(IFT_IEEE1394);
	if (ifp == NULL)
		return (ENOSPC);

	mtx_init(&fwip->mtx, "fwip", NULL, MTX_DEF);
	/* XXX */
	fwip->dma_ch = -1;

	fwip->fd.fc = device_get_ivars(dev);
	if (tx_speed < 0)
		tx_speed = fwip->fd.fc->speed;

	fwip->fd.dev = dev;
	fwip->fd.post_explore = NULL;
	fwip->fd.post_busreset = fwip_post_busreset;
	fwip->fw_softc.fwip = fwip;
	TASK_INIT(&fwip->start_send, 0, fwip_start_send, fwip);

	/*
	 * Encode our hardware the way that arp likes it.
	 */
	hwaddr = &IFP2FWC(fwip->fw_softc.fwip_ifp)->fc_hwaddr;
	hwaddr->sender_unique_ID_hi = htonl(fwip->fd.fc->eui.hi);
	hwaddr->sender_unique_ID_lo = htonl(fwip->fd.fc->eui.lo);
	hwaddr->sender_max_rec = fwip->fd.fc->maxrec;
	hwaddr->sspd = fwip->fd.fc->speed;
	hwaddr->sender_unicast_FIFO_hi = htons((uint16_t)(INET_FIFO >> 32));
	hwaddr->sender_unicast_FIFO_lo = htonl((uint32_t)INET_FIFO);

	/* fill the rest and attach interface */	
	ifp->if_softc = &fwip->fw_softc;

	if_initname(ifp, device_get_name(dev), unit);
	ifp->if_init = fwip_init;
	ifp->if_start = fwip_start;
	ifp->if_ioctl = fwip_ioctl;
	ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
	ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE;
#ifdef DEVICE_POLLING
	ifp->if_capabilities |= IFCAP_POLLING;
#endif

	s = splimp();
	firewire_ifattach(ifp, hwaddr);
	splx(s);

	FWIPDEBUG(ifp, "interface created\n");
	return 0;
}
Ejemplo n.º 2
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