Now that you’re familiar with the if* structures and their management routines, let’s go through an example. The following function, named em_setup_interface
and defined in /sys/dev/e1000/if_em.c, sets up em(4)
’s ifnet
and ifmedia
structures. (The em(4)
driver is for Intel’s PCI Gigabit Ethernet adapters.)
static int em_setup_interface(device_t dev, struct adapter *adapter) { struct ifnet *ifp; ifp = adapter->ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(dev, "cannot allocate ifnet structure "); return (-1); } if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_mtu = ETHERMTU; ifp->if_init = em_init; ifp->if_softc = adapter; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = em_ioctl; ifp->if_start = em_start; IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 1); ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 1; IFQ_SET_READY(&ifp->if_snd); ether_ifattach(ifp, adapter->hw.mac.addr); ifp->if_capabilities = ifp->if_capenable = 0; /* Enable checksum offload. */ ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; /* Enable TCP segmentation offload. */ ifp->if_capabilities |= IFCAP_TSO4; ifp->if_capenable |= IFCAP_TSO4; /* Enable VLAN support. */ ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; /* Interface can filter VLAN tags. */ ifp->if_capabilities |= IFCAP_VLAN_HWFILTER; #ifdef DEVICE_POLLING ifp->if_capabilities |= IFCAP_POLLING; #endif /* Enable Wake-on-LAN (WOL) via magic packet? */ if (adapter->wol) { ifp->if_capabilities |= IFCAP_WOL; ifp->if_capenable |= IFCAP_WOL_MAGIC; } ifmedia_init(&adapter->media, IFM_IMASK, em_media_change, em_media_status); if ((adapter->hw.phy.media_type == e1000_media_type_fiber) || (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) { u_char fiber_type = IFM_1000_SX; ifmedia_add(&adapter->media, IFM_ETHER | fiber_type, 0, NULL); ifmedia_add(&adapter->media, IFM_ETHER | fiber_type | IFM_FDX, 0, NULL); } else { ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T, 0, NULL); ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL); ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX, 0, NULL); ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL); if (adapter->hw.phy.type != e1000_phy_ife) { ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T, 0, NULL); ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL); } } ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL); ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); return (0); }
This function can be split into three parts. The first allocates an Ethernet-specific ifnet
structure and stores it in adapter->ifp
. Then adapter->ifp
is defined and activated. (Here, adapter is the name for em(4)’s softc structure.)
The second part outlines and enables the interface’s features, such as Wake-on-LAN (WOL). (WOL is an Ethernet standard that allows a computer to be turned on, or woken up, by a network message.)
The third part initializes an ifmedia
structure, adds the interface’s supported media to it, and defines the default media type as automatically select the best media.
Of course, em_setup_interface
is called during em(4)
’s device_attach
routine.
3.144.104.29