FreeBSD/sys/dev/cs/if_cs.c
/*
 * Install the interface into kernel networking data structures
 */
Install the interface into kernel networking data structures
Install the interface into kernel networking data structures
int
cs_attach(device_t dev)
{
	int error, media=0;
	struct cs_softc *sc = device_get_softc(dev);
	struct ifnet *ifp;
	sc->dev = dev;
	ifp = sc->ifp = if_alloc(IFT_ETHER);
	if (ifp == NULL) {
		device_printf(dev, "can not if_alloc()\n");
		cs_release_resources(dev);
		return (ENOMEM);
	}
	mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK,
	    MTX_DEF);
	callout_init_mtx(&sc->timer, &sc->lock, 0);
	CS_LOCK(sc);
	cs_stop(sc);
	CS_UNLOCK(sc);
	ifp->if_softc=sc;
	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
	ifp->if_start=cs_start;
	ifp->if_ioctl=cs_ioctl;
	ifp->if_init=cs_init;
	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
	ifp->if_flags=(IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
	sc->buffer=malloc(ETHER_MAX_LEN-ETHER_CRC_LEN,M_DEVBUF,M_NOWAIT);
	if (sc->buffer == NULL) {
		device_printf(sc->dev, "Couldn't allocate memory for NIC\n");
		if_free(ifp);
		mtx_destroy(&sc->lock);
		cs_release_resources(dev);
		return(ENOMEM);
	}
	ifmedia_init(&sc->media, 0, cs_mediachange, cs_mediastatus);
	if (sc->adapter_cnf & A_CNF_10B_T) {
		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL);
		if (sc->chip_type != CS8900) {
			ifmedia_add(&sc->media,
				IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
			ifmedia_add(&sc->media,
				IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
		}
	} 
	if (sc->adapter_cnf & A_CNF_10B_2)
		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_2, 0, NULL);
	if (sc->adapter_cnf & A_CNF_AUI)
		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_5, 0, NULL);
	if (sc->adapter_cnf & A_CNF_MEDIA)
		ifmedia_add(&sc->media, IFM_ETHER|IFM_AUTO, 0, NULL);
	switch (sc->adapter_cnf & A_CNF_MEDIA_TYPE) {
	case A_CNF_MEDIA_AUTO:  media = IFM_ETHER|IFM_AUTO; break;
	case A_CNF_MEDIA_10B_T: media = IFM_ETHER|IFM_10_T; break;
	case A_CNF_MEDIA_10B_2: media = IFM_ETHER|IFM_10_2; break;
	case A_CNF_MEDIA_AUI:   media = IFM_ETHER|IFM_10_5; break;
	default:
		device_printf(sc->dev, "no media, assuming 10baseT\n");
		sc->adapter_cnf |= A_CNF_10B_T;
		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL);
		if (sc->chip_type != CS8900) {
			ifmedia_add(&sc->media,
			    IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
			ifmedia_add(&sc->media,
			    IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
		}
		media = IFM_ETHER | IFM_10_T;
		break;
	}
	ifmedia_set(&sc->media, media);
	cs_mediaset(sc, media);
	ether_ifattach(ifp, sc->enaddr);
  	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
	    NULL, csintr, sc, &sc->irq_handle);
	if (error) {
		ether_ifdetach(ifp);
		free(sc->buffer, M_DEVBUF);
		if_free(ifp);
		mtx_destroy(&sc->lock);
		cs_release_resources(dev);
		return (error);
	}
	return (0);
}
int cs_attach ( device_t dev ) { int error , media = 0 ; struct cs_softc * sc = device_get_softc ( dev ) ; struct ifnet * ifp ; sc -> dev = dev ; ifp = sc -> ifp = if_alloc ( IFT_ETHER ) ; if ( ifp == NULL ) { device_printf ( dev , " \n " ) ; cs_release_resources ( dev ) ; return ( ENOMEM ) ; } mtx_init ( & sc -> lock , device_get_nameunit ( dev ) , MTX_NETWORK_LOCK , MTX_DEF ) ; callout_init_mtx ( & sc -> timer , & sc -> lock , 0 ) ; CS_LOCK ( sc ) ; cs_stop ( sc ) ; CS_UNLOCK ( sc ) ; ifp -> if_softc = sc ; if_initname ( ifp , device_get_name ( dev ) , device_get_unit ( dev ) ) ; ifp -> if_start = cs_start ; ifp -> if_ioctl = cs_ioctl ; ifp -> if_init = cs_init ; IFQ_SET_MAXLEN ( & ifp -> if_snd , ifqmaxlen ) ; ifp -> if_flags = ( IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST ) ; sc -> buffer = malloc ( ETHER_MAX_LEN - ETHER_CRC_LEN , M_DEVBUF , M_NOWAIT ) ; if ( sc -> buffer == NULL ) { device_printf ( sc -> dev , " \n " ) ; if_free ( ifp ) ; mtx_destroy ( & sc -> lock ) ; cs_release_resources ( dev ) ; return ( ENOMEM ) ; } ifmedia_init ( & sc -> media , 0 , cs_mediachange , cs_mediastatus ) ; if ( sc -> adapter_cnf & A_CNF_10B_T ) { ifmedia_add ( & sc -> media , IFM_ETHER | IFM_10_T , 0 , NULL ) ; if ( sc -> chip_type != CS8900 ) { ifmedia_add ( & sc -> media , IFM_ETHER | IFM_10_T | IFM_FDX , 0 , NULL ) ; ifmedia_add ( & sc -> media , IFM_ETHER | IFM_10_T | IFM_HDX , 0 , NULL ) ; } } if ( sc -> adapter_cnf & A_CNF_10B_2 ) ifmedia_add ( & sc -> media , IFM_ETHER | IFM_10_2 , 0 , NULL ) ; if ( sc -> adapter_cnf & A_CNF_AUI ) ifmedia_add ( & sc -> media , IFM_ETHER | IFM_10_5 , 0 , NULL ) ; if ( sc -> adapter_cnf & A_CNF_MEDIA ) ifmedia_add ( & sc -> media , IFM_ETHER | IFM_AUTO , 0 , NULL ) ; switch ( sc -> adapter_cnf & A_CNF_MEDIA_TYPE ) { case A_CNF_MEDIA_AUTO : media = IFM_ETHER | IFM_AUTO ; break ; case A_CNF_MEDIA_10B_T : media = IFM_ETHER | IFM_10_T ; break ; case A_CNF_MEDIA_10B_2 : media = IFM_ETHER | IFM_10_2 ; break ; case A_CNF_MEDIA_AUI : media = IFM_ETHER | IFM_10_5 ; break ; default : device_printf ( sc -> dev , " \n " ) ; sc -> adapter_cnf |= A_CNF_10B_T ; ifmedia_add ( & sc -> media , IFM_ETHER | IFM_10_T , 0 , NULL ) ; if ( sc -> chip_type != CS8900 ) { ifmedia_add ( & sc -> media , IFM_ETHER | IFM_10_T | IFM_FDX , 0 , NULL ) ; ifmedia_add ( & sc -> media , IFM_ETHER | IFM_10_T | IFM_HDX , 0 , NULL ) ; } media = IFM_ETHER | IFM_10_T ; break ; } ifmedia_set ( & sc -> media , media ) ; cs_mediaset ( sc , media ) ; ether_ifattach ( ifp , sc -> enaddr ) ; error = bus_setup_intr ( dev , sc -> irq_res , INTR_TYPE_NET | INTR_MPSAFE , NULL , csintr , sc , & sc -> irq_handle ) ; if ( error ) { ether_ifdetach ( ifp ) ; free ( sc -> buffer , M_DEVBUF ) ; if_free ( ifp ) ; mtx_destroy ( & sc -> lock ) ; cs_release_resources ( dev ) ; return ( error ) ; } return ( 0 ) ; }
Install the interface into kernel networking data structures
Install the interface into kernel networking data structures
/*
	 * this code still in progress (DMA support)
	 *

	sc->recv_ring=malloc(CS_DMA_BUFFER_SIZE<<1, M_DEVBUF, M_NOWAIT);
	if (sc->recv_ring == NULL) {
		log(LOG_ERR,
		"%s: Couldn't allocate memory for NIC\n", ifp->if_xname);
		return(0);
	}
	if ((sc->recv_ring-(sc->recv_ring & 0x1FFFF))
	    < (128*1024-CS_DMA_BUFFER_SIZE))
	    sc->recv_ring+=16*1024;

	*/ /*
	 * Initialize the media structures.
	 */ /* Set default media from EEPROM */