1 /* $FreeBSD$ */ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4 * 5 * Copyright (c) 2008 Hans Petter Selasky. 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 * 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 * $FreeBSD$ 29 */ 30 31 #ifndef _USB_ETHERNET_H_ 32 #define _USB_ETHERNET_H_ 33 34 #include "net/usb_eth_drv.h" 35 36 /* FreeBSD net Interface flags */ 37 #define IFF_DRV_RUNNING 0x40 /* (d) resources allocated */ 38 39 #ifndef MCLSHIFT 40 #define MCLSHIFT 11 /* convert bytes to mbuf clusters */ 41 #endif /* MCLSHIFT */ 42 43 #define MCLBYTES (1 << MCLSHIFT) /* size of an mbuf cluster */ 44 45 /* 46 * Structure defining a queue for a network interface. 47 */ 48 struct ifqueue { 49 struct pbuf *ifq_head; 50 struct pbuf *ifq_tail; 51 int ifq_len; 52 }; 53 54 #define UE_LOCK(_ue) mtx_lock((_ue)->ue_mtx) 55 #define UE_UNLOCK(_ue) mtx_unlock((_ue)->ue_mtx) 56 #define UE_LOCK_ASSERT(_ue, t) mtx_assert((_ue)->ue_mtx, t) 57 58 #define IF_ENQUEUE(ifq, m) do { \ 59 if ((ifq)->ifq_tail == NULL) \ 60 (ifq)->ifq_head = m; \ 61 else \ 62 (ifq)->ifq_tail->next = m; \ 63 (ifq)->ifq_tail = m; \ 64 (ifq)->ifq_len++; \ 65 } while (0) 66 67 #define IF_DEQUEUE(ifq, m) do { \ 68 (m) = (ifq)->ifq_head; \ 69 if (m) { \ 70 if (((ifq)->ifq_head = (m)->next) == NULL) \ 71 (ifq)->ifq_tail = NULL; \ 72 (m)->next = NULL; \ 73 (ifq)->ifq_len--; \ 74 } \ 75 } while (0) 76 77 #define IF_PREPEND(ifq, m) \ 78 do { \ 79 (m)->next = (ifq)->ifq_head; \ 80 if ((ifq)->ifq_tail == NULL) \ 81 (ifq)->ifq_tail = (m); \ 82 (ifq)->ifq_head = (m); \ 83 (ifq)->ifq_len++; \ 84 } while (0) 85 86 struct usb_ether; 87 struct usb_device_request; 88 89 typedef void (uether_fn_t)(struct usb_ether *); 90 91 struct usb_ether_methods { 92 uether_fn_t *ue_attach_post; 93 uether_fn_t *ue_start; 94 uether_fn_t *ue_init; 95 uether_fn_t *ue_stop; 96 uether_fn_t *ue_setmulti; 97 uether_fn_t *ue_setpromisc; 98 uether_fn_t *ue_tick; 99 int (*ue_attach_post_sub)(struct usb_ether *); 100 }; 101 102 struct usb_ether_cfg_task { 103 struct usb_proc_msg hdr; 104 struct usb_ether *ue; 105 }; 106 107 struct usb_ether { 108 /* NOTE: the "ue_ifp" pointer must be first --hps */ 109 struct los_eth_driver *ue_drv_sc; 110 EVENT_CB_S ue_event; 111 struct mtx *ue_mtx; 112 const struct usb_ether_methods *ue_methods; 113 void *ue_sc; 114 struct usb_device *ue_udev; /* used by uether_do_request() */ 115 device_t ue_dev; 116 device_t ue_miibus; 117 118 struct usb_process ue_tq; 119 struct ifqueue ue_rxq; 120 struct ifqueue ue_txq; 121 struct callout ue_watchdog; 122 struct usb_ether_cfg_task ue_sync_task[2]; 123 struct usb_ether_cfg_task ue_media_task[2]; 124 struct usb_ether_cfg_task ue_multi_task[2]; 125 struct usb_ether_cfg_task ue_promisc_task[2]; 126 struct usb_ether_cfg_task ue_tick_task[2]; 127 128 int ue_unit; 129 130 /* ethernet address from eeprom */ 131 uint8_t ue_eaddr[NETIF_MAX_HWADDR_LEN]; 132 }; 133 134 #define uether_do_request(ue,req,data,timo) \ 135 usbd_do_request_proc((ue)->ue_udev,&(ue)->ue_tq,req,data,0,NULL,timo) 136 137 uint8_t uether_pause(struct usb_ether *, unsigned int); 138 void *uether_getsc(struct usb_ether *); 139 int uether_ifattach(struct usb_ether *); 140 void uether_ifattach_wait(struct usb_ether *); 141 void uether_ifdetach(struct usb_ether *); 142 struct pbuf *uether_newbuf(int length); 143 void uether_freebuf(struct pbuf *buf); 144 int uether_rxmbuf(struct usb_ether *, struct pbuf *, 145 unsigned int); 146 void uether_rxflush(struct usb_ether *); 147 uint8_t uether_is_gone(struct usb_ether *); 148 #endif /* _USB_ETHERNET_H_ */ 149