| USBNET(9) | Kernel Developer's Manual | USBNET(9) | 
usbnet —
#include <dev/usb/usbnet.h>
usbnet_set_link(struct
  usbnet *un, bool
  link);
struct ifnet *
  
  usbnet_ifp(struct
    usbnet *un);
struct ethercom *
  
  usbnet_ec(struct
    usbnet *un);
struct mii_data *
  
  usbnet_mii(struct
    usbnet *un);
krndsource_t *
  
  usbnet_rndsrc(struct
    usbnet *un);
void *
  
  usbnet_softc(struct
    usbnet *un);
bool
  
  usbnet_havelink(struct
    usbnet *un);
int
  
  usbnet_ispromisc(struct
    usbnet *un);
bool
  
  usbnet_isdying(struct
    usbnet *un);
void
  
  usbnet_enqueue(struct
    usbnet *un, uint8_t
    *buf, size_t
    buflen, int
    csum_flags, uint32_t
    csum_data, int
    mbuf_flags);
void
  
  usbnet_input(struct
    usbnet *un, uint8_t
    *buf, size_t
    buflen);
void
  
  usbnet_attach(struct
    usbnet *un);
void
  
  usbnet_attach_ifp(struct
    usbnet *un, unsigned
    if_flags, unsigned
    if_extflags, const struct
    usbnet_mii *unm);
int
  
  usbnet_detach(device_t
    dev, int
  flags);
int
  
  usbnet_activate(device_t
    dev, devact_t
  act);
usbnet framework provides methods usable for USB
  Ethernet drivers. The framework has support for these features:
usbnet provides many or all of the
    traditional “softc” members inside struct
    usbnet, which can be used directly as the device softc structure if no
    additional storage is required. A structure exists for receive and transmit
    chain management, struct usbnet_chain, that tracks the
    metadata for each transfer descriptor available, minimum of one each for Rx
    and Tx slot, and will be passed to the Rx and Tx callbacks.
There is a struct usbnet_ops structure that provides a number of optional and required callbacks that will be described below.
For autoconfiguration the device attach routine is expected to
    ensure that this device's struct usbnet is the first
    member of the device softc, if it can not be used directly as the device
    softc, as well as set up the necessary structure members, find end-points,
    find the Ethernet address if relevant, call
    usbnet_attach(), set up interface, Ethernet, and MII
    capabilities, and finally call usbnet_attach_ifp().
    The device detach routine should free any resources allocated by attach and
    then call usbnet_detach(), possibly directly using
    usbnet_detach() as most consumers have no additional
    resources not owned and released by the usbnet
    framework itself. The device activate function should be set to
    usbnet_activate().
When bringing an interface up from
    if_init(9), which happens
    under IFNET_LOCK(9),
    usbnet will:
See the RECEIVE AND SEND section for details on using the chains.
When bringing an interface down from
    if_stop(9), which happens
    under IFNET_LOCK(9),
    usbnet will:
For interface ioctl, most of the handling is in the framework.
    While the interface is running, the optional “uno_mcast”
    callback is invoked after handling the SIOCADDMULTI
    and SIOCDELMULTI ioctl commands to update the
    hardware's multicast filter from the
    ethersubr(9) lists. The
    optional “uno_ioctl” callback, which is invoked under
    IFNET_LOCK(9), can be used
    to program special settings like offload handling.
If ioctl handling requires capturing device-specific ioctls then
    the “uno_override_ioctl” callback may be used instead to
    replace the framework's ioctl handler completely (i.e., the replacement
    should call any generic ioctl handlers such as
    ether_ioctl() as required.) For sending packets, the
    “uno_tx_prepare” callback must be used to convert an mbuf into
    a chain buffer ready for transmission.
For devices requiring MII handling there are callbacks for reading
    and writing registers, and for status change events. Access to all the MII
    functions is serialized by usbnet.
As receive must handle the case of multiple packets in one buffer,
    the support is split between the driver and the framework. A
    “uno_rx_loop” callback must be provided that loops over the
    incoming packet data found in a chain, performs necessary checking and
    passes the network frame up the stack via either
    usbnet_enqueue() or
    usbnet_input(). Typically Ethernet devices prefer
    usbnet_enqueue().
