828 lines
21 KiB
Groff
828 lines
21 KiB
Groff
.\" $NetBSD: usbnet.9,v 1.22 2024/02/04 05:43:06 mrg Exp $
|
|
.\"
|
|
.\" Copyright (c) 2019 Matthew R. Green
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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.
|
|
.\"
|
|
.Dd March 15, 2020
|
|
.Dt USBNET 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm usbnet
|
|
.Nd common USB Ethernet driver framework
|
|
.Sh SYNOPSIS
|
|
.In dev/usb/usbnet.h
|
|
.Ss Functions offered by usbnet.h
|
|
.Ft void
|
|
.Fn usbnet_set_link "struct usbnet *un" "bool link"
|
|
.Ft struct ifnet *
|
|
.Fn usbnet_ifp "struct usbnet *un"
|
|
.Ft struct ethercom *
|
|
.Fn usbnet_ec "struct usbnet *un"
|
|
.Ft struct mii_data *
|
|
.Fn usbnet_mii "struct usbnet *un"
|
|
.Ft krndsource_t *
|
|
.Fn usbnet_rndsrc "struct usbnet *un"
|
|
.Ft void *
|
|
.Fn usbnet_softc "struct usbnet *un"
|
|
.Ft bool
|
|
.Fn usbnet_havelink "struct usbnet *un"
|
|
.Ft int
|
|
.Fn usbnet_ispromisc "struct usbnet *un"
|
|
.Ft bool
|
|
.Fn usbnet_isdying "struct usbnet *un"
|
|
.Ft void
|
|
.Fn usbnet_enqueue "struct usbnet *un" "uint8_t *buf" "size_t buflen" "int csum_flags" "uint32_t csum_data" "int mbuf_flags"
|
|
.Ft void
|
|
.Fn usbnet_input "struct usbnet *un" "uint8_t *buf" "size_t buflen"
|
|
.Ft void
|
|
.Fn usbnet_attach "struct usbnet *un"
|
|
.Ft void
|
|
.Fn usbnet_attach_ifp "struct usbnet *un" "unsigned if_flags" "unsigned if_extflags" "const struct usbnet_mii *unm"
|
|
.Ft int
|
|
.Fn usbnet_detach "device_t dev" "int flags"
|
|
.Ft int
|
|
.Fn usbnet_activate "device_t dev" "devact_t act"
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm
|
|
framework provides methods usable for USB Ethernet drivers.
|
|
The framework has support for these features:
|
|
.Bl -bullet -offset 8n
|
|
.It
|
|
Partial autoconf handling
|
|
.It
|
|
USB endpoint pipe handling
|
|
.It
|
|
Rx and Tx chain handling
|
|
.It
|
|
Generic handlers or support for several struct ifnet callbacks
|
|
.It
|
|
Network stack locking protocol
|
|
.It
|
|
Interrupt handling
|
|
.El
|
|
.Pp
|
|
.Nm
|
|
provides many or all of the traditional
|
|
.Dq softc
|
|
members inside
|
|
.Va 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,
|
|
.Va 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.
|
|
.Pp
|
|
There is a
|
|
.Va struct usbnet_ops
|
|
structure that provides a number of optional and required callbacks
|
|
that will be described below.
|
|
.Pp
|
|
For autoconfiguration the device attach routine is expected to
|
|
ensure that this device's
|
|
.Va 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
|
|
.Fn usbnet_attach ,
|
|
set up interface, Ethernet, and MII capabilities, and finally call
|
|
.Fn usbnet_attach_ifp .
|
|
The device detach routine should free any resources allocated
|
|
by attach and then call
|
|
.Fn usbnet_detach ,
|
|
possibly directly using
|
|
.Fn usbnet_detach
|
|
as most consumers have no additional resources not owned and
|
|
released by the
|
|
.Nm
|
|
framework itself.
|
|
The device activate function should be set to
|
|
.Fn usbnet_activate .
|
|
.Pp
|
|
When bringing an interface up from
|
|
.Xr if_init 9 ,
|
|
which happens under
|
|
.Xr IFNET_LOCK 9 ,
|
|
.Nm
|
|
will:
|
|
.Bl -enum
|
|
.It
|
|
call
|
|
.Dq uno_init
|
|
to initialize the hardware for sending and receiving packets,
|
|
.It
|
|
open the USB pipes,
|
|
.It
|
|
allocate Rx and Tx buffers for transfers,
|
|
.It
|
|
call
|
|
.Dq uno_mcast
|
|
to initially program the hardware multicast filter, and finally
|
|
.It
|
|
start the Rx transfers so packets can be received.
|
|
.El
|
|
.Pp
|
|
See the
|
|
.Sx RECEIVE AND SEND
|
|
section for details on using the chains.
|
|
.Pp
|
|
When bringing an interface down from
|
|
.Xr if_stop 9 ,
|
|
which happens under
|
|
.Xr IFNET_LOCK 9 ,
|
|
.Nm
|
|
will:
|
|
.Bl -enum
|
|
.It
|
|
abort the USB pipes,
|
|
.It
|
|
call
|
|
.Dq uno_stop
|
|
to stop the hardware from receiving packets (unless the device is
|
|
detaching),
|
|
.It
|
|
free Rx and Tx buffers for transfers, and
|
|
.It
|
|
close the USB pipes.
|
|
.El
|
|
.Pp
|
|
For interface ioctl, most of the handling is in the framework.
|
|
While the interface is running, the optional
|
|
.Dq uno_mcast
|
|
callback is invoked after handling the
|
|
.Dv SIOCADDMULTI
|
|
and
|
|
.Dv SIOCDELMULTI
|
|
ioctl commands to update the hardware's multicast filter from the
|
|
.Xr ethersubr 9
|
|
lists.
|
|
The optional
|
|
.Dq uno_ioctl
|
|
callback, which is invoked under
|
|
.Xr IFNET_LOCK 9 ,
|
|
can be used to program special settings like offload handling.
|
|
.Pp
|
|
If ioctl handling requires capturing device-specific ioctls then the
|
|
.Dq 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
|
|
.Fn ether_ioctl
|
|
as required.)
|
|
For sending packets, the
|
|
.Dq uno_tx_prepare
|
|
callback must be used to convert
|
|
an mbuf into a chain buffer ready for transmission.
|
|
.Pp
|
|
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
|
|
.Nm .
|
|
.Pp
|
|
As receive must handle the case of multiple packets in one buffer,
|
|
the support is split between the driver and the framework.
|
|
A
|
|
.Dq 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
|
|
.Fn usbnet_enqueue
|
|
or
|
|
.Fn usbnet_input .
|
|
Typically Ethernet devices prefer
|
|
.Fn usbnet_enqueue .
|
|
.Pp
|
|
General accessor functions for
|
|
.Fa struct usbnet :
|
|
.Bl -tag -width 4n
|
|
.It Fn usbnet_set_link un link
|
|
Set the link status for this
|
|
.Fa un
|
|
to
|
|
.Fa link .
|
|
.It Fn usbnet_ifp un
|
|
Returns pointer to this
|
|
.Fa un Ns 's
|
|
.Va struct ifnet .
|
|
.It Fn usbnet_ec un
|
|
Returns pointer to this
|
|
.Fa un Ns 's
|
|
.Va struct ethercom .
|
|
.It Fn usbnet_mii un
|
|
Returns pointer to this
|
|
.Fa un Ns 's
|
|
.Va struct mii_data .
|
|
.It Fn usbnet_rndsrc un
|
|
Returns pointer to this
|
|
.Fa un Ns 's
|
|
.Va krndsource_t .
|
|
.It Fn usbnet_softc un
|
|
Returns pointer to this
|
|
.Fa un Ns 's
|
|
device softc.
|
|
.It Fn usbnet_havelink un
|
|
Returns true if link is active.
|
|
.It Fn usbnet_ispromisc un
|
|
True if
|
|
.Dv IFF_PROMISC
|
|
is enabled, false if not.
|
|
.Pp
|
|
May be used only in
|
|
.Dq uno_init
|
|
and
|
|
.Dq uno_mcast .
|
|
.Pp
|
|
Drivers must use this in
|
|
.Dq uno_mcast
|
|
instead of reading
|
|
.Li ifp->if_flags .
|
|
.It Fn usbnet_isdying un
|
|
Returns true if device is dying (has been pulled or deactivated,
|
|
pending detach).
|
|
This should be used only to abort timeout loops early.
|
|
.El
|
|
.Pp
|
|
Buffer enqueue handling for
|
|
.Fa struct usbnet :
|
|
.Bl -tag -width 4n
|
|
.It Fn usbnet_enqueue un buf buflen csum_flags csum_data mbuf_flags
|
|
Enqueue buffer
|
|
.Fa buf
|
|
for length
|
|
.Fa buflen
|
|
with higher layers, using the provided
|
|
.Fa csum_flags ,
|
|
and
|
|
.Fa csum_data ,
|
|
which are written directly to the mbuf packet header, and
|
|
.Fa mbuf_flags ,
|
|
which is or-ed into the mbuf flags for the created mbuf.
|
|
.It Fn usbnet_input un buf buflen
|
|
Enqueue buffer
|
|
.Fa buf
|
|
for length
|
|
.Fa buflen
|
|
with higher layers.
|
|
.El
|
|
.Pp
|
|
Autoconfiguration handling for
|
|
.Fa struct usbnet .
|
|
See the
|
|
.Sx AUTOCONFIGURATION
|
|
section for more details about these functions.
|
|
.Bl -tag -width 4n
|
|
.It Fn usbnet_attach un
|
|
Initial stage attach of a usb network device.
|
|
Performs internal initialization and memory allocation only \(em
|
|
nothing is published yet.
|
|
.It Fn usbnet_attach_ifp un if_flags if_extflags unm
|
|
Final stage attach of usb network device.
|
|
Publishes the network interface to the rest of the system.
|
|
.Pp
|
|
If the passed in
|
|
.Fa unm
|
|
is
|
|
.Pf non- Dv NULL
|
|
then an MII interface will be created using the values
|
|
provided in the
|
|
.Fa struct usbnet_mii
|
|
structure, which has these members passed to
|
|
.Fn mii_attach :
|
|
.Bl -tag -width "un_mii_capmask"
|
|
.It un_mii_flags
|
|
Flags.
|
|
.It un_mii_capmask
|
|
Capability mask.
|
|
.It un_mii_phyloc
|
|
PHY location.
|
|
.It un_mii_offset
|
|
PHY offset.
|
|
.El
|
|
.Pp
|
|
A default
|
|
.Fa unm
|
|
can be set using the
|
|
.Fn USBNET_MII_DECL_DEFAULT
|
|
macro.
|
|
The
|
|
.Fa if_flags
|
|
and
|
|
.Fa if_extflags
|
|
will be or-ed into the interface flags and extflags.
|
|
.It Fn usbnet_detach dev flags
|
|
Device detach.
|
|
Stops all activity and frees memory.
|
|
Usable as
|
|
.Xr driver 9
|
|
detach method.
|
|
.It Fn usbnet_activate dev act
|
|
Device activate (deactivate) method.
|
|
Usable as
|
|
.Xr driver 9
|
|
activate method.
|
|
.El
|
|
.Sh AUTOCONFIGURATION
|
|
The framework expects the usbnet structure to have these members
|
|
filled in with valid values or functions:
|
|
.Bl -tag -width 6n
|
|
.It un_sc
|
|
Real softc allocated by autoconf and provided to attach, should be
|
|
set to the usbnet structure if no device-specific softc is needed.
|
|
.It un_dev
|
|
device_t saved in attach, used for messages mostly.
|
|
.It un_iface
|
|
The USB iface handle for data interactions, see
|
|
.Fn usbd_device2interface_handle
|
|
for more details.
|
|
.It un_udev
|
|
The struct usbd_device for this device, provided as the usb_attach_arg's
|
|
.Va uaa_device
|
|
member.
|
|
.It un_ops
|
|
Points to a
|
|
.Va struct usbnet_ops
|
|
structure which contains these members:
|
|
.Bl -tag -width 4n
|
|
.It Ft void Fn (*uno_stop) "struct ifnet *ifp" "int disable"
|
|
Stop hardware activity
|
|
.Pq optional .
|
|
Called under
|
|
.Xr IFNET_LOCK 9
|
|
when bringing the interface down, but skipped when the device is
|
|
detaching.
|
|
.It Ft int Fn (*uno_ioctl) "struct ifnet *ifp" "u_long cmd" "void *data"
|
|
Handle driver-specific ioctls
|
|
.Pq optional .
|
|
Called under
|
|
.Xr IFNET_LOCK 9 .
|
|
.It Ft void Fn (*uno_mcast) "struct ifnet *"
|
|
Program hardware multicast filters from
|
|
.Xr ethersubr 9
|
|
lists
|
|
.Pq optional .
|
|
Called between, and not during,
|
|
.Dq uno_init
|
|
and
|
|
.Dq uno_stop .
|
|
.It Ft int Fn (*uno_override_ioctl) "struct ifnet *ifp" "u_long cmd" "void *data"
|
|
Handle all ioctls, including standard ethernet ioctls normally handled
|
|
internally by
|
|
.Nm
|
|
.Pq optional .
|
|
May or may not be called under
|
|
.Xr IFNET_LOCK 9 .
|
|
.It Ft int Fn (*uno_init) "struct ifnet *ifp"
|
|
Initialize hardware activity
|
|
.Pq optional .
|
|
Called under
|
|
.Xr IFNET_LOCK 9
|
|
when bringing the interface up.
|
|
.It Ft int Fn (*uno_read_reg) "struct usbnet *un" "int phy" "int reg" "uint16_t *val"
|
|
Read MII register.
|
|
Required with MII.
|
|
Serialized with other MII functions, and only called after
|
|
.Dq uno_init
|
|
and before
|
|
.Dq uno_stop .
|
|
.It Ft int Fn (*uno_write_reg) "struct usbnet *un" "int phy" "int reg" "uint16_t val"
|
|
Write MII register.
|
|
Required with MII.
|
|
Serialized with other MII functions, and only called after
|
|
.Dq uno_init
|
|
and before
|
|
.Dq uno_stop .
|
|
.It Ft usbd_status Fn (*uno_statchg) "struct ifnet *ifp"
|
|
Handle MII status change.
|
|
Required with MII.
|
|
Serialized with other MII functions, and only called after
|
|
.Dq uno_init
|
|
and before
|
|
.Dq uno_stop .
|
|
.It Ft unsigned Fn (*uno_tx_prepare) "struct usbnet *un" "struct mbuf *m" "struct usbnet_chain *c"
|
|
Prepare an mbuf for transmit.
|
|
Required.
|
|
Called sequentially between, and not during,
|
|
.Dq uno_init
|
|
and
|
|
.Dq uno_stop .
|
|
.It Ft void Fn (*uno_rx_loop) "struct usbnet *un" "struct usbnet_chain *c" "uint32_t total_len"
|
|
Prepare one or more chain for enqueue.
|
|
Required.
|
|
Called sequentially between, and not during,
|
|
.Dq uno_init
|
|
and
|
|
.Dq uno_stop .
|
|
.It Ft void Fn (*uno_intr) "struct usbnet *un" "usbd_status status"
|
|
Process periodic interrupt
|
|
.Pq optional .
|
|
Called sequentially between, and not during,
|
|
.Dq uno_init
|
|
and
|
|
.Dq uno_stop .
|
|
.It Ft void Fn (*uno_tick) "struct usbnet *un"
|
|
Called every second with USB task thread context
|
|
.Pq optional .
|
|
Called sequentially between, and not during,
|
|
.Dq uno_init
|
|
and
|
|
.Dq uno_stop .
|
|
.El
|
|
.It un_intr
|
|
Points to a
|
|
.Va struct usbnet_intr
|
|
structure which should have these members set:
|
|
.Bl -tag -width 4n
|
|
.It uni_buf
|
|
If
|
|
.Pf non- Dv NULL ,
|
|
points to a buffer passed to
|
|
.Fn usbd_open_pipe_intr
|
|
in the device init callback, along with the size and interval.
|
|
.It uni_bufsz
|
|
Size of interrupt pipe buffer.
|
|
.It uni_interval
|
|
Frequency of the interrupt in milliseconds.
|
|
.El
|
|
.It un_ed
|
|
Array of endpoint descriptors.
|
|
There indexes are provided:
|
|
.Dv USBNET_ENDPT_RX ,
|
|
.Dv USBNET_ENDPT_TX ,
|
|
and
|
|
.Dv USBNET_ENDPT_INTR .
|
|
The Rx and Tx endpoints are required.
|
|
.It un_phyno
|
|
MII phy number.
|
|
Not used by
|
|
.Nm .
|
|
.It un_eaddr
|
|
6 bytes of Ethernet address that must be provided before calling
|
|
.Fn usbnet_attach_ifp
|
|
if the device has Ethernet.
|
|
.It un_flags
|
|
Device owned flags word.
|
|
The
|
|
.Nm
|
|
framework will not touch this value.
|
|
.It un_rx_xfer_flags
|
|
Passed to
|
|
.Fn usbd_setup_xfer
|
|
for receiving packets.
|
|
.It un_tx_xfer_flags
|
|
Passed to
|
|
.Fn usbd_setup_xfer
|
|
for sending packets.
|
|
.It un_rx_list_cnt
|
|
Number of chain elements to allocate for Rx.
|
|
.It un_tx_list_cnt
|
|
Number of chain elements to allocate for Tx.
|
|
.It un_rx_bufsz
|
|
Rx buffer size.
|
|
.It un_tx_bufsz
|
|
Tx buffer size.
|
|
.El
|
|
.Pp
|
|
The device detach and activate callbacks can typically be set to
|
|
.Fn usbnet_detach
|
|
and
|
|
.Fn usbnet_activate
|
|
unless device-specific handling is required, in which case, they
|
|
can be called before or after such handling.
|
|
.Pp
|
|
The capabilities described in both
|
|
.Va struct ifp
|
|
and
|
|
.Va struct ethercom
|
|
must be set before calling
|
|
.Fn usbnet_attach_ifp .
|
|
.Sh RECEIVE AND SEND
|
|
Receive and send routines are structured around the
|
|
.Va usbnet_cdata
|
|
and
|
|
.Va usbnet_chain
|
|
structures, the
|
|
.Dv un_ed ,
|
|
.Dv un_rx_xfer_flags ,
|
|
and
|
|
.Dv un_tx_xfer_flags
|
|
members, and the
|
|
.Fn uno_init ,
|
|
.Fn uno_tx_prepare ,
|
|
.Fn uno_rx_loop ,
|
|
and
|
|
.Fn uno_stop
|
|
callbacks of
|
|
.Va usbnet_ops .
|
|
.Pp
|
|
Typically, the device attach routine will fill in members of the
|
|
.Va usbnet
|
|
structure, as listed in
|
|
.Sx AUTOCONFIGURATION .
|
|
The
|
|
.Dv un_ed
|
|
array should have the
|
|
.Dv USBNET_ENDPT_RX
|
|
and
|
|
.Dv USBNET_ENDPT_TX
|
|
array entries filled in, and optionally the
|
|
.Dv USBNET_ENDPT_INTR
|
|
entry filled in if applicable.
|
|
.Pp
|
|
The
|
|
.Fn 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.
|
|
.Pp
|
|
The
|
|
.Fn uno_rx_loop
|
|
callback, called sequentially, converts the provided
|
|
.Va usbnet_chain
|
|
data and length into a series (one or more) of packets that are
|
|
enqueued with the higher layers using either
|
|
.Fn usbnet_enqueue
|
|
(for most devices) or
|
|
.Fn usbnet_input
|
|
for devices that use
|
|
.Fn if_input .
|
|
(This currently relies upon the
|
|
.Va struct ifnet
|
|
having the
|
|
.Dq _if_input
|
|
member set as well, which is true for current consumers.)
|
|
.Pp
|
|
The
|
|
.Fn uno_tx_prepare
|
|
callback must convert the provided
|
|
.Va struct mbuf
|
|
into the provided
|
|
.Va 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
|
|
.Va usbnet
|
|
.Dq un_tx_bufsz
|
|
member.
|
|
This callback is only called once per packet, sequentially.
|
|
.Pp
|
|
The
|
|
.Fa struct usbnet_chain
|
|
structure which contains a
|
|
.Dq 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
|
|
.Fa struct usbnet ,
|
|
and the
|
|
.Va struct usbd_xfer
|
|
associated with this transfer.
|
|
.Pp
|
|
After aborting all USB Tx/Rx transfers when bringing an interface down,
|
|
the framework calls the optional
|
|
.Fn uno_stop
|
|
callback to disable the hardware.
|
|
.Sh MII
|
|
For devices that have MII support these callbacks in
|
|
.Fa struct usbnet_ops
|
|
must be provided:
|
|
.Bl -tag -width 4n
|
|
.It uno_read_reg
|
|
Read an MII register for a particular PHY.
|
|
Returns standard
|
|
.Xr errno 2 .
|
|
Must initialize the result even on failure.
|
|
.It uno_write_reg
|
|
Write an MII register for a particular PHY.
|
|
Returns standard
|
|
.Xr errno 2 .
|
|
.It uno_statchg
|
|
Handle a status change event for this interface.
|
|
.El
|
|
.Sh INTERRUPT PIPE
|
|
The interrupt specific callback,
|
|
.Dq uno_intr ,
|
|
is an optional callback that can be called periodically, registered by
|
|
.Nm
|
|
using the
|
|
.Fn usbd_open_pipe_intr
|
|
function (instead of the
|
|
.Fn usbd_open_pipe
|
|
function.)
|
|
The
|
|
.Nm
|
|
framework provides most of the interrupt handling and the callback
|
|
simply inspects the returned buffer as necessary.
|
|
To enable the this callback point the
|
|
.Va struct usbnet
|
|
member
|
|
.Dq un_intr
|
|
to a
|
|
.Va struct usbnet_intr
|
|
structure with these members set:
|
|
.Bl -tag -width 4n
|
|
.It uni_buf
|
|
Data buffer for interrupt status relies.
|
|
.It uni_bufsz
|
|
Size of the above buffer.
|
|
.It uni_interval
|
|
Interval in millieconds.
|
|
.El
|
|
.Pp
|
|
These values will be passed to
|
|
.Fn usbd_open_pipe_intr .
|
|
.Sh CONVERTING OLD-STYLE DRIVERS
|
|
The porting of an older driver to the
|
|
.Nm
|
|
framework is largely an effort in deleting code.
|
|
The process involves making these changes:
|
|
.Bl -tag -width 4n
|
|
.It Headers
|
|
Many headers are included in
|
|
.Pa usbnet.h
|
|
and can be removed from the driver, as well as headers no longer used,
|
|
such as
|
|
.Pa callout.h
|
|
and
|
|
.Pa rndsource.h ,
|
|
etc.
|
|
.It Device softc
|
|
The majority of the driver's existing
|
|
.Dq softc
|
|
structure can likely be replaced with usage of
|
|
.Va struct usbnet
|
|
and its related functionality.
|
|
This includes at least the device_t pointer, Ethernet address, the
|
|
ethercom and mii_data structures, end point descriptors, usbd device,
|
|
interface, and task and callout structures (both these probably go
|
|
away entirely) and all the associated watchdog handling,
|
|
timevals, list size, buffer size and xfer flags for
|
|
both Rx, and Tx, and interrupt notices, interface flags, device link,
|
|
PHY number, chain data, locks including Rx, Tx, and MII.
|
|
There is a driver-only
|
|
.Dq un_flags
|
|
in the
|
|
.Va usbnet
|
|
structure available for drivers to use.
|
|
.Pp
|
|
Many drivers can use the
|
|
.Va usbnet
|
|
structure as the device private storage passed to
|
|
.Dv CFATTACH_DECL_NEW .
|
|
Many internal functions to the driver may look better if switched to
|
|
operate on the device's
|
|
.Va usbnet
|
|
as, for example, the
|
|
.Va usbd_device
|
|
value is now available (and must be set by the driver) in the
|
|
.Va usbnet ,
|
|
which may be needed for any call to
|
|
.Fn usbd_do_request .
|
|
The standard endpoint values must be stored in the
|
|
.Nm
|
|
.Dq un_ed[]
|
|
array.
|
|
.Pp
|
|
As
|
|
.Nm
|
|
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
|
|
.Va subnet ,
|
|
so all code related to them should be deleted.
|
|
.It Interface setup
|
|
The vast majority of interface specific code should be deleted.
|
|
For device-specific interface values, the
|
|
.Va ifnet
|
|
flags and exflags can be set, as well as the
|
|
.Va ethercom
|
|
.Dq ec_capabilities
|
|
member, before calling
|
|
.Fn usbnet_attach_ifp .
|
|
All calls to
|
|
.Fn ifmedia_init ,
|
|
.Fn mii_attach ,
|
|
.Fn ifmedia_add ,
|
|
.Fn ifmedia_set ,
|
|
.Fn if_attach ,
|
|
.Fn ether_ifattach ,
|
|
.Fn rnd_attach_source ,
|
|
and
|
|
.Fn usbd_add_drv_event
|
|
should be eliminated.
|
|
The device
|
|
.Dq 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
|
|
.Dq 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.
|
|
.It MII handling
|
|
For devices with MII support the three normal callbacks
|
|
.Pq read, write, and status change
|
|
must be converted to
|
|
.Va usbnet .
|
|
Local
|
|
.Dq link
|
|
variables need to be replaced with accesses to
|
|
.Fn usbnet_set_link
|
|
and
|
|
.Fn usbnet_havelink .
|
|
Other ifmedia callbacks that were passed to
|
|
.Fn ifmedia_init
|
|
should be deleted and any work moved into
|
|
.Dq uno_statchg .
|
|
.It Receive and Transmit
|
|
The
|
|
.Nm
|
|
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
|
|
.Fn usbnet_init_rx_tx .
|
|
The typical receive handling will normally be replaced with a receive
|
|
loop functions that can accept one or more packets,
|
|
.Dq uno_rx_loop ,
|
|
which can use either
|
|
.Fn usbnet_enqueue
|
|
or
|
|
.Fn usbnet_input
|
|
to pass the packets up to higher layers.
|
|
The typical interface
|
|
.Dq if_start
|
|
function and any additional functions used will normal be replaced
|
|
with a relatively simple
|
|
.Dq uno_tx_prepare
|
|
function that simply converts an
|
|
.Va mbuf
|
|
into a
|
|
.Va usbnet_chain
|
|
useful for this device that will be passed onto
|
|
.Fn usbd_transfer .
|
|
The framework's handling of the Tx interrupt is all internal.
|
|
.It Interrupt pipe handling
|
|
For devices requiring special handling of the interrupt pipe (i.e.,
|
|
they use the
|
|
.Fn usbd_open_pipe_intr
|
|
method), most of the interrupt handler should be deleted, leaving
|
|
only code that inspects the result of the interrupt transfer.
|
|
.It Common errors
|
|
It's common to forget to set link active on devices with MII.
|
|
Be sure to call
|
|
.Fn usbnet_set_link
|
|
during any status change event.
|
|
.Pp
|
|
Many locking issues are hidden without
|
|
.Dv LOCKDEBUG ,
|
|
including hard-hangs.
|
|
It's highly recommended to develop with
|
|
.Dv LOCKDEBUG .
|
|
.Pp
|
|
The
|
|
.Va usbnet
|
|
.Dq un_ed
|
|
array is unsigned and should use
|
|
.Dq 0
|
|
as the no-endpoint value.
|
|
.El
|
|
.Sh SEE ALSO
|
|
.Xr usb 4 ,
|
|
.Xr driver 9 ,
|
|
.Xr usbd_status 9 ,
|
|
.Xr usbdi 9
|
|
.Sh HISTORY
|
|
This
|
|
.Nm
|
|
interface first appeared in
|
|
.Nx 9.0 .
|
|
Portions of the original design are based upon ideas from
|
|
.An Nick Hudson Aq Mt skrll@NetBSD.org .
|
|
.Sh AUTHORS
|
|
.An Matthew R. Green Aq Mt mrg@eterna23.net
|