1 /* $NetBSD: usbnet.h,v 1.20 2021/03/01 22:59:52 mrg Exp $ */ 2 3 /* 4 * Copyright (c) 2019 Matthew R. Green 5 * All rights reserved. 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 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #ifndef _DEV_USB_USBNET_H 32 #define _DEV_USB_USBNET_H 33 34 /* 35 * Common code/data shared by all USB ethernet drivers (using these routines.) 36 * 37 * This framework provides the following features for USB ethernet drivers: 38 * 39 * - USB endpoint pipe handling 40 * - rx and tx chain handling 41 * - generic handlers or support for several struct ifnet callbacks 42 * - MII bus locking 43 * - interrupt handling 44 * - partial autoconf handling 45 * 46 * Consumers of this interface need to: 47 * 48 * - replace most softc members with "struct usbnet" usage, in particular 49 * use usbnet pointer for ifp->if_softc, and device_private (real softc 50 * can be stored in un_sc member) 51 * - use MII bus lock / access methods 52 * - usbnet_attach() to initialise and allocate rx/tx chains 53 * - usbnet_attach_ifp() to attach the interface, and either ether_ifattach() 54 * for ethernet devices, or if_alloc_sadl()/bpf_attach() pair otherwise. 55 * - usbnet_detach() to clean them up 56 * - usbnet_activate() for autoconf 57 * - interface ioctl and start have direct frontends with callbacks for 58 * device specific handling: 59 * - ioctl can use either a device-specific override (useful for special 60 * cases), but provides a normal handler with callback to handle 61 * ENETRESET conditions that should be sufficient for most users 62 * - start uses usbnet send callback 63 * - interface init and stop have helper functions 64 * - device specific init should use usbnet_init_rx_tx() to open pipes 65 * to the device and setup the rx/tx chains for use after any device 66 * specific setup 67 * - usbnet_stop() must be called with the un_lock held, and will 68 * call the device-specific usbnet stop callback, which enables the 69 * standard init calls stop idiom. 70 * - interrupt handling: 71 * - for rx, usbnet_init_rx_tx() will enable the receive pipes and 72 * call the rx_loop callback to handle device specific processing of 73 * packets, which can use usbnet_enqueue() to provide data to the 74 * higher layers 75 * - for tx, usbnet_start (if_start) will pull entries out of the 76 * transmit queue and use the send callback for the given mbuf. 77 * the usb callback will use usbnet_txeof() for the transmit 78 * completion function (internal to usbnet) 79 * - there is special interrupt pipe handling 80 * - timer/tick: 81 * - the uno_tick callback will be called once a second if present. 82 */ 83 84 #include <sys/device.h> 85 #include <sys/mbuf.h> 86 #include <sys/rndsource.h> 87 #include <sys/mutex.h> 88 #include <sys/module.h> 89 90 #include <net/bpf.h> 91 #include <net/if.h> 92 #include <net/if_arp.h> 93 #include <net/if_dl.h> 94 #include <net/if_ether.h> 95 #include <net/if_media.h> 96 97 #include <dev/mii/mii.h> 98 #include <dev/mii/miivar.h> 99 100 #include <dev/usb/usb.h> 101 #include <dev/usb/usbdi.h> 102 #include <dev/usb/usbdivar.h> 103 #include <dev/usb/usbdi_util.h> 104 #include <dev/usb/usbdevs.h> 105 106 /* 107 * Per-transfer data. 108 * 109 * Front-end must set un_rx_list_cnt and un_tx_list_cnt before 110 * calling usbnet_attach(), and then call usbnet_rx_tx_init() 111 * which will allocate the chain arrays, and must be NULL to 112 * indicate the first call. 113 */ 114 struct usbnet; 115 struct usbnet_chain { 116 struct usbnet *unc_un; 117 struct usbd_xfer *unc_xfer; 118 uint8_t *unc_buf; 119 }; 120 121 /* 122 * Extend this as necessary. axe(4) claims to want 6 total, but 123 * does not implement them. 124 */ 125 enum usbnet_ep { 126 USBNET_ENDPT_RX, 127 USBNET_ENDPT_TX, 128 USBNET_ENDPT_INTR, 129 USBNET_ENDPT_MAX, 130 }; 131 132 /* Interface stop callback. */ 133 typedef void (*usbnet_stop_cb)(struct ifnet *, int); 134 /* Interface ioctl callback. */ 135 typedef int (*usbnet_ioctl_cb)(struct ifnet *, u_long, void *); 136 /* Initialise device callback. */ 137 typedef int (*usbnet_init_cb)(struct ifnet *); 138 139 /* MII read register callback. */ 140 typedef int (*usbnet_mii_read_reg_cb)(struct usbnet *, int reg, 141 int phy, uint16_t *val); 142 /* MII write register callback. */ 143 typedef int (*usbnet_mii_write_reg_cb)(struct usbnet *, int reg, 144 int phy, uint16_t val); 145 /* MII status change callback. */ 146 typedef void (*usbnet_mii_statchg_cb)(struct ifnet *); 147 148 /* Prepare packet to send callback, returns length. */ 149 typedef unsigned (*usbnet_tx_prepare_cb)(struct usbnet *, struct mbuf *, 150 struct usbnet_chain *); 151 /* Receive some packets callback. */ 152 typedef void (*usbnet_rx_loop_cb)(struct usbnet *, struct usbnet_chain *, 153 uint32_t); 154 /* Tick callback. */ 155 typedef void (*usbnet_tick_cb)(struct usbnet *); 156 /* Interrupt pipe callback. */ 157 typedef void (*usbnet_intr_cb)(struct usbnet *, usbd_status); 158 159 /* 160 * LOCKING 161 * ======= 162 * 163 * The following annotations indicate which locks are held when 164 * usbnet_ops functions are invoked: 165 * 166 * I -> IFNET_LOCK (if_ioctl_lock) 167 * C -> CORE_LOCK (usbnet core_lock) 168 * T -> TX_LOCK (usbnet tx_lock) 169 * R -> RX_LOCK (usbnet rx_lock) 170 * n -> no locks held 171 * 172 * Note that when CORE_LOCK is held, IFNET_LOCK may or may not also 173 * be held. 174 * 175 * Note that the IFNET_LOCK **may not be held** for some ioctl 176 * operations (add/delete multicast addresses, for example). 177 * 178 * Busy reference counts are maintained across calls to: uno_stop, 179 * uno_read_reg, uno_write_reg, uno_statchg, and uno_tick. 180 */ 181 struct usbnet_ops { 182 usbnet_stop_cb uno_stop; /* C */ 183 usbnet_ioctl_cb uno_ioctl; /* I (maybe) */ 184 usbnet_ioctl_cb uno_override_ioctl; /* I (maybe) */ 185 usbnet_init_cb uno_init; /* I */ 186 usbnet_mii_read_reg_cb uno_read_reg; /* C */ 187 usbnet_mii_write_reg_cb uno_write_reg; /* C */ 188 usbnet_mii_statchg_cb uno_statchg; /* C */ 189 usbnet_tx_prepare_cb uno_tx_prepare; /* T */ 190 usbnet_rx_loop_cb uno_rx_loop; /* R */ 191 usbnet_tick_cb uno_tick; /* n */ 192 usbnet_intr_cb uno_intr; /* n */ 193 }; 194 195 /* 196 * USB interrupt pipe support. Use this if usbd_open_pipe_intr() should 197 * be used for the interrupt pipe. 198 */ 199 struct usbnet_intr { 200 /* 201 * Point un_intr to this structure to use usbd_open_pipe_intr() not 202 * usbd_open_pipe() for USBNET_ENDPT_INTR, with this buffer, size, 203 * and interval. 204 */ 205 void *uni_buf; 206 unsigned uni_bufsz; 207 unsigned uni_interval; 208 }; 209 210 /* 211 * Structure to setup MII. Use the USBNET_MII_DECL_DEFAULT() macro for 212 * sane default. Pass a copy to usbnet_attach_ifp(). Not used 213 * after the usbnet_attach_ifp() function returns. 214 */ 215 struct usbnet_mii { 216 int un_mii_flags; 217 int un_mii_capmask; 218 int un_mii_phyloc; 219 int un_mii_offset; 220 }; 221 222 #define USBNET_MII_DECL(name, capmask, loc, off, flags) \ 223 struct usbnet_mii name = { \ 224 .un_mii_capmask = capmask, \ 225 .un_mii_phyloc = loc, \ 226 .un_mii_offset = off, \ 227 .un_mii_flags = flags, \ 228 } 229 #define USBNET_MII_DECL_DEFAULT(name) \ 230 USBNET_MII_DECL(name, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0) 231 232 /* 233 * Generic USB ethernet structure. Use this as ifp->if_softc and set as 234 * device_private() in attach unless already using struct usbnet here. 235 * 236 * Devices without MII should call usbnet_attach_ifp() with have_mii set 237 * to true, and should ensure that the un_statchg_cb callback sets the 238 * un_link member. Devices without MII have this forced to true. 239 */ 240 struct usbnet_private; 241 struct usbnet { 242 /* 243 * This section should be filled in before calling 244 * usbnet_attach(). 245 */ 246 void *un_sc; /* real softc */ 247 device_t un_dev; 248 struct usbd_interface *un_iface; 249 struct usbd_device *un_udev; 250 const struct usbnet_ops *un_ops; 251 struct usbnet_intr *un_intr; 252 253 /* Inputs for rx/tx chain control. */ 254 unsigned un_rx_bufsz; 255 unsigned un_tx_bufsz; 256 unsigned un_rx_list_cnt; 257 unsigned un_tx_list_cnt; 258 int un_rx_xfer_flags; 259 int un_tx_xfer_flags; 260 261 /* 262 * This section should be filled in before calling 263 * usbnet_attach_ifp(). 264 * 265 * XXX This should be of type "uByte". enum usbnet_ep 266 * is the index. Fix this in a kernel version bump. 267 */ 268 enum usbnet_ep un_ed[USBNET_ENDPT_MAX]; 269 270 /* MII specific. Not used without MII. */ 271 int un_phyno; 272 /* Ethernet specific. All zeroes indicates non-Ethernet. */ 273 uint8_t un_eaddr[ETHER_ADDR_LEN]; 274 275 /* 276 * This section is for driver to use, not touched by usbnet. 277 */ 278 unsigned un_flags; 279 280 /* 281 * This section is private to usbnet. Don't touch. 282 */ 283 struct usbnet_private *un_pri; 284 }; 285 286 /* Various accessors. */ 287 288 void usbnet_set_link(struct usbnet *, bool); 289 void usbnet_set_dying(struct usbnet *, bool); 290 291 struct ifnet *usbnet_ifp(struct usbnet *); 292 struct ethercom *usbnet_ec(struct usbnet *); 293 struct mii_data *usbnet_mii(struct usbnet *); 294 krndsource_t *usbnet_rndsrc(struct usbnet *); 295 void *usbnet_softc(struct usbnet *); 296 297 bool usbnet_havelink(struct usbnet *); 298 bool usbnet_isdying(struct usbnet *); 299 300 301 /* 302 * Locking. Note that the isowned() are implemented here so that 303 * empty-KASSERT() causes them to be elided for non-DIAG builds. 304 */ 305 void usbnet_lock_core(struct usbnet *); 306 void usbnet_unlock_core(struct usbnet *); 307 kmutex_t *usbnet_mutex_core(struct usbnet *); 308 static __inline__ void 309 usbnet_isowned_core(struct usbnet *un) 310 { 311 KASSERT(mutex_owned(usbnet_mutex_core(un))); 312 } 313 314 void usbnet_busy(struct usbnet *); 315 void usbnet_unbusy(struct usbnet *); 316 317 void usbnet_lock_rx(struct usbnet *); 318 void usbnet_unlock_rx(struct usbnet *); 319 kmutex_t *usbnet_mutex_rx(struct usbnet *); 320 static __inline__ void 321 usbnet_isowned_rx(struct usbnet *un) 322 { 323 KASSERT(mutex_owned(usbnet_mutex_rx(un))); 324 } 325 326 void usbnet_lock_tx(struct usbnet *); 327 void usbnet_unlock_tx(struct usbnet *); 328 kmutex_t *usbnet_mutex_tx(struct usbnet *); 329 static __inline__ void 330 usbnet_isowned_tx(struct usbnet *un) 331 { 332 KASSERT(mutex_owned(usbnet_mutex_tx(un))); 333 } 334 335 /* 336 * Endpoint / rx/tx chain management: 337 * 338 * usbnet_attach() initialises usbnet and allocates rx and tx chains 339 * usbnet_init_rx_tx() open pipes, initialises the rx/tx chains for use 340 * usbnet_stop() stops pipes, cleans (not frees) rx/tx chains, locked 341 * version assumes un_lock is held 342 * usbnet_detach() frees the rx/tx chains 343 * 344 * Setup un_ed[] with valid end points before calling usbnet_attach(). 345 * Call usbnet_init_rx_tx() to initialise pipes, which will be open 346 * upon success. 347 */ 348 int usbnet_init_rx_tx(struct usbnet * const); 349 350 /* MII. */ 351 int usbnet_mii_readreg(device_t, int, int, uint16_t *); 352 int usbnet_mii_writereg(device_t, int, int, uint16_t); 353 void usbnet_mii_statchg(struct ifnet *); 354 355 /* interrupt handling */ 356 void usbnet_enqueue(struct usbnet * const, uint8_t *, size_t, int, 357 uint32_t, int); 358 void usbnet_input(struct usbnet * const, uint8_t *, size_t); 359 360 /* autoconf */ 361 void usbnet_attach(struct usbnet *un, const char *); 362 void usbnet_attach_ifp(struct usbnet *, unsigned, unsigned, 363 const struct usbnet_mii *); 364 int usbnet_detach(device_t, int); 365 int usbnet_activate(device_t, devact_t); 366 367 /* stop backend */ 368 void usbnet_stop(struct usbnet *, struct ifnet *, int); 369 370 /* module hook up */ 371 372 #ifdef _MODULE 373 #define USBNET_INIT(name) \ 374 error = config_init_component(cfdriver_ioconf_##name, \ 375 cfattach_ioconf_##name, cfdata_ioconf_##name); 376 #define USBNET_FINI(name) \ 377 error = config_fini_component(cfdriver_ioconf_##name, \ 378 cfattach_ioconf_##name, cfdata_ioconf_##name); 379 #else 380 #define USBNET_INIT(name) 381 #define USBNET_FINI(name) 382 #endif 383 384 #define USBNET_MODULE(name) \ 385 \ 386 MODULE(MODULE_CLASS_DRIVER, if_##name, "usbnet"); \ 387 \ 388 static int \ 389 if_##name##_modcmd(modcmd_t cmd, void *aux) \ 390 { \ 391 int error = 0; \ 392 \ 393 switch (cmd) { \ 394 case MODULE_CMD_INIT: \ 395 USBNET_INIT(name) \ 396 return error; \ 397 case MODULE_CMD_FINI: \ 398 USBNET_FINI(name) \ 399 return error; \ 400 default: \ 401 return ENOTTY; \ 402 } \ 403 } 404 405 #endif /* _DEV_USB_USBNET_H */ 406