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