The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/net/usb_ethernet.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $FreeBSD$ */
    2 /*-
    3  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    4  *
    5  * Copyright (c) 2009 Andrew Thompson (thompsa@FreeBSD.org)
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/bus.h>
   35 #include <sys/condvar.h>
   36 #include <sys/kernel.h>
   37 #include <sys/lock.h>
   38 #include <sys/malloc.h>
   39 #include <sys/mbuf.h>
   40 #include <sys/module.h>
   41 #include <sys/mutex.h>
   42 #include <sys/socket.h>
   43 #include <sys/sockio.h>
   44 #include <sys/sysctl.h>
   45 #include <sys/sx.h>
   46 
   47 #include <net/if.h>
   48 #include <net/if_var.h>
   49 #include <net/ethernet.h>
   50 #include <net/if_types.h>
   51 #include <net/if_media.h>
   52 #include <net/if_vlan_var.h>
   53 
   54 #include <dev/mii/mii.h>
   55 #include <dev/mii/miivar.h>
   56 
   57 #include <dev/usb/usb.h>
   58 #include <dev/usb/usbdi.h>
   59 
   60 #include <dev/usb/usb_process.h>
   61 #include <dev/usb/net/usb_ethernet.h>
   62 
   63 static SYSCTL_NODE(_net, OID_AUTO, ue, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
   64     "USB Ethernet parameters");
   65 
   66 #define UE_LOCK(_ue)            mtx_lock((_ue)->ue_mtx)
   67 #define UE_UNLOCK(_ue)          mtx_unlock((_ue)->ue_mtx)
   68 #define UE_LOCK_ASSERT(_ue, t)  mtx_assert((_ue)->ue_mtx, t)
   69 
   70 MODULE_DEPEND(uether, usb, 1, 1, 1);
   71 MODULE_DEPEND(uether, miibus, 1, 1, 1);
   72 
   73 static struct unrhdr *ueunit;
   74 
   75 static usb_proc_callback_t ue_attach_post_task;
   76 static usb_proc_callback_t ue_promisc_task;
   77 static usb_proc_callback_t ue_setmulti_task;
   78 static usb_proc_callback_t ue_ifmedia_task;
   79 static usb_proc_callback_t ue_tick_task;
   80 static usb_proc_callback_t ue_start_task;
   81 static usb_proc_callback_t ue_stop_task;
   82 
   83 static void     ue_init(void *);
   84 static void     ue_start(struct ifnet *);
   85 static int      ue_ifmedia_upd(struct ifnet *);
   86 static void     ue_watchdog(void *);
   87 
   88 /*
   89  * Return values:
   90  *    0: success
   91  * Else: device has been detached
   92  */
   93 uint8_t
   94 uether_pause(struct usb_ether *ue, unsigned _ticks)
   95 {
   96         if (usb_proc_is_gone(&ue->ue_tq)) {
   97                 /* nothing to do */
   98                 return (1);
   99         }
  100         usb_pause_mtx(ue->ue_mtx, _ticks);
  101         return (0);
  102 }
  103 
  104 static void
  105 ue_queue_command(struct usb_ether *ue,
  106     usb_proc_callback_t *fn,
  107     struct usb_proc_msg *t0, struct usb_proc_msg *t1)
  108 {
  109         struct usb_ether_cfg_task *task;
  110 
  111         UE_LOCK_ASSERT(ue, MA_OWNED);
  112 
  113         if (usb_proc_is_gone(&ue->ue_tq)) {
  114                 return;         /* nothing to do */
  115         }
  116         /* 
  117          * NOTE: The task cannot get executed before we drop the
  118          * "sc_mtx" mutex. It is safe to update fields in the message
  119          * structure after that the message got queued.
  120          */
  121         task = (struct usb_ether_cfg_task *)
  122           usb_proc_msignal(&ue->ue_tq, t0, t1);
  123 
  124         /* Setup callback and self pointers */
  125         task->hdr.pm_callback = fn;
  126         task->ue = ue;
  127 
  128         /*
  129          * Start and stop must be synchronous!
  130          */
  131         if ((fn == ue_start_task) || (fn == ue_stop_task))
  132                 usb_proc_mwait(&ue->ue_tq, t0, t1);
  133 }
  134 
  135 struct ifnet *
  136 uether_getifp(struct usb_ether *ue)
  137 {
  138         return (ue->ue_ifp);
  139 }
  140 
  141 struct mii_data *
  142 uether_getmii(struct usb_ether *ue)
  143 {
  144         return (device_get_softc(ue->ue_miibus));
  145 }
  146 
  147 void *
  148 uether_getsc(struct usb_ether *ue)
  149 {
  150         return (ue->ue_sc);
  151 }
  152 
  153 static int
  154 ue_sysctl_parent(SYSCTL_HANDLER_ARGS)
  155 {
  156         struct usb_ether *ue = arg1;
  157         const char *name;
  158 
  159         name = device_get_nameunit(ue->ue_dev);
  160         return SYSCTL_OUT_STR(req, name);
  161 }
  162 
  163 int
  164 uether_ifattach(struct usb_ether *ue)
  165 {
  166         int error;
  167 
  168         /* check some critical parameters */
  169         if ((ue->ue_dev == NULL) ||
  170             (ue->ue_udev == NULL) ||
  171             (ue->ue_mtx == NULL) ||
  172             (ue->ue_methods == NULL))
  173                 return (EINVAL);
  174 
  175         error = usb_proc_create(&ue->ue_tq, ue->ue_mtx, 
  176             device_get_nameunit(ue->ue_dev), USB_PRI_MED);
  177         if (error) {
  178                 device_printf(ue->ue_dev, "could not setup taskqueue\n");
  179                 goto error;
  180         }
  181 
  182         /* fork rest of the attach code */
  183         UE_LOCK(ue);
  184         ue_queue_command(ue, ue_attach_post_task,
  185             &ue->ue_sync_task[0].hdr,
  186             &ue->ue_sync_task[1].hdr);
  187         UE_UNLOCK(ue);
  188 
  189 error:
  190         return (error);
  191 }
  192 
  193 void
  194 uether_ifattach_wait(struct usb_ether *ue)
  195 {
  196 
  197         UE_LOCK(ue);
  198         usb_proc_mwait(&ue->ue_tq,
  199             &ue->ue_sync_task[0].hdr,
  200             &ue->ue_sync_task[1].hdr);
  201         UE_UNLOCK(ue);
  202 }
  203 
  204 static void
  205 ue_attach_post_task(struct usb_proc_msg *_task)
  206 {
  207         struct usb_ether_cfg_task *task =
  208             (struct usb_ether_cfg_task *)_task;
  209         struct usb_ether *ue = task->ue;
  210         struct ifnet *ifp;
  211         int error;
  212         char num[14];                   /* sufficient for 32 bits */
  213 
  214         /* first call driver's post attach routine */
  215         ue->ue_methods->ue_attach_post(ue);
  216 
  217         UE_UNLOCK(ue);
  218 
  219         ue->ue_unit = alloc_unr(ueunit);
  220         usb_callout_init_mtx(&ue->ue_watchdog, ue->ue_mtx, 0);
  221         sysctl_ctx_init(&ue->ue_sysctl_ctx);
  222         mbufq_init(&ue->ue_rxq, 0 /* unlimited length */);
  223 
  224         error = 0;
  225         CURVNET_SET_QUIET(vnet0);
  226         ifp = if_alloc(IFT_ETHER);
  227         if (ifp == NULL) {
  228                 device_printf(ue->ue_dev, "could not allocate ifnet\n");
  229                 goto fail;
  230         }
  231 
  232         ifp->if_softc = ue;
  233         if_initname(ifp, "ue", ue->ue_unit);
  234         if (ue->ue_methods->ue_attach_post_sub != NULL) {
  235                 ue->ue_ifp = ifp;
  236                 error = ue->ue_methods->ue_attach_post_sub(ue);
  237         } else {
  238                 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  239                 if (ue->ue_methods->ue_ioctl != NULL)
  240                         ifp->if_ioctl = ue->ue_methods->ue_ioctl;
  241                 else
  242                         ifp->if_ioctl = uether_ioctl;
  243                 ifp->if_start = ue_start;
  244                 ifp->if_init = ue_init;
  245                 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
  246                 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
  247                 IFQ_SET_READY(&ifp->if_snd);
  248                 ue->ue_ifp = ifp;
  249 
  250                 if (ue->ue_methods->ue_mii_upd != NULL &&
  251                     ue->ue_methods->ue_mii_sts != NULL) {
  252                         bus_topo_lock();
  253                         error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp,
  254                             ue_ifmedia_upd, ue->ue_methods->ue_mii_sts,
  255                             BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0);
  256                         bus_topo_unlock();
  257                 }
  258         }
  259 
  260         if (error) {
  261                 device_printf(ue->ue_dev, "attaching PHYs failed\n");
  262                 goto fail;
  263         }
  264 
  265         if_printf(ifp, "<USB Ethernet> on %s\n", device_get_nameunit(ue->ue_dev));
  266         ether_ifattach(ifp, ue->ue_eaddr);
  267         /* Tell upper layer we support VLAN oversized frames. */
  268         if (ifp->if_capabilities & IFCAP_VLAN_MTU)
  269                 ifp->if_hdrlen = sizeof(struct ether_vlan_header);
  270 
  271         CURVNET_RESTORE();
  272 
  273         snprintf(num, sizeof(num), "%u", ue->ue_unit);
  274         ue->ue_sysctl_oid = SYSCTL_ADD_NODE(&ue->ue_sysctl_ctx,
  275             &SYSCTL_NODE_CHILDREN(_net, ue),
  276             OID_AUTO, num, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "");
  277         SYSCTL_ADD_PROC(&ue->ue_sysctl_ctx,
  278             SYSCTL_CHILDREN(ue->ue_sysctl_oid), OID_AUTO, "%parent",
  279             CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, ue, 0,
  280             ue_sysctl_parent, "A", "parent device");
  281 
  282         UE_LOCK(ue);
  283         return;
  284 
  285 fail:
  286         CURVNET_RESTORE();
  287 
  288         /* drain mbuf queue */
  289         mbufq_drain(&ue->ue_rxq);
  290 
  291         /* free unit */
  292         free_unr(ueunit, ue->ue_unit);
  293         if (ue->ue_ifp != NULL) {
  294                 if_free(ue->ue_ifp);
  295                 ue->ue_ifp = NULL;
  296         }
  297         UE_LOCK(ue);
  298         return;
  299 }
  300 
  301 void
  302 uether_ifdetach(struct usb_ether *ue)
  303 {
  304         struct ifnet *ifp;
  305 
  306         /* wait for any post attach or other command to complete */
  307         usb_proc_drain(&ue->ue_tq);
  308 
  309         /* read "ifnet" pointer after taskqueue drain */
  310         ifp = ue->ue_ifp;
  311 
  312         if (ifp != NULL) {
  313                 /* we are not running any more */
  314                 UE_LOCK(ue);
  315                 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
  316                 UE_UNLOCK(ue);
  317 
  318                 /* drain any callouts */
  319                 usb_callout_drain(&ue->ue_watchdog);
  320 
  321                 /*
  322                  * Detach ethernet first to stop miibus calls from
  323                  * user-space:
  324                  */
  325                 ether_ifdetach(ifp);
  326 
  327                 /* detach miibus */
  328                 if (ue->ue_miibus != NULL) {
  329                         bus_topo_lock();
  330                         device_delete_child(ue->ue_dev, ue->ue_miibus);
  331                         bus_topo_unlock();
  332                 }
  333 
  334                 /* free interface instance */
  335                 if_free(ifp);
  336 
  337                 /* free sysctl */
  338                 sysctl_ctx_free(&ue->ue_sysctl_ctx);
  339 
  340                 /* drain mbuf queue */
  341                 mbufq_drain(&ue->ue_rxq);
  342 
  343                 /* free unit */
  344                 free_unr(ueunit, ue->ue_unit);
  345         }
  346 
  347         /* free taskqueue, if any */
  348         usb_proc_free(&ue->ue_tq);
  349 }
  350 
  351 uint8_t
  352 uether_is_gone(struct usb_ether *ue)
  353 {
  354         return (usb_proc_is_gone(&ue->ue_tq));
  355 }
  356 
  357 void
  358 uether_init(void *arg)
  359 {
  360 
  361         ue_init(arg);
  362 }
  363 
  364 static void
  365 ue_init(void *arg)
  366 {
  367         struct usb_ether *ue = arg;
  368 
  369         UE_LOCK(ue);
  370         ue_queue_command(ue, ue_start_task,
  371             &ue->ue_sync_task[0].hdr, 
  372             &ue->ue_sync_task[1].hdr);
  373         UE_UNLOCK(ue);
  374 }
  375 
  376 static void
  377 ue_start_task(struct usb_proc_msg *_task)
  378 {
  379         struct usb_ether_cfg_task *task =
  380             (struct usb_ether_cfg_task *)_task;
  381         struct usb_ether *ue = task->ue;
  382         struct ifnet *ifp = ue->ue_ifp;
  383 
  384         UE_LOCK_ASSERT(ue, MA_OWNED);
  385 
  386         ue->ue_methods->ue_init(ue);
  387 
  388         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
  389                 return;
  390 
  391         if (ue->ue_methods->ue_tick != NULL)
  392                 usb_callout_reset(&ue->ue_watchdog, hz, ue_watchdog, ue);
  393 }
  394 
  395 static void
  396 ue_stop_task(struct usb_proc_msg *_task)
  397 {
  398         struct usb_ether_cfg_task *task =
  399             (struct usb_ether_cfg_task *)_task;
  400         struct usb_ether *ue = task->ue;
  401 
  402         UE_LOCK_ASSERT(ue, MA_OWNED);
  403 
  404         usb_callout_stop(&ue->ue_watchdog);
  405 
  406         ue->ue_methods->ue_stop(ue);
  407 }
  408 
  409 void
  410 uether_start(struct ifnet *ifp)
  411 {
  412 
  413         ue_start(ifp);
  414 }
  415 
  416 static void
  417 ue_start(struct ifnet *ifp)
  418 {
  419         struct usb_ether *ue = ifp->if_softc;
  420 
  421         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
  422                 return;
  423 
  424         UE_LOCK(ue);
  425         ue->ue_methods->ue_start(ue);
  426         UE_UNLOCK(ue);
  427 }
  428 
  429 static void
  430 ue_promisc_task(struct usb_proc_msg *_task)
  431 {
  432         struct usb_ether_cfg_task *task =
  433             (struct usb_ether_cfg_task *)_task;
  434         struct usb_ether *ue = task->ue;
  435 
  436         ue->ue_methods->ue_setpromisc(ue);
  437 }
  438 
  439 static void
  440 ue_setmulti_task(struct usb_proc_msg *_task)
  441 {
  442         struct usb_ether_cfg_task *task =
  443             (struct usb_ether_cfg_task *)_task;
  444         struct usb_ether *ue = task->ue;
  445 
  446         ue->ue_methods->ue_setmulti(ue);
  447 }
  448 
  449 int
  450 uether_ifmedia_upd(struct ifnet *ifp)
  451 {
  452 
  453         return (ue_ifmedia_upd(ifp));
  454 }
  455 
  456 static int
  457 ue_ifmedia_upd(struct ifnet *ifp)
  458 {
  459         struct usb_ether *ue = ifp->if_softc;
  460 
  461         /* Defer to process context */
  462         UE_LOCK(ue);
  463         ue_queue_command(ue, ue_ifmedia_task,
  464             &ue->ue_media_task[0].hdr,
  465             &ue->ue_media_task[1].hdr);
  466         UE_UNLOCK(ue);
  467 
  468         return (0);
  469 }
  470 
  471 static void
  472 ue_ifmedia_task(struct usb_proc_msg *_task)
  473 {
  474         struct usb_ether_cfg_task *task =
  475             (struct usb_ether_cfg_task *)_task;
  476         struct usb_ether *ue = task->ue;
  477         struct ifnet *ifp = ue->ue_ifp;
  478 
  479         ue->ue_methods->ue_mii_upd(ifp);
  480 }
  481 
  482 static void
  483 ue_watchdog(void *arg)
  484 {
  485         struct usb_ether *ue = arg;
  486         struct ifnet *ifp = ue->ue_ifp;
  487 
  488         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
  489                 return;
  490 
  491         ue_queue_command(ue, ue_tick_task,
  492             &ue->ue_tick_task[0].hdr, 
  493             &ue->ue_tick_task[1].hdr);
  494 
  495         usb_callout_reset(&ue->ue_watchdog, hz, ue_watchdog, ue);
  496 }
  497 
  498 static void
  499 ue_tick_task(struct usb_proc_msg *_task)
  500 {
  501         struct usb_ether_cfg_task *task =
  502             (struct usb_ether_cfg_task *)_task;
  503         struct usb_ether *ue = task->ue;
  504         struct ifnet *ifp = ue->ue_ifp;
  505 
  506         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
  507                 return;
  508 
  509         ue->ue_methods->ue_tick(ue);
  510 }
  511 
  512 int
  513 uether_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
  514 {
  515         struct usb_ether *ue = ifp->if_softc;
  516         struct ifreq *ifr = (struct ifreq *)data;
  517         struct mii_data *mii;
  518         int error = 0;
  519 
  520         switch (command) {
  521         case SIOCSIFFLAGS:
  522                 UE_LOCK(ue);
  523                 if (ifp->if_flags & IFF_UP) {
  524                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
  525                                 ue_queue_command(ue, ue_promisc_task,
  526                                     &ue->ue_promisc_task[0].hdr, 
  527                                     &ue->ue_promisc_task[1].hdr);
  528                         else
  529                                 ue_queue_command(ue, ue_start_task,
  530                                     &ue->ue_sync_task[0].hdr, 
  531                                     &ue->ue_sync_task[1].hdr);
  532                 } else {
  533                         ue_queue_command(ue, ue_stop_task,
  534                             &ue->ue_sync_task[0].hdr, 
  535                             &ue->ue_sync_task[1].hdr);
  536                 }
  537                 UE_UNLOCK(ue);
  538                 break;
  539         case SIOCADDMULTI:
  540         case SIOCDELMULTI:
  541                 UE_LOCK(ue);
  542                 ue_queue_command(ue, ue_setmulti_task,
  543                     &ue->ue_multi_task[0].hdr, 
  544                     &ue->ue_multi_task[1].hdr);
  545                 UE_UNLOCK(ue);
  546                 break;
  547         case SIOCGIFMEDIA:
  548         case SIOCSIFMEDIA:
  549                 if (ue->ue_miibus != NULL) {
  550                         mii = device_get_softc(ue->ue_miibus);
  551                         error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
  552                 } else
  553                         error = ether_ioctl(ifp, command, data);
  554                 break;
  555         default:
  556                 error = ether_ioctl(ifp, command, data);
  557                 break;
  558         }
  559         return (error);
  560 }
  561 
  562 static int
  563 uether_modevent(module_t mod, int type, void *data)
  564 {
  565 
  566         switch (type) {
  567         case MOD_LOAD:
  568                 ueunit = new_unrhdr(0, INT_MAX, NULL);
  569                 break;
  570         case MOD_UNLOAD:
  571                 break;
  572         default:
  573                 return (EOPNOTSUPP);
  574         }
  575         return (0);
  576 }
  577 static moduledata_t uether_mod = {
  578         "uether",
  579         uether_modevent,
  580         0
  581 };
  582 
  583 struct mbuf *
  584 uether_newbuf(void)
  585 {
  586         struct mbuf *m_new;
  587 
  588         m_new = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
  589         if (m_new == NULL)
  590                 return (NULL);
  591         m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
  592 
  593         m_adj(m_new, ETHER_ALIGN);
  594         return (m_new);
  595 }
  596 
  597 int
  598 uether_rxmbuf(struct usb_ether *ue, struct mbuf *m, 
  599     unsigned len)
  600 {
  601         struct ifnet *ifp = ue->ue_ifp;
  602 
  603         UE_LOCK_ASSERT(ue, MA_OWNED);
  604 
  605         /* finalize mbuf */
  606         if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
  607         m->m_pkthdr.rcvif = ifp;
  608         m->m_pkthdr.len = m->m_len = len;
  609 
  610         /* enqueue for later when the lock can be released */
  611         (void)mbufq_enqueue(&ue->ue_rxq, m);
  612         return (0);
  613 }
  614 
  615 int
  616 uether_rxbuf(struct usb_ether *ue, struct usb_page_cache *pc, 
  617     unsigned offset, unsigned len)
  618 {
  619         struct ifnet *ifp = ue->ue_ifp;
  620         struct mbuf *m;
  621 
  622         UE_LOCK_ASSERT(ue, MA_OWNED);
  623 
  624         if (len < ETHER_HDR_LEN || len > MCLBYTES - ETHER_ALIGN)
  625                 return (1);
  626 
  627         m = uether_newbuf();
  628         if (m == NULL) {
  629                 if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
  630                 return (ENOMEM);
  631         }
  632 
  633         usbd_copy_out(pc, offset, mtod(m, uint8_t *), len);
  634 
  635         /* finalize mbuf */
  636         if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
  637         m->m_pkthdr.rcvif = ifp;
  638         m->m_pkthdr.len = m->m_len = len;
  639 
  640         /* enqueue for later when the lock can be released */
  641         (void)mbufq_enqueue(&ue->ue_rxq, m);
  642         return (0);
  643 }
  644 
  645 void
  646 uether_rxflush(struct usb_ether *ue)
  647 {
  648         struct ifnet *ifp = ue->ue_ifp;
  649         struct epoch_tracker et;
  650         struct mbuf *m, *n;
  651 
  652         UE_LOCK_ASSERT(ue, MA_OWNED);
  653 
  654         n = mbufq_flush(&ue->ue_rxq);
  655         UE_UNLOCK(ue);
  656         NET_EPOCH_ENTER(et);
  657         while ((m = n) != NULL) {
  658                 n = STAILQ_NEXT(m, m_stailqpkt);
  659                 m->m_nextpkt = NULL;
  660                 ifp->if_input(ifp, m);
  661         }
  662         NET_EPOCH_EXIT(et);
  663         UE_LOCK(ue);
  664 }
  665 
  666 /*
  667  * USB net drivers are run by DRIVER_MODULE() thus SI_SUB_DRIVERS,
  668  * SI_ORDER_MIDDLE.  Run uether after that.
  669  */
  670 DECLARE_MODULE(uether, uether_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
  671 MODULE_VERSION(uether, 1);

Cache object: e073cadeaf227ab4221b882e6b461766


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.