General accessor functions for struct usbnet:
usbnet_set_link(un,
    link)usbnet_ifp(un)usbnet_ec(un)usbnet_mii(un)usbnet_rndsrc(un)usbnet_softc(un)usbnet_havelink(un)usbnet_ispromisc(un)IFF_PROMISC is enabled, false if not.
    May be used only in “uno_init” and “uno_mcast”.
Drivers must use this in “uno_mcast” instead of
        reading ifp->if_flags.
usbnet_isdying(un)Buffer enqueue handling for struct usbnet:
usbnet_enqueue(un,
    buf, buflen,
    csum_flags, csum_data,
    mbuf_flags)usbnet_input(un,
    buf, buflen)Autoconfiguration handling for struct usbnet. See the AUTOCONFIGURATION section for more details about these functions.
usbnet_attach(un)usbnet_attach_ifp(un,
    if_flags, if_extflags,
    unm)If the passed in unm is
        non-NULL then an MII interface will be created
        using the values provided in the struct usbnet_mii
        structure, which has these members passed to
        mii_attach():
A default unm can be set using the
        USBNET_MII_DECL_DEFAULT() macro. The
        if_flags and if_extflags
        will be or-ed into the interface flags and extflags.
usbnet_detach(dev,
    flags)usbnet_activate(dev,
    act)usbd_device2interface_handle() for more
    details.(*uno_stop)(struct ifnet
        *ifp, int disable)(*uno_ioctl)(struct ifnet
        *ifp, u_long cmd, void
        *data)(*uno_mcast)(struct ifnet
        *)(*uno_override_ioctl)(struct
        ifnet *ifp, u_long cmd, void
        *data)usbnet (optional). May or may
          not be called under
          IFNET_LOCK(9).(*uno_init)(struct ifnet
        *ifp)(*uno_read_reg)(struct usbnet
        *un, int phy, int reg,
        uint16_t *val)(*uno_write_reg)(struct usbnet
        *un, int phy, int reg,
        uint16_t val)(*uno_statchg)(struct ifnet
        *ifp)(*uno_tx_prepare)(struct usbnet
        *un, struct mbuf *m, struct
        usbnet_chain *c)(*uno_rx_loop)(struct usbnet
        *un, struct usbnet_chain *c,
        uint32_t total_len)(*uno_intr)(struct usbnet
        *un, usbd_status status)(*uno_tick)(struct usbnet
        *un)NULL, points to a buffer passed to
          usbd_open_pipe_intr() in the device init
          callback, along with the size and interval.USBNET_ENDPT_RX,
      USBNET_ENDPT_TX, and
      USBNET_ENDPT_INTR. The Rx and Tx endpoints are
      required.usbnet.usbnet_attach_ifp() if the device has
    Ethernet.usbnet framework will
      not touch this value.usbd_setup_xfer() for receiving
    packets.usbd_setup_xfer() for sending
    packets.The device detach and activate callbacks can typically be set to
    usbnet_detach() and
    usbnet_activate() unless device-specific handling is
    required, in which case, they can be called before or after such
  handling.
The capabilities described in both struct
    ifp and struct ethercom must be set before
    calling usbnet_attach_ifp().
un_ed,
  un_rx_xfer_flags, and
  un_tx_xfer_flags members, and the
  uno_init(), uno_tx_prepare(),
  uno_rx_loop(), and uno_stop()
  callbacks of usbnet_ops.
Typically, the device attach routine will fill in members of the
    usbnet structure, as listed in
    AUTOCONFIGURATION. The
    un_ed array should have the
    USBNET_ENDPT_RX and
    USBNET_ENDPT_TX array entries filled in, and
    optionally the USBNET_ENDPT_INTR entry filled in if
    applicable.
The uno_init() callback enables the
    hardware, and if necessary reprograms the hardware multicast filter, before
    the framework initiates USB Tx/Rx transfers. All USB transfer setup is
    handled by the framework. The driver callbacks merely copy data in or out of
    a chain entry using what is typically a device-specific method.
