Example #1
0
static int
pqmdio_fdt_attach(device_t dev)
{
	struct pqmdio_softc *sc;
	rman_res_t start, count;

	sc = device_get_softc(dev);

	fman_get_bushandle(&sc->sc_handle);
	bus_get_resource(dev, SYS_RES_MEMORY, 0, &start, &count);
	sc->sc_offset = start;

	mtx_init(&sc->sc_lock, device_get_nameunit(dev), "QorIQ MDIO lock",
	    MTX_DEF);

	return (0);
}
Example #2
0
int
dtsec_attach(device_t dev)
{
	struct dtsec_softc *sc;
	int error;
	struct ifnet *ifp;

	sc = device_get_softc(dev);

	sc->sc_dev = dev;
	sc->sc_mac_mdio_irq = NO_IRQ;
	sc->sc_eth_id = device_get_unit(dev);


	/* Check if MallocSmart allocator is ready */
	if (XX_MallocSmartInit() != E_OK)
		return (ENXIO);

	XX_TrackInit();

	/* Init locks */
	mtx_init(&sc->sc_lock, device_get_nameunit(dev),
	    "DTSEC Global Lock", MTX_DEF);

	mtx_init(&sc->sc_mii_lock, device_get_nameunit(dev),
	    "DTSEC MII Lock", MTX_DEF);

	/* Init callouts */
	callout_init(&sc->sc_tick_callout, CALLOUT_MPSAFE);

	/* Read configuraton */
	if ((error = fman_get_handle(&sc->sc_fmh)) != 0)
		return (error);

	if ((error = fman_get_muram_handle(&sc->sc_muramh)) != 0)
		return (error);

	if ((error = fman_get_bushandle(&sc->sc_fm_base)) != 0)
		return (error);

	/* Configure working mode */
	dtsec_configure_mode(sc);

	/* If we are working in regular mode configure BMAN and QMAN */
	if (sc->sc_mode == DTSEC_MODE_REGULAR) {
		/* Create RX buffer pool */
		error = dtsec_rm_pool_rx_init(sc);
		if (error != 0)
			return (EIO);

		/* Create RX frame queue range */
		error = dtsec_rm_fqr_rx_init(sc);
		if (error != 0)
			return (EIO);

		/* Create frame info pool */
		error = dtsec_rm_fi_pool_init(sc);
		if (error != 0)
			return (EIO);

		/* Create TX frame queue range */
		error = dtsec_rm_fqr_tx_init(sc);
		if (error != 0)
			return (EIO);
	}

	/* Init FMan MAC module. */
	error = dtsec_fm_mac_init(sc, sc->sc_mac_addr);
	if (error != 0) {
		dtsec_detach(dev);
		return (ENXIO);
	}

	/*
	 * XXX: All phys are connected to MDIO interface of the first dTSEC
	 * device (dTSEC0). We have to save handle to the FM_MAC instance of
	 * dTSEC0, which is used later during phy's registers accesses. Another
	 * option would be adding new property to DTS pointing to correct dTSEC
	 * instance, of which FM_MAC handle has to be used for phy's registers
	 * accesses. We did not want to add new properties to DTS, thus this
	 * quite ugly hack.
	 */
	if (sc->sc_eth_id == 0)
		dtsec_mdio_mac_handle = sc->sc_mach;
	if (sc->sc_hidden)
		return (0);

	/* Init FMan TX port */
	error = sc->sc_port_tx_init(sc, device_get_unit(sc->sc_dev));
	if (error != 0) {
		dtsec_detach(dev);
		return (ENXIO);
	}

	/* Init FMan RX port */
	error = sc->sc_port_rx_init(sc, device_get_unit(sc->sc_dev));
	if (error != 0) {
		dtsec_detach(dev);
		return (ENXIO);
	}

	/* Create network interface for upper layers */
	ifp = sc->sc_ifnet = if_alloc(IFT_ETHER);
	if (ifp == NULL) {
		device_printf(sc->sc_dev, "if_alloc() failed.\n");
		dtsec_detach(dev);
		return (ENOMEM);
	}

	ifp->if_softc = sc;
	ifp->if_mtu = ETHERMTU;	/* TODO: Configure */
	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST;
	ifp->if_init = dtsec_if_init;
	ifp->if_start = dtsec_if_start;
	ifp->if_ioctl = dtsec_if_ioctl;
	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;

	if (sc->sc_phy_addr >= 0)
		if_initname(ifp, device_get_name(sc->sc_dev),
		    device_get_unit(sc->sc_dev));
	else
		if_initname(ifp, "dtsec_phy", device_get_unit(sc->sc_dev));

	/* TODO */
#if 0
	IFQ_SET_MAXLEN(&ifp->if_snd, TSEC_TX_NUM_DESC - 1);
	ifp->if_snd.ifq_drv_maxlen = TSEC_TX_NUM_DESC - 1;
	IFQ_SET_READY(&ifp->if_snd);
#endif
	ifp->if_capabilities = 0; /* TODO: Check */
	ifp->if_capenable = ifp->if_capabilities;

	/* Attach PHY(s) */
	error = mii_attach(sc->sc_dev, &sc->sc_mii_dev, ifp, dtsec_ifmedia_upd,
	    dtsec_ifmedia_sts, BMSR_DEFCAPMASK, sc->sc_phy_addr,
	    MII_OFFSET_ANY, 0);
	if (error) {
		device_printf(sc->sc_dev, "attaching PHYs failed: %d\n", error);
		dtsec_detach(sc->sc_dev);
		return (error);
	}
	sc->sc_mii = device_get_softc(sc->sc_mii_dev);

	/* Attach to stack */
	ether_ifattach(ifp, sc->sc_mac_addr);

	return (0);
}