1.\" $NetBSD: usbnet.9,v 1.14 2021/12/11 19:24:19 mrg Exp $ 2.\" 3.\" Copyright (c) 2019 Matthew R. Green 4.\" All rights reserved. 5.\" 6.\" Redistribution and use in source and binary forms, with or without 7.\" modification, are permitted provided that the following conditions 8.\" are met: 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" SUCH DAMAGE. 26.\" 27.Dd March 15, 2020 28.Dt USBNET 9 29.Os 30.Sh NAME 31.Nm usbnet 32.Nd common USB Ethernet driver framework 33.Sh SYNOPSIS 34.In dev/usb/usbnet.h 35.Ss Functions offered by usbnet.h 36.Ft void 37.Fn usbnet_set_link "struct usbnet *un" "bool link" 38.Ft void 39.Fn usbnet_set_dying "struct usbnet *un" "bool dying" 40.Ft struct ifnet * 41.Fn usbnet_ifp "struct usbnet *un" 42.Ft struct ethercom * 43.Fn usbnet_ec "struct usbnet *un" 44.Ft struct mii_data * 45.Fn usbnet_mii "struct usbnet *un" 46.Ft krndsource_t * 47.Fn usbnet_rndsrc "struct usbnet *un" 48.Ft void * 49.Fn usbnet_softc "struct usbnet *un" 50.Ft bool 51.Fn usbnet_havelink "struct usbnet *un" 52.Ft bool 53.Fn usbnet_isdying "struct usbnet *un" 54.Ft void 55.Fn usbnet_lock_core "struct usbnet *un" 56.Ft void 57.Fn usbnet_unlock_core "struct usbnet *un" 58.Ft kmutex_t * 59.Fn usbnet_mutex_core "struct usbnet *un" 60.Ft void 61.Fn usbnet_isowned_core "struct usbnet *un" 62.Ft void 63.Fn usbnet_lock_rx "struct usbnet *un" 64.Ft void 65.Fn usbnet_unlock_rx "struct usbnet *un" 66.Ft kmutex_t * 67.Fn usbnet_mutex_rx "struct usbnet *un" 68.Ft void 69.Fn usbnet_isowned_rx "struct usbnet *un" 70.Ft void 71.Fn usbnet_lock_tx "struct usbnet *un" 72.Ft void 73.Fn usbnet_unlock_tx "struct usbnet *un" 74.Ft kmutex_t * 75.Fn usbnet_mutex_tx "struct usbnet *un" 76.Ft void 77.Fn usbnet_isowned_tx "struct usbnet *un" 78.Ft int 79.Fn usbnet_init_rx_tx "struct usbnet *un" "unsigned rxflags" "unsigned txflags" 80.Ft int 81.Fn usbnet_miibus_readreg "device_t dev" "int phy" "int reg" "uint16_t *val" 82.Ft int 83.Fn usbnet_miibus_writereg "device_t dev" "int phy" "int reg" "uint16_t val" 84.Ft void 85.Fn usbnet_miibus_statchg "struct ifnet *" 86.Ft void 87.Fn usbnet_busy "struct usbnet *un" 88.Ft void 89.Fn usbnet_unbusy "struct usbnet *un" 90.Ft void 91.Fn usbnet_enqueue "struct usbnet *un" "uint8_t *buf" "size_t buflen" "int csum_flags" "uint32_t csum_data" "int mbuf_flags" 92.Ft void 93.Fn usbnet_input "struct usbnet *un" "uint8_t *buf" "size_t buflen" 94.Ft void 95.Fn usbnet_attach "struct usbnet *un" "const char *detname" 96.Ft void 97.Fn usbnet_attach_ifp "struct usbnet *un" "unsigned if_flags" "unsigned if_extflags" "const struct usbnet_mii *unm" 98.Ft int 99.Fn usbnet_detach "device_t dev" "int flags" 100.Ft int 101.Fn usbnet_activate "device_t dev" "devact_t act" 102.Ft void 103.Fn usbnet_stop "struct usbnet *un" "struct ifnet *ifp" "int disable" 104.Sh DESCRIPTION 105The 106.Nm 107framework provides methods usable for USB Ethernet drivers. 108The framework has support for these features: 109.Bl -bullet -offset 8n 110.It 111Partial autoconf handling 112.It 113USB endpoint pipe handling 114.It 115Rx and Tx chain handling 116.It 117Generic handlers or support for several struct ifnet callbacks 118.It 119Network stack locking protocol 120.It 121Interrupt handling 122.El 123.Pp 124.Nm 125provides many or all of the traditional 126.Dq softc 127members inside 128.Va struct usbnet , 129which can be used directly as the device softc structure if 130no additional storage is required. 131A structure exists for receive and transmit chain management, 132.Va struct usbnet_chain , 133that tracks the metadata for each transfer descriptor available, 134minimum of one each for Rx and Tx slot, and will be passed 135to the Rx and Tx callbacks. 136.Pp 137There is a 138.Va struct usbnet_ops 139structure that provides a number of optional and required callbacks 140that will be described below. 141.Pp 142For autoconfiguration the device attach routine is expected to 143ensure that this device's 144.Va struct usbnet 145is the first member of the device softc, if it can not be used directly 146as the device softc, as well as set up the necessary structure members, 147find end-points, find the Ethernet address if relevant, call 148.Fn usbnet_attach , 149set up interface, Ethernet, and MII capabilities, and finally call 150.Fn usbnet_attach_ifp . 151The device detach routine should free any resources allocated 152by attach and then call 153.Fn usbnet_detach , 154possibly directly using 155.Fn usbnet_detach 156as most consumers have no additional resources not owned and 157released by the 158.Nm 159framework itself. 160The device activate function should be set to 161.Fn usbnet_activate . 162.Pp 163To manage all Rx and Tx chains the 164.Dq uno_init 165callback of 166.Va struct usbnet_ops 167should perform any device specific initialization and then call 168.Fn usbnet_init_rx_tx 169which will allocate chains, set up and open pipes, and start the 170Rx transfers so that packets can arrived. 171These allocations and pipes can be closed and destroyed by calling 172.Fn usbnet_stop . 173Both of 174.Fn usbnet_init_rx_tx 175and 176.Fn usbnet_stop 177must be called with the 178.Nm 179lock held, see 180.Fn usbnet_lock 181and 182.Fn usbnet_unlock . 183See the 184.Sx RECEIVE AND SEND 185section for details on using the chains. 186.Pp 187The interface init, ioctl, start, and stop, routines are handled by the 188framework with callbacks for device-specific handling. 189For interface init (i.e., when bringing the interface up), the 190.Dq uno_init 191callback should perform any device specific initialization and then call 192.Fn usbnet_init_rx_tx 193to finalize Rx and Tx queue initialization. 194For interface ioctl, most of the handling is in the framework and the 195optional 196.Dq uno_ioctl 197callback should be used to program special settings 198like multicast filters or offload handling. 199If ioctl handling requires capturing device-specific ioctls then the 200.Dq uno_override_ioctl 201callback may be used instead to replace the framework's 202ioctl handler completely (i.e., the replacement should call any generic 203ioctl handlers such as 204.Fn ether_ioctl 205as required.) 206For interface start, the 207.Dq uno_tx_prepare 208callback must be used to convert 209an mbuf into a chain buffer ready for transmission. 210For interface stop, there is an optional 211.Dq uno_stop 212callback to turn off any chipset specific values if required. 213.Pp 214For devices requiring MII handling there are callbacks for reading and 215writing registers, and for status change events. 216The framework serializes MII access with the core lock, which will be 217held when calling these functions, and this lock should be used by 218internal code that also requires serialized access to registers with the 219.Fn usbnet_lock_core 220and 221.Fn usbnet_unlock_core 222functions. 223The MII callbacks handle device detach events safely; a reference count 224is taken and released around calls to the callbacks as the MII callbacks 225usually block. 226.Pp 227As receive must handle the case of multiple packets in one buffer, 228the support is split between the driver and the framework. 229A 230.Dq uno_rx_loop 231callback must be provided that loops over the incoming 232packet data found in a chain, performs necessary checking and passes 233the network frame up the stack via either 234.Fn usbnet_enqueue 235or 236.Fn usbnet_input . 237Typically Ethernet devices prefer 238.Fn usbnet_enqueue . 239.Pp 240General accessor functions for 241.Fa struct usbnet : 242.Bl -tag -width 4n 243.It Fn usbnet_set_link un link 244Set the link status for this 245.Fa un 246to 247.Fa link . 248.It Fn usbnet_set_dying un dying 249Set the dying status for this 250.Fa un 251to 252.Fa dying . 253.It Fn usbnet_ifp un 254Returns pointer to this 255.Fa un's 256.Va struct ifnet . 257.It Fn usbnet_ec un 258Returns pointer to this 259.Fa un's 260.Va struct ethercom . 261.It Fn usbnet_mii un 262Returns pointer to this 263.Fa un's 264.Va struct mii_data . 265.It Fn usbnet_rndsrc un 266Returns pointer to this 267.Fa un's 268.Va krndsource_t . 269.It Fn usbnet_softc un 270Returns pointer to this 271.Fa un's 272device softc. 273.It Fn usbnet_havelink un 274Returns true if link is active. 275.It Fn usbnet_isdying un 276Returns true if device is dying (has been pulled or deactivated, 277pending detach.) 278.El 279.Pp 280Reference counting functions for 281.Fa struct usbnet : 282.Bl -tag -width 4n 283.It Fn usbnet_busy un 284Increases the reference count on the driver instance, preventing 285detach from occurring while the driver is blocked accessing the 286device. 287Must be called with the core lock held. 288.It Fn usbnet_unbusy un 289Decreases the reference count on the driver instance. 290Once the final reference has been dropped, if a detach event 291is pending, it is allowed to proceed. 292Must be called with the core lock held. 293.El 294.Pp 295Lock handling functions for 296.Fa struct usbnet : 297.Pp 298.Bl -tag -width 4n -compact 299.It Fn usbnet_lock_core un 300.It Fn usbnet_unlock_core un 301.It Fn usbnet_isowned_core un 302.It Fn usbnet_lock_rx un 303.It Fn usbnet_unlock_rx un 304.It Fn usbnet_isowned_rx un 305.It Fn usbnet_lock_tx un 306.It Fn usbnet_unlock_tx un 307.It Fn usbnet_isowned_tx un 308These groups of three functions provide methods to lock, 309unlock, and assert ownership of one of the three locks provided by 310.Nm . 311The three locks are the 312.Dq core 313lock, the 314.Dq Tx 315lock, and the 316.Dq Rx 317lock. 318.El 319.Pp 320MII access functions for 321.Fa struct usbnet : 322.Bl -tag -width 4n 323.It Fn usbnet_mii_readreg dev phy reg valp 324Read register 325.Fa reg 326on PHY number 327.Fa phy 328and return the value in 329.Fa valp . 330Called with the core lock held. 331.It Fn usbnet_mii_writereg dev phy reg val 332Write register 333.Fa reg 334on PHY number 335.Fa phy 336with 337.Fa val . 338Called with the core lock held. 339.It Fn usbnet_mii_statchg ifp 340Trigger a status change update for interface 341.Fa ifp . 342Called with the core lock held. 343.El 344.Pp 345Buffer enqueue handling for 346.Fa struct usbnet : 347.Bl -tag -width 4n 348.It Fn usbnet_enqueue un buf buflen csum_flags csum_data mbuf_flags 349Enqueue buffer 350.Fa buf 351for length 352.Fa buflen 353with higher layers, using the provided 354.Fa csum_flags , 355and 356.Fa csum_data , 357which are written directly to the mbuf packet header, and 358.Fa mbuf_flags , 359which is or-ed into the mbuf flags for the created mbuf. 360.It Fn usbnet_input un buf buflen 361Enqueue buffer 362.Fa buf 363for length 364.Fa buflen 365with higher layers 366.El 367.Pp 368Autoconfiguration handling for 369.Fa struct usbnet . 370See the 371.Sx AUTOCONFIGURATION 372section for more details about these functions. 373.Bl -tag -width 4n 374.It Fn usbnet_attach un detachname 375Initial stage attach of a usb network device. 376The 377.Fa detachname 378will be used while waiting for final references to drain when detaching. 379.It Fn usbnet_attach_ifp un if_flags if_extflags unm 380Final stage attach of usb network device. 381If the passed in 382.Fa unm 383is 384.Pf non- Dv NULL 385then an MII interface will be created using the values 386provided in the 387.Fa struct usbnet_mii 388structure, which has these members passed to 389.Fn mii_attach : 390.Bl -tag -width 4n 391.It un_mii_flags 392Flags. 393.It un_mii_capmask 394Capability mask. 395.It un_mii_phyloc 396PHY location. 397.It un_mii_offset 398PHY offset. 399.El 400.Pp 401A default 402.Fa unm 403can be set using the 404.Fn USBNET_MII_DECL_DEFAULT 405macro. 406The 407.Fa if_flags 408and 409.Fa if_extflags 410will be or-ed into the interface flags and extflags. 411.It Fn usbnet_detach dev flags 412Device detach. 413Usable as actual device method. 414.It Fn usbnet_activate dev act 415Device activate (deactivate) method. 416Usable as actual device method. 417.It Fn usbnet_stop un ifp disable 418Interface stop routine. 419.El 420.Sh AUTOCONFIGURATION 421The framework expects the usbnet structure to have these members 422filled in with valid values or functions: 423.Bl -tag -width 6n 424.It un_sc 425Real softc allocated by autoconf and provided to attach, should be 426set to the usbnet structure if no device-specific softc is needed. 427.It un_dev 428device_t saved in attach, used for messages mostly. 429.It un_iface 430The USB iface handle for data interactions, see 431.Fn usbd_device2interface_handle 432for more details. 433.It un_udev 434The struct usbd_device for this device, provided as the usb_attach_arg's 435.Va uaa_device 436member. 437.It un_ops 438Points to a 439.Va struct usbnet_ops 440structure which contains these members: 441.Bl -tag -width 4n 442.It Ft void Fn (*uno_stop) "struct ifnet *ifp" "int disable" 443Stop interface 444.Pq optional . 445Called with the core lock held and with a busy reference. 446.It Ft int Fn (*uno_ioctl) "struct ifnet *ifp" "u_long cmd" "void *data" 447Simple ioctl callback 448.Pq optional . 449May be called with the ifnet lock held. 450.It Ft int Fn (*uno_override_ioctl) "struct ifnet *ifp" "u_long cmd" "void *data" 451Full ioctl callback 452.Pq optional . 453May be called with the ifnet lock held. 454.It Ft int Fn (*uno_init) "struct ifnet *ifp" 455Initialize (bring up) interface. 456Required. 457Called with the ifnet lock held. 458Must call 459.Fn usbnet_rx_tx_init . 460.It Ft int Fn (*uno_read_reg) "struct usbnet *un" "int phy" "int reg" "uint16_t *val" 461Read MII register. 462Required with MII. 463Called with the core lock held and with a busy reference. 464.It Ft int Fn (*uno_write_reg) "struct usbnet *un" "int phy" "int reg" "uint16_t val" 465Write MII register. 466Required with MII. 467Called with the core lock held and with a busy reference. 468.It Ft usbd_status Fn (*uno_statchg) "struct ifnet *ifp" 469Handle MII status change. 470Required with MII. 471Called with the core lock held and with a busy reference. 472.It Ft unsigned Fn (*uno_tx_prepare) "struct usbnet *un" "struct mbuf *m" "struct usbnet_chain *c" 473Prepare an mbuf for transmit. 474Required. 475Called with the Tx lock held. 476.It Ft void Fn (*uno_rx_loop) "struct usbnet *un" "struct usbnet_chain *c" "uint32_t total_len" 477Prepare one or more chain for enqueue. 478Required. 479Called with the Rx lock held. 480.It Ft void Fn (*uno_intr) "struct usbnet *un" "usbd_status status" 481Process periodic interrupt 482.Pq optional . 483Called with no locks held. 484.It Ft void Fn (*uno_tick) "struct usbnet *un" 485Called every second with USB task thread context 486.Pq optional . 487Called with no locks held, but a busy reference is maintained across this call. 488.El 489.It un_intr 490Points to a 491.Va struct usbnet_intr 492structure which should have these members set: 493.Bl -tag -width 4n 494.It uni_intr_buf 495If 496.Pf non- Dv NULL , 497points to a buffer passed to 498.Fn usbd_open_pipe_intr 499in the device init callback, along with the size and interval. 500.It uni_intr_bufsz 501Size of interrupt pipe buffer. 502.It uni_intr_interval 503Frequency of the interrupt in milliseconds. 504.El 505.It un_ed 506Array of endpoint descriptors. 507There indexes are provided: 508.Dv USBNET_ENDPT_RX , 509.Dv USBNET_ENDPT_TX , 510and 511.Dv USBNET_ENDPT_INTR . 512The Rx and Tx endpoints are required. 513.It un_phyno 514MII phy number. 515Not used by 516.Nm . 517.It un_eaddr 5186 bytes of Ethernet address that must be provided before calling 519.Fn usbnet_attach_ifp 520if the device has Ethernet. 521.It un_flags 522Device owned flags word. 523The 524.Nm 525framework will not touch this value. 526.It un_rx_xfer_flags 527Passed to 528.Fn usbd_setup_xfer 529for receiving packets. 530.It un_tx_xfer_flags 531Passed to 532.Fn usbd_setup_xfer 533for sending packets. 534.It un_rx_list_cnt 535Number of chain elements to allocate for Rx. 536.It un_tx_list_cnt 537Number of chain elements to allocate for Tx. 538.It un_rx_bufsz 539Rx buffer size. 540.It un_tx_bufsz 541Tx buffer size. 542.El 543.Pp 544The device detach and activate callbacks can typically be set to 545.Fn usbnet_detach 546and 547.Fn usbnet_activate 548unless device-specific handling is required, in which case, they 549can be called before or after such handling. 550.Pp 551The capabilities described in both 552.Va struct ifp 553and 554.Va struct ethercom 555must be set before calling 556.Fn usbnet_attach_ifp . 557.Sh RECEIVE AND SEND 558Receive and send routines are structured around a the 559.Va usbnet_cdata 560and 561.Va usbnet_chain 562structures, the 563.Dv un_ed , 564.Dv un_rx_xfer_flags , 565and 566.Dv un_tx_xfer_flags 567members, and the 568.Fn uno_stop , 569.Fn uno_init , 570.Fn uno_tx_prepare , 571and 572.Fn uno_rx_loop 573callbacks of 574.Va usbnet_ops . 575.Pp 576Typically, the device attach routine will fill in members of the 577.Va usbnet 578structure, as listed in 579.Sx AUTOCONFIGURATION . 580The 581.Dv un_ed 582array should have the 583.Dv USBNET_ENDPT_RX 584and 585.Dv USBNET_ENDPT_TX 586array entries filled in, and optionally the 587.Dv USBNET_ENDPT_INTR 588entry filled in if applicable. 589.Pp 590The optional 591.Fn uno_stop 592callback performs device-specific operations to shutdown the 593transmit or receive handling. 594.Fn uno_stop 595will be called with the usbnet lock held. 596.Pp 597The 598.Fn uno_init 599callback both performs device-specific enablement and then calls 600.Fn usbnet_rx_tx_init , 601which sets up the receive, transmit, and, optionally, the interrupt 602pipes, as well as starting the receive pipes. 603All USB transfer setup is handled internally to the framework, and 604the driver callbacks merely copy data in or out of a chain entry using 605what is typically a device-specific method. 606.Pp 607The 608.Fn uno_rx_loop 609callback converts the provided 610.Va usbnet_chain 611data and length into a series (one or more) of packets that are 612enqueued with the higher layers using either 613.Fn usbnet_enqueue 614(for most devices) or 615.Fn usbnet_input 616for devices that use 617.Fn if_input 618(this currently relies upon the 619.Va struct ifnet 620having the 621.Dq _if_input 622member set as well, which is true for current consumers.) 623The Rx lock will be held during this call, see 624.Fn usbnet_lock_rx 625and 626.Fn usbnet_unlock_rx . 627.Pp 628The 629.Fn uno_tx_prepare 630callback must convert the provided 631.Va struct mbuf 632into the provided 633.Va struct usbnet_chain 634performing any device-specific padding, checksum, header or other. 635Note that this callback must check that it is not attempting to copy 636more than the chain buffer size, as set in the 637.Va usbnet 638.Dq un_tx_bufsz 639member. 640This callback is only called once per packet. 641The Tx lock will be held during this call, see 642.Fn usbnet_lock_tx 643and 644.Fn usbnet_unlock_tx . 645.Pp 646The 647.Fa struct usbnet_chain 648structure which contains a 649.Dq unc_buf 650member which has the chain buffer allocated where data should be 651copied to or from for receive or transmit operations. 652It also contains pointers back to the owning 653.Fa struct usbnet , 654and the 655.Va struct usbd_xfer 656associated with this transfer. 657.Sh MII 658For devices that have MII support these callbacks in 659.Fa struct usbnet_ops 660must be provided: 661.Bl -tag -width 4n 662.It uno_read_reg 663Read an MII register for a particular PHY. 664Returns standard 665.Xr errno 2 . 666.It uno_write_reg 667Write an MII register for a particular PHY. 668Returns standard 669.Xr errno 2 . 670.It uno_statchg 671Handle a status change event for this interface. 672.El 673.Pp 674The read and write callbacks are called with the core lock held. 675See 676.Fn usbnet_lock_mii 677and 678.Fn usbnet_unlock_mii . 679.Sh INTERRUPT PIPE 680The interrupt specific callback, 681.Dq uno_intr , 682is an optional callback that can be called periodically, registered by 683.Nm 684using the 685.Fn usbd_open_pipe_intr 686function (instead of the 687.Fn usbd_open_pipe 688function.) 689The 690.Nm 691framework provides most of the interrupt handling and the callback 692simply inspects the returned buffer as necessary. 693To enable the this callback point the 694.Va struct usbnet 695member 696.Dq un_intr 697to a 698.Va struct usbnet_intr 699structure with these members set: 700.Bl -tag -width 4n 701.It uni_buf 702Data buffer for interrupt status relies. 703.It uni_bufsz 704Size of the above buffer. 705.It uni_interval 706Interval in millieconds. 707.El 708.Pp 709These values will be passed to 710.Fn usbd_open_pipe_intr . 711.Sh CONVERTING OLD-STYLE DRIVERS 712The porting of an older driver to the 713.Nm 714framework is largely an effort in deleting code. 715The process involves making these changes: 716.Bl -tag -width 4n 717.It Headers 718Many headers are included in 719.Pa usbnet.h 720and can be removed from the driver, as well as headers no longer used, 721such as 722.Pa callout.h 723and 724.Pa rndsource.h , 725etc. 726.It Device softc 727The majority of the driver's existing 728.Dq softc 729structure can likely be replaced with usage of 730.Va struct usbnet 731and its related functionality. 732This includes at least the device_t pointer, Ethernet address, the 733ethercom and mii_data structures, end point descriptors, usbd device, 734interface, and task and callout structures (both these probably go 735away entirely) and all the associated watchdog handling, 736timevals, list size, buffer size and xfer flags for 737both Rx, and Tx, and interrupt notices, interface flags, device link, 738PHY number, chain data, locks including Rx, Tx, MII, and the 739base softc lock. 740There is a driver-only 741.Dq un_flags 742in the 743.Va usbnet 744structure available for drivers to use. 745.Pp 746Many drivers can use the 747.Va usbnet 748structure as the device private storage passed to 749.Dv CFATTACH_DECL_NEW . 750Many internal functions to the driver may look better if switched to 751operate on the device's 752.Va usbnet 753as, for example, the 754.Va usbd_device 755value is now available (and must be set by the driver) in the 756.Va usbnet , 757which may be needed for any call to 758.Fn usbd_do_request . 759The standard endpoint values must be stored in the 760.Nm 761.Dq un_ed[] 762array. 763.Pp 764As 765.Nm 766manages xfer chains all code related to the opening, closing, aborting 767and transferring of data on pipes is performed by the framework based 768upon the buffer size and more provided in 769.Va subnet , 770so all code related to them should be deleted. 771.It Interface setup 772The vast majority of interface specific code should be deleted. 773For device-specific interface values, the 774.Va ifnet 775flags and exflags can be set, as well as the 776.Va ethercom 777.Dq ec_capabilities 778member, before calling 779.Fn usbnet_attach_ifp . 780All calls to 781.Fn ifmedia_init , 782.Fn mii_attach , 783.Fn ifmedia_add , 784.Fn ifmedia_set , 785.Fn if_attach , 786.Fn ether_ifattach , 787.Fn rnd_attach_source , 788and 789.Fn usbd_add_drv_event 790should be eliminated. 791The device 792.Dq ioctl 793routine can use the default handling with a callback for additional 794device specific programming (multicast filters, etc.), which can be 795empty, or, the override ioctl can be used for heavier requirements. 796The device 797.Dq stop 798routine is replaced with a simple call that turns off the 799device-specific transmitter and receiver if necessary, as the 800framework handles pipes and transfers and buffers. 801.It Device locking 802The 803.Nm 804framework provides three locks for the system: core lock, 805receive lock, and transmit lock. 806The normal locking order 807for these locks is ifnet lock -> usbnet core lock -> usbnet rxlock -> usbnet 808txlock, or, ifnet lock -> usbnet core lock. 809Also note that the core lock may be taken when the ifnet lock is not 810held. 811.It MII handling 812For devices with MII support the three normal callbacks 813.Pq read, write, and status change 814must be converted to 815.Va usbnet . 816These functions are called with the core lock is held 817.Po 818see 819.Dq Fn usbnet_isowned_core 820.Pc , 821and with a busy reference held and do not require any checking for running, 822or up, or dying devices. 823Local 824.Dq link 825variables need to be replaced with accesses to 826.Fn usbnet_set_link 827and 828.Fn usbnet_havelink . 829Other ifmedia callbacks that were passed to 830.Fn ifmedia_init 831should be deleted and any work moved into 832.Dq uno_statchg . 833.It Receive and Transmit 834The 835.Nm 836framework handles the majority of handling of both network directions. 837The interface init routine should keep all of the device specific setup 838but replace all pipe management with a call to 839.Fn usbnet_init_rx_tx . 840The typical receive handling will normally be replaced with a receive 841loop functions that can accept one or more packets, 842.Dq uno_rx_loop , 843which can use either 844.Fn usbnet_enqueue 845or 846.Fn usbnet_input 847to pass the packets up to higher layers. 848The typical interface 849.Dq if_start 850function and any additional functions used will normal be replaced 851with a relatively simple 852.Dq uno_tx_prepare 853function that simply converts an 854.Va mbuf 855into a 856.Va usbnet_chain 857useful for this device that will be passed onto 858.Fn usbd_transfer . 859The framework's handling of the Tx interrupt is all internal. 860.It Interrupt pipe handling 861For devices requiring special handling of the interrupt pipe (i.e., 862they use the 863.Fn usbd_open_pipe_intr 864method), most of the interrupt handler should be deleted, leaving 865only code that inspects the result of the interrupt transfer. 866.It Common errors 867It's common to forget to set link active on devices with MII. 868Be sure to call 869.Fn usbent_set_link 870during any status change event. 871.Pp 872Many locking issues are hidden without 873.Dv LOCKDEBUG , 874including hard-hangs. 875It's highly recommended to develop with 876.Dv LOCKDEBUG . 877.Pp 878The 879.Va usbnet 880.Dq un_ed 881array is unsigned and should use 882.Dq 0 883as the no-endpoint value. 884.El 885.Sh SEE ALSO 886.Xr usb 4 , 887.Xr driver 9 , 888.Xr usbd_status 9 , 889.Xr usbdi 9 890.Sh HISTORY 891This 892.Nm 893interface first appeared in 894.Nx 9.0 . 895Portions of the original design are based upon ideas from 896.An Nick Hudson Aq Mt skrll@NetBSD.org . 897.Sh AUTHORS 898.An Matthew R. Green Aq Mt mrg@eterna.com.au 899