The uno_rx_loop() callback, called
    sequentially, converts the provided usbnet_chain data
    and length into a series (one or more) of packets that are enqueued with the
    higher layers using either usbnet_enqueue() (for
    most devices) or usbnet_input() for devices that use
    if_input(). (This currently relies upon the
    struct ifnet having the “_if_input”
    member set as well, which is true for current consumers.)
The uno_tx_prepare() callback must convert
    the provided struct mbuf into the provided
    struct usbnet_chain performing any device-specific
    padding, checksum, header or other. Note that this callback must check that
    it is not attempting to copy more than the chain buffer size, as set in the
    usbnet “un_tx_bufsz” member. This
    callback is only called once per packet, sequentially.
The struct usbnet_chain structure which contains a “unc_buf” member which has the chain buffer allocated where data should be copied to or from for receive or transmit operations. It also contains pointers back to the owning struct usbnet, and the struct usbd_xfer associated with this transfer.
After aborting all USB Tx/Rx transfers when bringing an interface
    down, the framework calls the optional uno_stop()
    callback to disable the hardware.
usbnet using the
  usbd_open_pipe_intr() function (instead of the
  usbd_open_pipe() function.) The
  usbnet framework provides most of the interrupt
  handling and the callback simply inspects the returned buffer as necessary. To
  enable the this callback point the struct usbnet member
  “un_intr” to a struct usbnet_intr
  structure with these members set:
These values will be passed to
    usbd_open_pipe_intr().
usbnet framework
  is largely an effort in deleting code. The process involves making these
  changes:
Many drivers can use the usbnet
        structure as the device private storage passed to
        CFATTACH_DECL_NEW. Many internal functions to
        the driver may look better if switched to operate on the device's
        usbnet as, for example, the
        usbd_device value is now available (and must be
        set by the driver) in the usbnet, which may be
        needed for any call to usbd_do_request(). The
        standard endpoint values must be stored in the
        usbnet “un_ed[]” array.
As usbnet manages xfer chains all code
        related to the opening, closing, aborting and transferring of data on
        pipes is performed by the framework based upon the buffer size and more
        provided in subnet, so all code related to them
        should be deleted.
usbnet_attach_ifp(). All calls to
      ifmedia_init(),
      mii_attach(),
      ifmedia_add(),
      ifmedia_set(),
      if_attach(),
      ether_ifattach(),
      rnd_attach_source(), and
      usbd_add_drv_event() should be eliminated. The
      device “ioctl” routine can use the default handling with a
      callback for additional device specific programming (multicast filters,
      etc.), which can be empty, or, the override ioctl can be used for heavier
      requirements. The device “stop” routine is replaced with a
      simple call that turns off the device-specific transmitter and receiver if
      necessary, as the framework handles pipes and transfers and buffers.usbnet_set_link() and
      usbnet_havelink(). Other ifmedia callbacks that
      were passed to ifmedia_init() should be deleted
      and any work moved into “uno_statchg”.usbnet framework handles the majority of
      handling of both network directions. The interface init routine should
      keep all of the device specific setup but replace all pipe management with
      a call to usbnet_init_rx_tx(). The typical receive
      handling will normally be replaced with a receive loop functions that can
      accept one or more packets, “uno_rx_loop”, which can use
      either usbnet_enqueue() or
      usbnet_input() to pass the packets up to higher
      layers. The typical interface “if_start” function and any
      additional functions used will normal be replaced with a relatively simple
      “uno_tx_prepare” function that simply converts an
      mbuf into a usbnet_chain
      useful for this device that will be passed onto
      usbd_transfer(). The framework's handling of the
      Tx interrupt is all internal.usbd_open_pipe_intr() method), most of the
      interrupt handler should be deleted, leaving only code that inspects the
      result of the interrupt transfer.usbent_set_link() during any status change
      event.
    Many locking issues are hidden without
        LOCKDEBUG, including hard-hangs. It's highly
        recommended to develop with LOCKDEBUG.
The usbnet “un_ed” array is unsigned and should use “0” as the no-endpoint value.
usbnet interface first appeared in
  NetBSD 9.0. Portions of the original design are based
  upon ideas from Nick Hudson
  <skrll@NetBSD.org>.
| March 15, 2020 | NetBSD 10.0 |