Index: usb_ethernet.c =================================================================== --- usb_ethernet.c (revision 224468) +++ usb_ethernet.c (working copy) @@ -24,25 +24,33 @@ * SUCH DAMAGE. */ -#include -#include +#include +__FBSDID("$FreeBSD$"); + #include -#include -#include #include +#include +#include #include -#include +#include +#include +#include #include -#include #include -#include +#include +#include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include + +#include +#include + #include #include @@ -197,42 +205,53 @@ usb_callout_init_mtx(&ue->ue_watchdog, ue->ue_mtx, 0); sysctl_ctx_init(&ue->ue_sysctl_ctx); + error = 0; ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(ue->ue_dev, "could not allocate ifnet\n"); - goto error; + goto fail; } ifp->if_softc = ue; if_initname(ifp, "ue", ue->ue_unit); - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - if (ue->ue_methods->ue_ioctl != NULL) - ifp->if_ioctl = ue->ue_methods->ue_ioctl; - else - ifp->if_ioctl = uether_ioctl; - ifp->if_start = ue_start; - ifp->if_init = ue_init; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - ue->ue_ifp = ifp; + if (ue->ue_methods->ue_attach_post_sub != NULL) { + ue->ue_ifp = ifp; + error = ue->ue_methods->ue_attach_post_sub(ue); + } else { + ifp->if_mtu = ETHERMTU; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + if (ue->ue_methods->ue_ioctl != NULL) + ifp->if_ioctl = ue->ue_methods->ue_ioctl; + else + ifp->if_ioctl = uether_ioctl; + ifp->if_start = ue_start; + ifp->if_init = ue_init; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; + IFQ_SET_READY(&ifp->if_snd); + ue->ue_ifp = ifp; - if (ue->ue_methods->ue_mii_upd != NULL && - ue->ue_methods->ue_mii_sts != NULL) { - mtx_lock(&Giant); /* device_xxx() depends on this */ - error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, - ue_ifmedia_upd, ue->ue_methods->ue_mii_sts, - BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); - mtx_unlock(&Giant); - if (error) { - device_printf(ue->ue_dev, "attaching PHYs failed\n"); - goto error; + if (ue->ue_methods->ue_mii_upd != NULL && + ue->ue_methods->ue_mii_sts != NULL) { + /* device_xxx() depends on this */ + mtx_lock(&Giant); + error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, + ue_ifmedia_upd, ue->ue_methods->ue_mii_sts, + BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); + mtx_unlock(&Giant); } } + if (error) { + device_printf(ue->ue_dev, "attaching PHYs failed\n"); + goto fail; + } + if_printf(ifp, " on %s\n", device_get_nameunit(ue->ue_dev)); ether_ifattach(ifp, ue->ue_eaddr); + /* Tell upper layer we support VLAN oversized frames. */ + if (ifp->if_capabilities & IFCAP_VLAN_MTU) + ifp->if_hdrlen = sizeof(struct ether_vlan_header); snprintf(num, sizeof(num), "%u", ue->ue_unit); ue->ue_sysctl_oid = SYSCTL_ADD_NODE(&ue->ue_sysctl_ctx, @@ -246,7 +265,7 @@ UE_LOCK(ue); return; -error: +fail: free_unr(ueunit, ue->ue_unit); if (ue->ue_ifp != NULL) { if_free(ue->ue_ifp); @@ -307,6 +326,13 @@ return (usb_proc_is_gone(&ue->ue_tq)); } +void +uether_init(void *arg) +{ + + ue_init(arg); +} + static void ue_init(void *arg) { @@ -352,6 +378,13 @@ ue->ue_methods->ue_stop(ue); } +void +uether_start(struct ifnet *ifp) +{ + + ue_start(ifp); +} + static void ue_start(struct ifnet *ifp) { @@ -385,6 +418,13 @@ ue->ue_methods->ue_setmulti(ue); } +int +uether_ifmedia_upd(struct ifnet *ifp) +{ + + return (ue_ifmedia_upd(ifp)); +} + static int ue_ifmedia_upd(struct ifnet *ifp) { Index: usb_ethernet.h =================================================================== --- usb_ethernet.h (revision 224468) +++ usb_ethernet.h (working copy) @@ -22,6 +22,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ #ifndef _USB_ETHERNET_H_ @@ -66,7 +68,7 @@ void (*ue_mii_sts)(struct ifnet *, struct ifmediareq *); int (*ue_ioctl)(struct ifnet *, u_long, caddr_t); - + int (*ue_attach_post_sub)(struct usb_ether *); }; struct usb_ether_cfg_task { @@ -110,6 +112,8 @@ void *uether_getsc(struct usb_ether *); int uether_ifattach(struct usb_ether *); void uether_ifdetach(struct usb_ether *); +int uether_ifmedia_upd(struct ifnet *); +void uether_init(void *); int uether_ioctl(struct ifnet *, u_long, caddr_t); struct mbuf *uether_newbuf(void); int uether_rxmbuf(struct usb_ether *, struct mbuf *, @@ -119,4 +123,5 @@ unsigned int, unsigned int); void uether_rxflush(struct usb_ether *); uint8_t uether_is_gone(struct usb_ether *); +void uether_start(struct ifnet *); #endif /* _USB_ETHERNET_H_ */