Thu Mar 3 05:47:43 2022 UTC ()
usbnet: Don't check if_flags for IFF_RUNNING in usbnet_rxeof.

This can only run after we start the pipes in usbnet_init_rx_tx, and
before we abort the pipes in usbnet_stop, during which time if_flags
& IFF_RUNNING is stably set.


(riastradh)
diff -r1.51 -r1.52 src/sys/dev/usb/usbnet.c

cvs diff -r1.51 -r1.52 src/sys/dev/usb/usbnet.c (switch to unified diff)

--- src/sys/dev/usb/usbnet.c 2022/03/03 05:47:36 1.51
+++ src/sys/dev/usb/usbnet.c 2022/03/03 05:47:43 1.52
@@ -1,1349 +1,1348 @@ @@ -1,1349 +1,1348 @@
1/* $NetBSD: usbnet.c,v 1.51 2022/03/03 05:47:36 riastradh Exp $ */ 1/* $NetBSD: usbnet.c,v 1.52 2022/03/03 05:47:43 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/* 29/*
30 * Common code shared between USB network drivers. 30 * Common code shared between USB network drivers.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.51 2022/03/03 05:47:36 riastradh Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.52 2022/03/03 05:47:43 riastradh Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/kmem.h> 38#include <sys/kmem.h>
39#include <sys/module.h> 39#include <sys/module.h>
40#include <sys/atomic.h> 40#include <sys/atomic.h>
41 41
42#include <dev/usb/usbnet.h> 42#include <dev/usb/usbnet.h>
43#include <dev/usb/usbhist.h> 43#include <dev/usb/usbhist.h>
44 44
45struct usbnet_cdata { 45struct usbnet_cdata {
46 struct usbnet_chain *uncd_tx_chain; 46 struct usbnet_chain *uncd_tx_chain;
47 struct usbnet_chain *uncd_rx_chain; 47 struct usbnet_chain *uncd_rx_chain;
48 48
49 int uncd_tx_prod; 49 int uncd_tx_prod;
50 int uncd_tx_cnt; 50 int uncd_tx_cnt;
51}; 51};
52 52
53struct usbnet_private { 53struct usbnet_private {
54 /* 54 /*
55 * - unp_core_lock protects most of this structure, the public one, 55 * - unp_core_lock protects most of this structure, the public one,
56 * and the MII / media data. 56 * and the MII / media data.
57 * - unp_rxlock protects the rx path and its data 57 * - unp_rxlock protects the rx path and its data
58 * - unp_txlock protects the tx path and its data 58 * - unp_txlock protects the tx path and its data
59 * - unp_detachcv handles detach vs open references 59 * - unp_detachcv handles detach vs open references
60 * 60 *
61 * the lock ordering is: 61 * the lock ordering is:
62 * ifnet lock -> unp_core_lock -> unp_rxlock -> unp_txlock 62 * ifnet lock -> unp_core_lock -> unp_rxlock -> unp_txlock
63 * - ifnet lock is not needed for unp_core_lock, but if ifnet lock is 63 * - ifnet lock is not needed for unp_core_lock, but if ifnet lock is
64 * involved, it must be taken first 64 * involved, it must be taken first
65 */ 65 */
66 kmutex_t unp_core_lock; 66 kmutex_t unp_core_lock;
67 kmutex_t unp_rxlock; 67 kmutex_t unp_rxlock;
68 kmutex_t unp_txlock; 68 kmutex_t unp_txlock;
69 kcondvar_t unp_detachcv; 69 kcondvar_t unp_detachcv;
70 70
71 struct usbnet_cdata unp_cdata; 71 struct usbnet_cdata unp_cdata;
72 72
73 struct ethercom unp_ec; 73 struct ethercom unp_ec;
74 struct mii_data unp_mii; 74 struct mii_data unp_mii;
75 struct usb_task unp_mcasttask; 75 struct usb_task unp_mcasttask;
76 struct usb_task unp_ticktask; 76 struct usb_task unp_ticktask;
77 struct callout unp_stat_ch; 77 struct callout unp_stat_ch;
78 struct usbd_pipe *unp_ep[USBNET_ENDPT_MAX]; 78 struct usbd_pipe *unp_ep[USBNET_ENDPT_MAX];
79 79
80 bool unp_dying; 80 bool unp_dying;
81 bool unp_stopping; 81 bool unp_stopping;
82 bool unp_attached; 82 bool unp_attached;
83 bool unp_ifp_attached; 83 bool unp_ifp_attached;
84 bool unp_link; 84 bool unp_link;
85 85
86 int unp_refcnt; 86 int unp_refcnt;
87 int unp_timer; 87 int unp_timer;
88 unsigned short unp_if_flags; 88 unsigned short unp_if_flags;
89 unsigned unp_number; 89 unsigned unp_number;
90 90
91 krndsource_t unp_rndsrc; 91 krndsource_t unp_rndsrc;
92 92
93 struct timeval unp_rx_notice; 93 struct timeval unp_rx_notice;
94 struct timeval unp_tx_notice; 94 struct timeval unp_tx_notice;
95 struct timeval unp_intr_notice; 95 struct timeval unp_intr_notice;
96}; 96};
97 97
98#define un_cdata(un) (&(un)->un_pri->unp_cdata) 98#define un_cdata(un) (&(un)->un_pri->unp_cdata)
99 99
100volatile unsigned usbnet_number; 100volatile unsigned usbnet_number;
101 101
102static int usbnet_modcmd(modcmd_t, void *); 102static int usbnet_modcmd(modcmd_t, void *);
103 103
104#ifdef USB_DEBUG 104#ifdef USB_DEBUG
105#ifndef USBNET_DEBUG 105#ifndef USBNET_DEBUG
106#define usbnetdebug 0 106#define usbnetdebug 0
107#else 107#else
108static int usbnetdebug = 0; 108static int usbnetdebug = 0;
109 109
110SYSCTL_SETUP(sysctl_hw_usbnet_setup, "sysctl hw.usbnet setup") 110SYSCTL_SETUP(sysctl_hw_usbnet_setup, "sysctl hw.usbnet setup")
111{ 111{
112 int err; 112 int err;
113 const struct sysctlnode *rnode; 113 const struct sysctlnode *rnode;
114 const struct sysctlnode *cnode; 114 const struct sysctlnode *cnode;
115 115
116 err = sysctl_createv(clog, 0, NULL, &rnode, 116 err = sysctl_createv(clog, 0, NULL, &rnode,
117 CTLFLAG_PERMANENT, CTLTYPE_NODE, "usbnet", 117 CTLFLAG_PERMANENT, CTLTYPE_NODE, "usbnet",
118 SYSCTL_DESCR("usbnet global controls"), 118 SYSCTL_DESCR("usbnet global controls"),
119 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 119 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
120 120
121 if (err) 121 if (err)
122 goto fail; 122 goto fail;
123 123
124 /* control debugging printfs */ 124 /* control debugging printfs */
125 err = sysctl_createv(clog, 0, &rnode, &cnode, 125 err = sysctl_createv(clog, 0, &rnode, &cnode,
126 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 126 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
127 "debug", SYSCTL_DESCR("Enable debugging output"), 127 "debug", SYSCTL_DESCR("Enable debugging output"),
128 NULL, 0, &usbnetdebug, sizeof(usbnetdebug), CTL_CREATE, CTL_EOL); 128 NULL, 0, &usbnetdebug, sizeof(usbnetdebug), CTL_CREATE, CTL_EOL);
129 if (err) 129 if (err)
130 goto fail; 130 goto fail;
131 131
132 return; 132 return;
133fail: 133fail:
134 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 134 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
135} 135}
136 136
137#endif /* USBNET_DEBUG */ 137#endif /* USBNET_DEBUG */
138#endif /* USB_DEBUG */ 138#endif /* USB_DEBUG */
139 139
140#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(usbnetdebug,1,FMT,A,B,C,D) 140#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(usbnetdebug,1,FMT,A,B,C,D)
141#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usbnetdebug,N,FMT,A,B,C,D) 141#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usbnetdebug,N,FMT,A,B,C,D)
142#define USBNETHIST_FUNC() USBHIST_FUNC() 142#define USBNETHIST_FUNC() USBHIST_FUNC()
143#define USBNETHIST_CALLED(name) USBHIST_CALLED(usbnetdebug) 143#define USBNETHIST_CALLED(name) USBHIST_CALLED(usbnetdebug)
144#define USBNETHIST_CALLARGS(FMT,A,B,C,D) \ 144#define USBNETHIST_CALLARGS(FMT,A,B,C,D) \
145 USBHIST_CALLARGS(usbnetdebug,FMT,A,B,C,D) 145 USBHIST_CALLARGS(usbnetdebug,FMT,A,B,C,D)
146#define USBNETHIST_CALLARGSN(N,FMT,A,B,C,D) \ 146#define USBNETHIST_CALLARGSN(N,FMT,A,B,C,D) \
147 USBHIST_CALLARGSN(usbnetdebug,N,FMT,A,B,C,D) 147 USBHIST_CALLARGSN(usbnetdebug,N,FMT,A,B,C,D)
148 148
149/* Callback vectors. */ 149/* Callback vectors. */
150 150
151static void 151static void
152uno_stop(struct usbnet *un, struct ifnet *ifp, int disable) 152uno_stop(struct usbnet *un, struct ifnet *ifp, int disable)
153{ 153{
154 KASSERTMSG(!un->un_pri->unp_ifp_attached || IFNET_LOCKED(ifp), 154 KASSERTMSG(!un->un_pri->unp_ifp_attached || IFNET_LOCKED(ifp),
155 "%s", ifp->if_xname); 155 "%s", ifp->if_xname);
156 usbnet_isowned_core(un); 156 usbnet_isowned_core(un);
157 if (un->un_ops->uno_stop) 157 if (un->un_ops->uno_stop)
158 (*un->un_ops->uno_stop)(ifp, disable); 158 (*un->un_ops->uno_stop)(ifp, disable);
159} 159}
160 160
161static int 161static int
162uno_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data) 162uno_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data)
163{ 163{
164 /* 164 /*
165 * There are cases where IFNET_LOCK will not be held when we 165 * There are cases where IFNET_LOCK will not be held when we
166 * are called (e.g. add/delete multicast address), so we can't 166 * are called (e.g. add/delete multicast address), so we can't
167 * assert it. 167 * assert it.
168 */ 168 */
169 if (un->un_ops->uno_ioctl) 169 if (un->un_ops->uno_ioctl)
170 return (*un->un_ops->uno_ioctl)(ifp, cmd, data); 170 return (*un->un_ops->uno_ioctl)(ifp, cmd, data);
171 return 0; 171 return 0;
172} 172}
173 173
174static int 174static int
175uno_override_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data) 175uno_override_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data)
176{ 176{
177 /* See above. */ 177 /* See above. */
178 return (*un->un_ops->uno_override_ioctl)(ifp, cmd, data); 178 return (*un->un_ops->uno_override_ioctl)(ifp, cmd, data);
179} 179}
180 180
181static int 181static int
182uno_init(struct usbnet *un, struct ifnet *ifp) 182uno_init(struct usbnet *un, struct ifnet *ifp)
183{ 183{
184 KASSERT(IFNET_LOCKED(ifp)); 184 KASSERT(IFNET_LOCKED(ifp));
185 return (*un->un_ops->uno_init)(ifp); 185 return (*un->un_ops->uno_init)(ifp);
186} 186}
187 187
188static int 188static int
189uno_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 189uno_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
190{ 190{
191 usbnet_isowned_core(un); 191 usbnet_isowned_core(un);
192 return (*un->un_ops->uno_read_reg)(un, phy, reg, val); 192 return (*un->un_ops->uno_read_reg)(un, phy, reg, val);
193} 193}
194 194
195static int 195static int
196uno_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 196uno_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
197{ 197{
198 usbnet_isowned_core(un); 198 usbnet_isowned_core(un);
199 return (*un->un_ops->uno_write_reg)(un, phy, reg, val); 199 return (*un->un_ops->uno_write_reg)(un, phy, reg, val);
200} 200}
201 201
202static void 202static void
203uno_mii_statchg(struct usbnet *un, struct ifnet *ifp) 203uno_mii_statchg(struct usbnet *un, struct ifnet *ifp)
204{ 204{
205 usbnet_isowned_core(un); 205 usbnet_isowned_core(un);
206 (*un->un_ops->uno_statchg)(ifp); 206 (*un->un_ops->uno_statchg)(ifp);
207} 207}
208 208
209static unsigned 209static unsigned
210uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 210uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
211{ 211{
212 usbnet_isowned_tx(un); 212 usbnet_isowned_tx(un);
213 return (*un->un_ops->uno_tx_prepare)(un, m, c); 213 return (*un->un_ops->uno_tx_prepare)(un, m, c);
214} 214}
215 215
216static void 216static void
217uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 217uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
218{ 218{
219 usbnet_isowned_rx(un); 219 usbnet_isowned_rx(un);
220 (*un->un_ops->uno_rx_loop)(un, c, total_len); 220 (*un->un_ops->uno_rx_loop)(un, c, total_len);
221} 221}
222 222
223static void 223static void
224uno_tick(struct usbnet *un) 224uno_tick(struct usbnet *un)
225{ 225{
226 if (un->un_ops->uno_tick) 226 if (un->un_ops->uno_tick)
227 (*un->un_ops->uno_tick)(un); 227 (*un->un_ops->uno_tick)(un);
228} 228}
229 229
230static void 230static void
231uno_intr(struct usbnet *un, usbd_status status) 231uno_intr(struct usbnet *un, usbd_status status)
232{ 232{
233 if (un->un_ops->uno_intr) 233 if (un->un_ops->uno_intr)
234 (*un->un_ops->uno_intr)(un, status); 234 (*un->un_ops->uno_intr)(un, status);
235} 235}
236 236
237/* Interrupt handling. */ 237/* Interrupt handling. */
238 238
239static struct mbuf * 239static struct mbuf *
240usbnet_newbuf(size_t buflen) 240usbnet_newbuf(size_t buflen)
241{ 241{
242 struct mbuf *m; 242 struct mbuf *m;
243 243
244 if (buflen > MCLBYTES) 244 if (buflen > MCLBYTES)
245 return NULL; 245 return NULL;
246 246
247 MGETHDR(m, M_DONTWAIT, MT_DATA); 247 MGETHDR(m, M_DONTWAIT, MT_DATA);
248 if (m == NULL) 248 if (m == NULL)
249 return NULL; 249 return NULL;
250 250
251 if (buflen > MHLEN - ETHER_ALIGN) { 251 if (buflen > MHLEN - ETHER_ALIGN) {
252 MCLGET(m, M_DONTWAIT); 252 MCLGET(m, M_DONTWAIT);
253 if (!(m->m_flags & M_EXT)) { 253 if (!(m->m_flags & M_EXT)) {
254 m_freem(m); 254 m_freem(m);
255 return NULL; 255 return NULL;
256 } 256 }
257 } 257 }
258 258
259 m_adj(m, ETHER_ALIGN); 259 m_adj(m, ETHER_ALIGN);
260 m->m_len = m->m_pkthdr.len = buflen; 260 m->m_len = m->m_pkthdr.len = buflen;
261 261
262 return m; 262 return m;
263} 263}
264 264
265/* 265/*
266 * usbnet_rxeof() is designed to be the done callback for rx completion. 266 * usbnet_rxeof() is designed to be the done callback for rx completion.
267 * it provides generic setup and finalisation, calls a different usbnet 267 * it provides generic setup and finalisation, calls a different usbnet
268 * rx_loop callback in the middle, which can use usbnet_enqueue() to 268 * rx_loop callback in the middle, which can use usbnet_enqueue() to
269 * enqueue a packet for higher levels (or usbnet_input() if previously 269 * enqueue a packet for higher levels (or usbnet_input() if previously
270 * using if_input() path.) 270 * using if_input() path.)
271 */ 271 */
272void 272void
273usbnet_enqueue(struct usbnet * const un, uint8_t *buf, size_t buflen, 273usbnet_enqueue(struct usbnet * const un, uint8_t *buf, size_t buflen,
274 int csum_flags, uint32_t csum_data, int mbuf_flags) 274 int csum_flags, uint32_t csum_data, int mbuf_flags)
275{ 275{
276 USBNETHIST_FUNC(); 276 USBNETHIST_FUNC();
277 struct ifnet * const ifp = usbnet_ifp(un); 277 struct ifnet * const ifp = usbnet_ifp(un);
278 struct usbnet_private * const unp __unused = un->un_pri; 278 struct usbnet_private * const unp __unused = un->un_pri;
279 struct mbuf *m; 279 struct mbuf *m;
280 280
281 USBNETHIST_CALLARGSN(5, "%jd: enter: len=%ju csf %#jx mbf %#jx", 281 USBNETHIST_CALLARGSN(5, "%jd: enter: len=%ju csf %#jx mbf %#jx",
282 unp->unp_number, buflen, csum_flags, mbuf_flags); 282 unp->unp_number, buflen, csum_flags, mbuf_flags);
283 283
284 usbnet_isowned_rx(un); 284 usbnet_isowned_rx(un);
285 285
286 m = usbnet_newbuf(buflen); 286 m = usbnet_newbuf(buflen);
287 if (m == NULL) { 287 if (m == NULL) {
288 DPRINTF("%jd: no memory", unp->unp_number, 0, 0, 0); 288 DPRINTF("%jd: no memory", unp->unp_number, 0, 0, 0);
289 if_statinc(ifp, if_ierrors); 289 if_statinc(ifp, if_ierrors);
290 return; 290 return;
291 } 291 }
292 292
293 m_set_rcvif(m, ifp); 293 m_set_rcvif(m, ifp);
294 m->m_pkthdr.csum_flags = csum_flags; 294 m->m_pkthdr.csum_flags = csum_flags;
295 m->m_pkthdr.csum_data = csum_data; 295 m->m_pkthdr.csum_data = csum_data;
296 m->m_flags |= mbuf_flags; 296 m->m_flags |= mbuf_flags;
297 memcpy(mtod(m, uint8_t *), buf, buflen); 297 memcpy(mtod(m, uint8_t *), buf, buflen);
298 298
299 /* push the packet up */ 299 /* push the packet up */
300 if_percpuq_enqueue(ifp->if_percpuq, m); 300 if_percpuq_enqueue(ifp->if_percpuq, m);
301} 301}
302 302
303void 303void
304usbnet_input(struct usbnet * const un, uint8_t *buf, size_t buflen) 304usbnet_input(struct usbnet * const un, uint8_t *buf, size_t buflen)
305{ 305{
306 USBNETHIST_FUNC(); 306 USBNETHIST_FUNC();
307 struct ifnet * const ifp = usbnet_ifp(un); 307 struct ifnet * const ifp = usbnet_ifp(un);
308 struct usbnet_private * const unp __unused = un->un_pri; 308 struct usbnet_private * const unp __unused = un->un_pri;
309 struct mbuf *m; 309 struct mbuf *m;
310 310
311 USBNETHIST_CALLARGSN(5, "%jd: enter: buf %#jx len %ju", 311 USBNETHIST_CALLARGSN(5, "%jd: enter: buf %#jx len %ju",
312 unp->unp_number, (uintptr_t)buf, buflen, 0); 312 unp->unp_number, (uintptr_t)buf, buflen, 0);
313 313
314 usbnet_isowned_rx(un); 314 usbnet_isowned_rx(un);
315 315
316 m = usbnet_newbuf(buflen); 316 m = usbnet_newbuf(buflen);
317 if (m == NULL) { 317 if (m == NULL) {
318 if_statinc(ifp, if_ierrors); 318 if_statinc(ifp, if_ierrors);
319 return; 319 return;
320 } 320 }
321 321
322 m_set_rcvif(m, ifp); 322 m_set_rcvif(m, ifp);
323 memcpy(mtod(m, char *), buf, buflen); 323 memcpy(mtod(m, char *), buf, buflen);
324 324
325 /* push the packet up */ 325 /* push the packet up */
326 if_input(ifp, m); 326 if_input(ifp, m);
327} 327}
328 328
329/* 329/*
330 * A frame has been uploaded: pass the resulting mbuf chain up to 330 * A frame has been uploaded: pass the resulting mbuf chain up to
331 * the higher level protocols. 331 * the higher level protocols.
332 */ 332 */
333static void 333static void
334usbnet_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 334usbnet_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
335{ 335{
336 USBNETHIST_FUNC(); 336 USBNETHIST_FUNC();
337 struct usbnet_chain * const c = priv; 337 struct usbnet_chain * const c = priv;
338 struct usbnet * const un = c->unc_un; 338 struct usbnet * const un = c->unc_un;
339 struct usbnet_private * const unp = un->un_pri; 339 struct usbnet_private * const unp = un->un_pri;
340 struct ifnet * const ifp = usbnet_ifp(un); 
341 uint32_t total_len; 340 uint32_t total_len;
342 341
343 USBNETHIST_CALLARGSN(5, "%jd: enter: status %#jx xfer %#jx", 342 USBNETHIST_CALLARGSN(5, "%jd: enter: status %#jx xfer %#jx",
344 unp->unp_number, status, (uintptr_t)xfer, 0); 343 unp->unp_number, status, (uintptr_t)xfer, 0);
345 344
346 mutex_enter(&unp->unp_rxlock); 345 mutex_enter(&unp->unp_rxlock);
347 346
348 if (unp->unp_dying || unp->unp_stopping || 347 if (unp->unp_dying || unp->unp_stopping ||
349 status == USBD_INVAL || status == USBD_NOT_STARTED || 348 status == USBD_INVAL || status == USBD_NOT_STARTED ||
350 status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) 349 status == USBD_CANCELLED)
351 goto out; 350 goto out;
352 351
353 if (status != USBD_NORMAL_COMPLETION) { 352 if (status != USBD_NORMAL_COMPLETION) {
354 if (usbd_ratecheck(&unp->unp_rx_notice)) 353 if (usbd_ratecheck(&unp->unp_rx_notice))
355 device_printf(un->un_dev, "usb errors on rx: %s\n", 354 device_printf(un->un_dev, "usb errors on rx: %s\n",
356 usbd_errstr(status)); 355 usbd_errstr(status));
357 if (status == USBD_STALLED) 356 if (status == USBD_STALLED)
358 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_RX]); 357 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_RX]);
359 goto done; 358 goto done;
360 } 359 }
361 360
362 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 361 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
363 362
364 if (total_len > un->un_rx_bufsz) { 363 if (total_len > un->un_rx_bufsz) {
365 aprint_error_dev(un->un_dev, 364 aprint_error_dev(un->un_dev,
366 "rxeof: too large transfer (%u > %u)\n", 365 "rxeof: too large transfer (%u > %u)\n",
367 total_len, un->un_rx_bufsz); 366 total_len, un->un_rx_bufsz);
368 goto done; 367 goto done;
369 } 368 }
370 369
371 uno_rx_loop(un, c, total_len); 370 uno_rx_loop(un, c, total_len);
372 usbnet_isowned_rx(un); 371 usbnet_isowned_rx(un);
373 372
374done: 373done:
375 if (unp->unp_dying || unp->unp_stopping) 374 if (unp->unp_dying || unp->unp_stopping)
376 goto out; 375 goto out;
377 376
378 mutex_exit(&unp->unp_rxlock); 377 mutex_exit(&unp->unp_rxlock);
379 378
380 /* Setup new transfer. */ 379 /* Setup new transfer. */
381 usbd_setup_xfer(xfer, c, c->unc_buf, un->un_rx_bufsz, 380 usbd_setup_xfer(xfer, c, c->unc_buf, un->un_rx_bufsz,
382 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof); 381 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof);
383 usbd_transfer(xfer); 382 usbd_transfer(xfer);
384 return; 383 return;
385 384
386out: 385out:
387 mutex_exit(&unp->unp_rxlock); 386 mutex_exit(&unp->unp_rxlock);
388} 387}
389 388
390static void 389static void
391usbnet_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 390usbnet_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
392{ 391{
393 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 392 USBNETHIST_FUNC(); USBNETHIST_CALLED();
394 struct usbnet_chain * const c = priv; 393 struct usbnet_chain * const c = priv;
395 struct usbnet * const un = c->unc_un; 394 struct usbnet * const un = c->unc_un;
396 struct usbnet_cdata * const cd = un_cdata(un); 395 struct usbnet_cdata * const cd = un_cdata(un);
397 struct usbnet_private * const unp = un->un_pri; 396 struct usbnet_private * const unp = un->un_pri;
398 struct ifnet * const ifp = usbnet_ifp(un); 397 struct ifnet * const ifp = usbnet_ifp(un);
399 398
400 USBNETHIST_CALLARGSN(5, "%jd: enter: status %#jx xfer %#jx", 399 USBNETHIST_CALLARGSN(5, "%jd: enter: status %#jx xfer %#jx",
401 unp->unp_number, status, (uintptr_t)xfer, 0); 400 unp->unp_number, status, (uintptr_t)xfer, 0);
402 401
403 mutex_enter(&unp->unp_txlock); 402 mutex_enter(&unp->unp_txlock);
404 if (unp->unp_stopping || unp->unp_dying) { 403 if (unp->unp_stopping || unp->unp_dying) {
405 mutex_exit(&unp->unp_txlock); 404 mutex_exit(&unp->unp_txlock);
406 return; 405 return;
407 } 406 }
408 407
409 KASSERT(cd->uncd_tx_cnt > 0); 408 KASSERT(cd->uncd_tx_cnt > 0);
410 cd->uncd_tx_cnt--; 409 cd->uncd_tx_cnt--;
411 410
412 unp->unp_timer = 0; 411 unp->unp_timer = 0;
413 412
414 switch (status) { 413 switch (status) {
415 case USBD_NOT_STARTED: 414 case USBD_NOT_STARTED:
416 case USBD_CANCELLED: 415 case USBD_CANCELLED:
417 break; 416 break;
418 417
419 case USBD_NORMAL_COMPLETION: 418 case USBD_NORMAL_COMPLETION:
420 if_statinc(ifp, if_opackets); 419 if_statinc(ifp, if_opackets);
421 break; 420 break;
422 421
423 default: 422 default:
424 423
425 if_statinc(ifp, if_oerrors); 424 if_statinc(ifp, if_oerrors);
426 if (usbd_ratecheck(&unp->unp_tx_notice)) 425 if (usbd_ratecheck(&unp->unp_tx_notice))
427 device_printf(un->un_dev, "usb error on tx: %s\n", 426 device_printf(un->un_dev, "usb error on tx: %s\n",
428 usbd_errstr(status)); 427 usbd_errstr(status));
429 if (status == USBD_STALLED) 428 if (status == USBD_STALLED)
430 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_TX]); 429 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_TX]);
431 break; 430 break;
432 } 431 }
433 432
434 mutex_exit(&unp->unp_txlock); 433 mutex_exit(&unp->unp_txlock);
435 434
436 if (status == USBD_NORMAL_COMPLETION && !IFQ_IS_EMPTY(&ifp->if_snd)) 435 if (status == USBD_NORMAL_COMPLETION && !IFQ_IS_EMPTY(&ifp->if_snd))
437 (*ifp->if_start)(ifp); 436 (*ifp->if_start)(ifp);
438} 437}
439 438
440static void 439static void
441usbnet_pipe_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) 440usbnet_pipe_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
442{ 441{
443 USBNETHIST_FUNC(); 442 USBNETHIST_FUNC();
444 struct usbnet * const un = priv; 443 struct usbnet * const un = priv;
445 struct usbnet_private * const unp = un->un_pri; 444 struct usbnet_private * const unp = un->un_pri;
446 struct usbnet_intr * const uni = un->un_intr; 445 struct usbnet_intr * const uni = un->un_intr;
447 struct ifnet * const ifp = usbnet_ifp(un); 446 struct ifnet * const ifp = usbnet_ifp(un);
448 447
449 if (uni == NULL || unp->unp_dying || unp->unp_stopping || 448 if (uni == NULL || unp->unp_dying || unp->unp_stopping ||
450 status == USBD_INVAL || status == USBD_NOT_STARTED || 449 status == USBD_INVAL || status == USBD_NOT_STARTED ||
451 status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) { 450 status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) {
452 USBNETHIST_CALLARGS("%jd: uni %#jx d/s %#jx status %#jx", 451 USBNETHIST_CALLARGS("%jd: uni %#jx d/s %#jx status %#jx",
453 unp->unp_number, (uintptr_t)uni, 452 unp->unp_number, (uintptr_t)uni,
454 (unp->unp_dying << 8) | unp->unp_stopping, status); 453 (unp->unp_dying << 8) | unp->unp_stopping, status);
455 return; 454 return;
456 } 455 }
457 456
458 if (status != USBD_NORMAL_COMPLETION) { 457 if (status != USBD_NORMAL_COMPLETION) {
459 if (usbd_ratecheck(&unp->unp_intr_notice)) { 458 if (usbd_ratecheck(&unp->unp_intr_notice)) {
460 aprint_error_dev(un->un_dev, "usb error on intr: %s\n", 459 aprint_error_dev(un->un_dev, "usb error on intr: %s\n",
461 usbd_errstr(status)); 460 usbd_errstr(status));
462 } 461 }
463 if (status == USBD_STALLED) 462 if (status == USBD_STALLED)
464 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_INTR]); 463 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_INTR]);
465 USBNETHIST_CALLARGS("%jd: not normal status %#jx", 464 USBNETHIST_CALLARGS("%jd: not normal status %#jx",
466 unp->unp_number, status, 0, 0); 465 unp->unp_number, status, 0, 0);
467 return; 466 return;
468 } 467 }
469 468
470 uno_intr(un, status); 469 uno_intr(un, status);
471} 470}
472 471
473static void 472static void
474usbnet_start_locked(struct ifnet *ifp) 473usbnet_start_locked(struct ifnet *ifp)
475{ 474{
476 USBNETHIST_FUNC(); 475 USBNETHIST_FUNC();
477 struct usbnet * const un = ifp->if_softc; 476 struct usbnet * const un = ifp->if_softc;
478 struct usbnet_cdata * const cd = un_cdata(un); 477 struct usbnet_cdata * const cd = un_cdata(un);
479 struct usbnet_private * const unp = un->un_pri; 478 struct usbnet_private * const unp = un->un_pri;
480 struct mbuf *m; 479 struct mbuf *m;
481 unsigned length; 480 unsigned length;
482 bool done_transmit = false; 481 bool done_transmit = false;
483 int idx, count; 482 int idx, count;
484 483
485 USBNETHIST_CALLARGS("%jd: tx_cnt %jd list_cnt %jd link %jd", 484 USBNETHIST_CALLARGS("%jd: tx_cnt %jd list_cnt %jd link %jd",
486 unp->unp_number, cd->uncd_tx_cnt, un->un_tx_list_cnt, 485 unp->unp_number, cd->uncd_tx_cnt, un->un_tx_list_cnt,
487 unp->unp_link); 486 unp->unp_link);
488 487
489 usbnet_isowned_tx(un); 488 usbnet_isowned_tx(un);
490 KASSERT(cd->uncd_tx_cnt <= un->un_tx_list_cnt); 489 KASSERT(cd->uncd_tx_cnt <= un->un_tx_list_cnt);
491 490
492 if (!unp->unp_link || (ifp->if_flags & IFF_RUNNING) == 0) { 491 if (!unp->unp_link || (ifp->if_flags & IFF_RUNNING) == 0) {
493 DPRINTF("start called no link (%jx) or running (flags %jx)", 492 DPRINTF("start called no link (%jx) or running (flags %jx)",
494 unp->unp_link, ifp->if_flags, 0, 0); 493 unp->unp_link, ifp->if_flags, 0, 0);
495 return; 494 return;
496 } 495 }
497 496
498 if (cd->uncd_tx_cnt == un->un_tx_list_cnt) { 497 if (cd->uncd_tx_cnt == un->un_tx_list_cnt) {
499 DPRINTF("start called, tx busy (%#jx == %#jx)", 498 DPRINTF("start called, tx busy (%#jx == %#jx)",
500 cd->uncd_tx_cnt, un->un_tx_list_cnt, 0, 0); 499 cd->uncd_tx_cnt, un->un_tx_list_cnt, 0, 0);
501 return; 500 return;
502 } 501 }
503 502
504 idx = cd->uncd_tx_prod; 503 idx = cd->uncd_tx_prod;
505 count = 0; 504 count = 0;
506 while (cd->uncd_tx_cnt < un->un_tx_list_cnt) { 505 while (cd->uncd_tx_cnt < un->un_tx_list_cnt) {
507 IFQ_POLL(&ifp->if_snd, m); 506 IFQ_POLL(&ifp->if_snd, m);
508 if (m == NULL) { 507 if (m == NULL) {
509 DPRINTF("start called, queue empty", 0, 0, 0, 0); 508 DPRINTF("start called, queue empty", 0, 0, 0, 0);
510 break; 509 break;
511 } 510 }
512 KASSERT(m->m_pkthdr.len <= un->un_tx_bufsz); 511 KASSERT(m->m_pkthdr.len <= un->un_tx_bufsz);
513 512
514 struct usbnet_chain *c = &cd->uncd_tx_chain[idx]; 513 struct usbnet_chain *c = &cd->uncd_tx_chain[idx];
515 514
516 length = uno_tx_prepare(un, m, c); 515 length = uno_tx_prepare(un, m, c);
517 if (length == 0) { 516 if (length == 0) {
518 DPRINTF("uno_tx_prepare gave zero length", 0, 0, 0, 0); 517 DPRINTF("uno_tx_prepare gave zero length", 0, 0, 0, 0);
519 if_statinc(ifp, if_oerrors); 518 if_statinc(ifp, if_oerrors);
520 break; 519 break;
521 } 520 }
522 521
523 if (__predict_false(c->unc_xfer == NULL)) { 522 if (__predict_false(c->unc_xfer == NULL)) {
524 DPRINTF("unc_xfer is NULL", 0, 0, 0, 0); 523 DPRINTF("unc_xfer is NULL", 0, 0, 0, 0);
525 if_statinc(ifp, if_oerrors); 524 if_statinc(ifp, if_oerrors);
526 break; 525 break;
527 } 526 }
528 527
529 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, length, 528 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, length,
530 un->un_tx_xfer_flags, 10000, usbnet_txeof); 529 un->un_tx_xfer_flags, 10000, usbnet_txeof);
531 530
532 /* Transmit */ 531 /* Transmit */
533 usbd_status err = usbd_transfer(c->unc_xfer); 532 usbd_status err = usbd_transfer(c->unc_xfer);
534 if (err != USBD_IN_PROGRESS) { 533 if (err != USBD_IN_PROGRESS) {
535 DPRINTF("usbd_transfer on %#jx for %ju bytes: %jd", 534 DPRINTF("usbd_transfer on %#jx for %ju bytes: %jd",
536 (uintptr_t)c->unc_buf, length, err, 0); 535 (uintptr_t)c->unc_buf, length, err, 0);
537 if_statinc(ifp, if_oerrors); 536 if_statinc(ifp, if_oerrors);
538 break; 537 break;
539 } 538 }
540 done_transmit = true; 539 done_transmit = true;
541 540
542 IFQ_DEQUEUE(&ifp->if_snd, m); 541 IFQ_DEQUEUE(&ifp->if_snd, m);
543 542
544 /* 543 /*
545 * If there's a BPF listener, bounce a copy of this frame 544 * If there's a BPF listener, bounce a copy of this frame
546 * to him. 545 * to him.
547 */ 546 */
548 bpf_mtap(ifp, m, BPF_D_OUT); 547 bpf_mtap(ifp, m, BPF_D_OUT);
549 m_freem(m); 548 m_freem(m);
550 549
551 idx = (idx + 1) % un->un_tx_list_cnt; 550 idx = (idx + 1) % un->un_tx_list_cnt;
552 cd->uncd_tx_cnt++; 551 cd->uncd_tx_cnt++;
553 count++; 552 count++;
554 } 553 }
555 cd->uncd_tx_prod = idx; 554 cd->uncd_tx_prod = idx;
556 555
557 DPRINTF("finished with start; tx_cnt %jd list_cnt %jd link %jd", 556 DPRINTF("finished with start; tx_cnt %jd list_cnt %jd link %jd",
558 cd->uncd_tx_cnt, un->un_tx_list_cnt, unp->unp_link, 0); 557 cd->uncd_tx_cnt, un->un_tx_list_cnt, unp->unp_link, 0);
559 558
560 /* 559 /*
561 * Set a timeout in case the chip goes out to lunch. 560 * Set a timeout in case the chip goes out to lunch.
562 */ 561 */
563 if (done_transmit) 562 if (done_transmit)
564 unp->unp_timer = 5; 563 unp->unp_timer = 5;
565 564
566 if (count != 0) 565 if (count != 0)
567 rnd_add_uint32(&unp->unp_rndsrc, count); 566 rnd_add_uint32(&unp->unp_rndsrc, count);
568} 567}
569 568
570static void 569static void
571usbnet_if_start(struct ifnet *ifp) 570usbnet_if_start(struct ifnet *ifp)
572{ 571{
573 struct usbnet * const un = ifp->if_softc; 572 struct usbnet * const un = ifp->if_softc;
574 struct usbnet_private * const unp = un->un_pri; 573 struct usbnet_private * const unp = un->un_pri;
575 574
576 USBNETHIST_FUNC(); 575 USBNETHIST_FUNC();
577 USBNETHIST_CALLARGS("%jd: stopping %jd", 576 USBNETHIST_CALLARGS("%jd: stopping %jd",
578 unp->unp_number, unp->unp_stopping, 0, 0); 577 unp->unp_number, unp->unp_stopping, 0, 0);
579 578
580 mutex_enter(&unp->unp_txlock); 579 mutex_enter(&unp->unp_txlock);
581 if (!unp->unp_stopping) 580 if (!unp->unp_stopping)
582 usbnet_start_locked(ifp); 581 usbnet_start_locked(ifp);
583 mutex_exit(&unp->unp_txlock); 582 mutex_exit(&unp->unp_txlock);
584} 583}
585 584
586/* 585/*
587 * Chain management. 586 * Chain management.
588 * 587 *
589 * RX and TX are identical. Keep them that way. 588 * RX and TX are identical. Keep them that way.
590 */ 589 */
591 590
592/* Start of common RX functions */ 591/* Start of common RX functions */
593 592
594static size_t 593static size_t
595usbnet_rx_list_size(struct usbnet_cdata * const cd, struct usbnet * const un) 594usbnet_rx_list_size(struct usbnet_cdata * const cd, struct usbnet * const un)
596{ 595{
597 return sizeof(*cd->uncd_rx_chain) * un->un_rx_list_cnt; 596 return sizeof(*cd->uncd_rx_chain) * un->un_rx_list_cnt;
598} 597}
599 598
600static void 599static void
601usbnet_rx_list_alloc(struct usbnet * const un) 600usbnet_rx_list_alloc(struct usbnet * const un)
602{ 601{
603 struct usbnet_cdata * const cd = un_cdata(un); 602 struct usbnet_cdata * const cd = un_cdata(un);
604 603
605 cd->uncd_rx_chain = kmem_zalloc(usbnet_rx_list_size(cd, un), KM_SLEEP); 604 cd->uncd_rx_chain = kmem_zalloc(usbnet_rx_list_size(cd, un), KM_SLEEP);
606} 605}
607 606
608static void 607static void
609usbnet_rx_list_free(struct usbnet * const un) 608usbnet_rx_list_free(struct usbnet * const un)
610{ 609{
611 struct usbnet_cdata * const cd = un_cdata(un); 610 struct usbnet_cdata * const cd = un_cdata(un);
612 611
613 if (cd->uncd_rx_chain) { 612 if (cd->uncd_rx_chain) {
614 kmem_free(cd->uncd_rx_chain, usbnet_rx_list_size(cd, un)); 613 kmem_free(cd->uncd_rx_chain, usbnet_rx_list_size(cd, un));
615 cd->uncd_rx_chain = NULL; 614 cd->uncd_rx_chain = NULL;
616 } 615 }
617} 616}
618 617
619static int 618static int
620usbnet_rx_list_init(struct usbnet * const un) 619usbnet_rx_list_init(struct usbnet * const un)
621{ 620{
622 struct usbnet_cdata * const cd = un_cdata(un); 621 struct usbnet_cdata * const cd = un_cdata(un);
623 struct usbnet_private * const unp = un->un_pri; 622 struct usbnet_private * const unp = un->un_pri;
624 623
625 for (size_t i = 0; i < un->un_rx_list_cnt; i++) { 624 for (size_t i = 0; i < un->un_rx_list_cnt; i++) {
626 struct usbnet_chain *c = &cd->uncd_rx_chain[i]; 625 struct usbnet_chain *c = &cd->uncd_rx_chain[i];
627 626
628 c->unc_un = un; 627 c->unc_un = un;
629 if (c->unc_xfer == NULL) { 628 if (c->unc_xfer == NULL) {
630 int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_RX], 629 int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_RX],
631 un->un_rx_bufsz, un->un_rx_xfer_flags, 0, 630 un->un_rx_bufsz, un->un_rx_xfer_flags, 0,
632 &c->unc_xfer); 631 &c->unc_xfer);
633 if (err) 632 if (err)
634 return err; 633 return err;
635 c->unc_buf = usbd_get_buffer(c->unc_xfer); 634 c->unc_buf = usbd_get_buffer(c->unc_xfer);
636 } 635 }
637 } 636 }
638 637
639 return 0; 638 return 0;
640} 639}
641 640
642static void 641static void
643usbnet_rx_list_fini(struct usbnet * const un) 642usbnet_rx_list_fini(struct usbnet * const un)
644{ 643{
645 struct usbnet_cdata * const cd = un_cdata(un); 644 struct usbnet_cdata * const cd = un_cdata(un);
646 645
647 for (size_t i = 0; i < un->un_rx_list_cnt; i++) { 646 for (size_t i = 0; i < un->un_rx_list_cnt; i++) {
648 struct usbnet_chain *c = &cd->uncd_rx_chain[i]; 647 struct usbnet_chain *c = &cd->uncd_rx_chain[i];
649 648
650 if (c->unc_xfer != NULL) { 649 if (c->unc_xfer != NULL) {
651 usbd_destroy_xfer(c->unc_xfer); 650 usbd_destroy_xfer(c->unc_xfer);
652 c->unc_xfer = NULL; 651 c->unc_xfer = NULL;
653 c->unc_buf = NULL; 652 c->unc_buf = NULL;
654 } 653 }
655 } 654 }
656} 655}
657 656
658/* End of common RX functions */ 657/* End of common RX functions */
659 658
660static void 659static void
661usbnet_rx_start_pipes(struct usbnet * const un) 660usbnet_rx_start_pipes(struct usbnet * const un)
662{ 661{
663 struct usbnet_cdata * const cd = un_cdata(un); 662 struct usbnet_cdata * const cd = un_cdata(un);
664 struct usbnet_private * const unp = un->un_pri; 663 struct usbnet_private * const unp = un->un_pri;
665 664
666 mutex_enter(&unp->unp_rxlock); 665 mutex_enter(&unp->unp_rxlock);
667 mutex_enter(&unp->unp_txlock); 666 mutex_enter(&unp->unp_txlock);
668 unp->unp_stopping = false; 667 unp->unp_stopping = false;
669 668
670 for (size_t i = 0; i < un->un_rx_list_cnt; i++) { 669 for (size_t i = 0; i < un->un_rx_list_cnt; i++) {
671 struct usbnet_chain *c = &cd->uncd_rx_chain[i]; 670 struct usbnet_chain *c = &cd->uncd_rx_chain[i];
672 671
673 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, un->un_rx_bufsz, 672 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, un->un_rx_bufsz,
674 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof); 673 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof);
675 usbd_transfer(c->unc_xfer); 674 usbd_transfer(c->unc_xfer);
676 } 675 }
677 676
678 mutex_exit(&unp->unp_txlock); 677 mutex_exit(&unp->unp_txlock);
679 mutex_exit(&unp->unp_rxlock); 678 mutex_exit(&unp->unp_rxlock);
680} 679}
681 680
682/* Start of common TX functions */ 681/* Start of common TX functions */
683 682
684static size_t 683static size_t
685usbnet_tx_list_size(struct usbnet_cdata * const cd, struct usbnet * const un) 684usbnet_tx_list_size(struct usbnet_cdata * const cd, struct usbnet * const un)
686{ 685{
687 return sizeof(*cd->uncd_tx_chain) * un->un_tx_list_cnt; 686 return sizeof(*cd->uncd_tx_chain) * un->un_tx_list_cnt;
688} 687}
689 688
690static void 689static void
691usbnet_tx_list_alloc(struct usbnet * const un) 690usbnet_tx_list_alloc(struct usbnet * const un)
692{ 691{
693 struct usbnet_cdata * const cd = un_cdata(un); 692 struct usbnet_cdata * const cd = un_cdata(un);
694 693
695 cd->uncd_tx_chain = kmem_zalloc(usbnet_tx_list_size(cd, un), KM_SLEEP); 694 cd->uncd_tx_chain = kmem_zalloc(usbnet_tx_list_size(cd, un), KM_SLEEP);
696} 695}
697 696
698static void 697static void
699usbnet_tx_list_free(struct usbnet * const un) 698usbnet_tx_list_free(struct usbnet * const un)
700{ 699{
701 struct usbnet_cdata * const cd = un_cdata(un); 700 struct usbnet_cdata * const cd = un_cdata(un);
702 701
703 if (cd->uncd_tx_chain) { 702 if (cd->uncd_tx_chain) {
704 kmem_free(cd->uncd_tx_chain, usbnet_tx_list_size(cd, un)); 703 kmem_free(cd->uncd_tx_chain, usbnet_tx_list_size(cd, un));
705 cd->uncd_tx_chain = NULL; 704 cd->uncd_tx_chain = NULL;
706 } 705 }
707} 706}
708 707
709static int 708static int
710usbnet_tx_list_init(struct usbnet * const un) 709usbnet_tx_list_init(struct usbnet * const un)
711{ 710{
712 struct usbnet_cdata * const cd = un_cdata(un); 711 struct usbnet_cdata * const cd = un_cdata(un);
713 struct usbnet_private * const unp = un->un_pri; 712 struct usbnet_private * const unp = un->un_pri;
714 713
715 for (size_t i = 0; i < un->un_tx_list_cnt; i++) { 714 for (size_t i = 0; i < un->un_tx_list_cnt; i++) {
716 struct usbnet_chain *c = &cd->uncd_tx_chain[i]; 715 struct usbnet_chain *c = &cd->uncd_tx_chain[i];
717 716
718 c->unc_un = un; 717 c->unc_un = un;
719 if (c->unc_xfer == NULL) { 718 if (c->unc_xfer == NULL) {
720 int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_TX], 719 int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_TX],
721 un->un_tx_bufsz, un->un_tx_xfer_flags, 0, 720 un->un_tx_bufsz, un->un_tx_xfer_flags, 0,
722 &c->unc_xfer); 721 &c->unc_xfer);
723 if (err) 722 if (err)
724 return err; 723 return err;
725 c->unc_buf = usbd_get_buffer(c->unc_xfer); 724 c->unc_buf = usbd_get_buffer(c->unc_xfer);
726 } 725 }
727 } 726 }
728 727
729 return 0; 728 return 0;
730} 729}
731 730
732static void 731static void
733usbnet_tx_list_fini(struct usbnet * const un) 732usbnet_tx_list_fini(struct usbnet * const un)
734{ 733{
735 struct usbnet_cdata * const cd = un_cdata(un); 734 struct usbnet_cdata * const cd = un_cdata(un);
736 735
737 for (size_t i = 0; i < un->un_tx_list_cnt; i++) { 736 for (size_t i = 0; i < un->un_tx_list_cnt; i++) {
738 struct usbnet_chain *c = &cd->uncd_tx_chain[i]; 737 struct usbnet_chain *c = &cd->uncd_tx_chain[i];
739 738
740 if (c->unc_xfer != NULL) { 739 if (c->unc_xfer != NULL) {
741 usbd_destroy_xfer(c->unc_xfer); 740 usbd_destroy_xfer(c->unc_xfer);
742 c->unc_xfer = NULL; 741 c->unc_xfer = NULL;
743 c->unc_buf = NULL; 742 c->unc_buf = NULL;
744 } 743 }
745 } 744 }
746 cd->uncd_tx_prod = cd->uncd_tx_cnt = 0; 745 cd->uncd_tx_prod = cd->uncd_tx_cnt = 0;
747} 746}
748 747
749/* End of common TX functions */ 748/* End of common TX functions */
750 749
751/* Endpoint pipe management. */ 750/* Endpoint pipe management. */
752 751
753static void 752static void
754usbnet_ep_close_pipes(struct usbnet * const un) 753usbnet_ep_close_pipes(struct usbnet * const un)
755{ 754{
756 struct usbnet_private * const unp = un->un_pri; 755 struct usbnet_private * const unp = un->un_pri;
757 756
758 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { 757 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) {
759 if (unp->unp_ep[i] == NULL) 758 if (unp->unp_ep[i] == NULL)
760 continue; 759 continue;
761 usbd_status err = usbd_close_pipe(unp->unp_ep[i]); 760 usbd_status err = usbd_close_pipe(unp->unp_ep[i]);
762 if (err) 761 if (err)
763 aprint_error_dev(un->un_dev, "close pipe %zu: %s\n", i, 762 aprint_error_dev(un->un_dev, "close pipe %zu: %s\n", i,
764 usbd_errstr(err)); 763 usbd_errstr(err));
765 unp->unp_ep[i] = NULL; 764 unp->unp_ep[i] = NULL;
766 } 765 }
767} 766}
768 767
769static usbd_status 768static usbd_status
770usbnet_ep_open_pipes(struct usbnet * const un) 769usbnet_ep_open_pipes(struct usbnet * const un)
771{ 770{
772 struct usbnet_intr * const uni = un->un_intr; 771 struct usbnet_intr * const uni = un->un_intr;
773 struct usbnet_private * const unp = un->un_pri; 772 struct usbnet_private * const unp = un->un_pri;
774 773
775 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { 774 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) {
776 usbd_status err; 775 usbd_status err;
777 776
778 if (un->un_ed[i] == 0) 777 if (un->un_ed[i] == 0)
779 continue; 778 continue;
780 779
781 if (i == USBNET_ENDPT_INTR && uni) { 780 if (i == USBNET_ENDPT_INTR && uni) {
782 err = usbd_open_pipe_intr(un->un_iface, un->un_ed[i], 781 err = usbd_open_pipe_intr(un->un_iface, un->un_ed[i],
783 USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i], un, 782 USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i], un,
784 uni->uni_buf, uni->uni_bufsz, usbnet_pipe_intr, 783 uni->uni_buf, uni->uni_bufsz, usbnet_pipe_intr,
785 uni->uni_interval); 784 uni->uni_interval);
786 } else { 785 } else {
787 err = usbd_open_pipe(un->un_iface, un->un_ed[i], 786 err = usbd_open_pipe(un->un_iface, un->un_ed[i],
788 USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i]); 787 USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i]);
789 } 788 }
790 if (err) { 789 if (err) {
791 usbnet_ep_close_pipes(un); 790 usbnet_ep_close_pipes(un);
792 return err; 791 return err;
793 } 792 }
794 } 793 }
795 794
796 return USBD_NORMAL_COMPLETION; 795 return USBD_NORMAL_COMPLETION;
797} 796}
798 797
799static usbd_status 798static usbd_status
800usbnet_ep_stop_pipes(struct usbnet * const un) 799usbnet_ep_stop_pipes(struct usbnet * const un)
801{ 800{
802 struct usbnet_private * const unp = un->un_pri; 801 struct usbnet_private * const unp = un->un_pri;
803 usbd_status err = USBD_NORMAL_COMPLETION; 802 usbd_status err = USBD_NORMAL_COMPLETION;
804 803
805 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { 804 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) {
806 if (unp->unp_ep[i] == NULL) 805 if (unp->unp_ep[i] == NULL)
807 continue; 806 continue;
808 usbd_status err2 = usbd_abort_pipe(unp->unp_ep[i]); 807 usbd_status err2 = usbd_abort_pipe(unp->unp_ep[i]);
809 if (err == USBD_NORMAL_COMPLETION && err2) 808 if (err == USBD_NORMAL_COMPLETION && err2)
810 err = err2; 809 err = err2;
811 } 810 }
812 811
813 return err; 812 return err;
814} 813}
815 814
816int 815int
817usbnet_init_rx_tx(struct usbnet * const un) 816usbnet_init_rx_tx(struct usbnet * const un)
818{ 817{
819 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 818 USBNETHIST_FUNC(); USBNETHIST_CALLED();
820 struct usbnet_private * const unp = un->un_pri; 819 struct usbnet_private * const unp = un->un_pri;
821 struct ifnet * const ifp = usbnet_ifp(un); 820 struct ifnet * const ifp = usbnet_ifp(un);
822 usbd_status err; 821 usbd_status err;
823 int error = 0; 822 int error = 0;
824 823
825 KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), 824 KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp),
826 "%s", ifp->if_xname); 825 "%s", ifp->if_xname);
827 826
828 usbnet_isowned_core(un); 827 usbnet_isowned_core(un);
829 828
830 if (unp->unp_dying) { 829 if (unp->unp_dying) {
831 return EIO; 830 return EIO;
832 } 831 }
833 832
834 usbnet_busy(un); 833 usbnet_busy(un);
835 834
836 /* Open RX and TX pipes. */ 835 /* Open RX and TX pipes. */
837 err = usbnet_ep_open_pipes(un); 836 err = usbnet_ep_open_pipes(un);
838 if (err) { 837 if (err) {
839 aprint_error_dev(un->un_dev, "open rx/tx pipes failed: %s\n", 838 aprint_error_dev(un->un_dev, "open rx/tx pipes failed: %s\n",
840 usbd_errstr(err)); 839 usbd_errstr(err));
841 error = EIO; 840 error = EIO;
842 goto out; 841 goto out;
843 } 842 }
844 843
845 /* Init RX ring. */ 844 /* Init RX ring. */
846 if (usbnet_rx_list_init(un)) { 845 if (usbnet_rx_list_init(un)) {
847 aprint_error_dev(un->un_dev, "rx list init failed\n"); 846 aprint_error_dev(un->un_dev, "rx list init failed\n");
848 error = ENOBUFS; 847 error = ENOBUFS;
849 goto out; 848 goto out;
850 } 849 }
851 850
852 /* Init TX ring. */ 851 /* Init TX ring. */
853 if (usbnet_tx_list_init(un)) { 852 if (usbnet_tx_list_init(un)) {
854 aprint_error_dev(un->un_dev, "tx list init failed\n"); 853 aprint_error_dev(un->un_dev, "tx list init failed\n");
855 error = ENOBUFS; 854 error = ENOBUFS;
856 goto out; 855 goto out;
857 } 856 }
858 857
859 /* Indicate we are up and running. */ 858 /* Indicate we are up and running. */
860#if 0 859#if 0
861 /* XXX if_mcast_op() can call this without ifnet locked */ 860 /* XXX if_mcast_op() can call this without ifnet locked */
862 KASSERT(ifp->if_softc == NULL || IFNET_LOCKED(ifp)); 861 KASSERT(ifp->if_softc == NULL || IFNET_LOCKED(ifp));
863#endif 862#endif
864 ifp->if_flags |= IFF_RUNNING; 863 ifp->if_flags |= IFF_RUNNING;
865 864
866 /* Start up the receive pipe(s). */ 865 /* Start up the receive pipe(s). */
867 usbnet_rx_start_pipes(un); 866 usbnet_rx_start_pipes(un);
868 867
869 callout_schedule(&unp->unp_stat_ch, hz); 868 callout_schedule(&unp->unp_stat_ch, hz);
870 869
871out: 870out:
872 if (error) { 871 if (error) {
873 usbnet_rx_list_fini(un); 872 usbnet_rx_list_fini(un);
874 usbnet_tx_list_fini(un); 873 usbnet_tx_list_fini(un);
875 usbnet_ep_close_pipes(un); 874 usbnet_ep_close_pipes(un);
876 } 875 }
877 usbnet_unbusy(un); 876 usbnet_unbusy(un);
878 877
879 usbnet_isowned_core(un); 878 usbnet_isowned_core(un);
880 879
881 return error; 880 return error;
882} 881}
883 882
884void 883void
885usbnet_busy(struct usbnet *un) 884usbnet_busy(struct usbnet *un)
886{ 885{
887 struct usbnet_private * const unp = un->un_pri; 886 struct usbnet_private * const unp = un->un_pri;
888 887
889 usbnet_isowned_core(un); 888 usbnet_isowned_core(un);
890 889
891 unp->unp_refcnt++; 890 unp->unp_refcnt++;
892} 891}
893 892
894void 893void
895usbnet_unbusy(struct usbnet *un) 894usbnet_unbusy(struct usbnet *un)
896{ 895{
897 struct usbnet_private * const unp = un->un_pri; 896 struct usbnet_private * const unp = un->un_pri;
898 897
899 usbnet_isowned_core(un); 898 usbnet_isowned_core(un);
900 899
901 if (--unp->unp_refcnt < 0) 900 if (--unp->unp_refcnt < 0)
902 cv_broadcast(&unp->unp_detachcv); 901 cv_broadcast(&unp->unp_detachcv);
903} 902}
904 903
905/* MII management. */ 904/* MII management. */
906 905
907int 906int
908usbnet_mii_readreg(device_t dev, int phy, int reg, uint16_t *val) 907usbnet_mii_readreg(device_t dev, int phy, int reg, uint16_t *val)
909{ 908{
910 USBNETHIST_FUNC(); 909 USBNETHIST_FUNC();
911 struct usbnet * const un = device_private(dev); 910 struct usbnet * const un = device_private(dev);
912 struct usbnet_private * const unp = un->un_pri; 911 struct usbnet_private * const unp = un->un_pri;
913 int err; 912 int err;
914 913
915 /* MII layer ensures core_lock is held. */ 914 /* MII layer ensures core_lock is held. */
916 usbnet_isowned_core(un); 915 usbnet_isowned_core(un);
917 916
918 if (unp->unp_dying) { 917 if (unp->unp_dying) {
919 return EIO; 918 return EIO;
920 } 919 }
921 920
922 usbnet_busy(un); 921 usbnet_busy(un);
923 err = uno_read_reg(un, phy, reg, val); 922 err = uno_read_reg(un, phy, reg, val);
924 usbnet_unbusy(un); 923 usbnet_unbusy(un);
925 924
926 if (err) { 925 if (err) {
927 USBNETHIST_CALLARGS("%jd: read PHY failed: %jd", 926 USBNETHIST_CALLARGS("%jd: read PHY failed: %jd",
928 unp->unp_number, err, 0, 0); 927 unp->unp_number, err, 0, 0);
929 return err; 928 return err;
930 } 929 }
931 930
932 return 0; 931 return 0;
933} 932}
934 933
935int 934int
936usbnet_mii_writereg(device_t dev, int phy, int reg, uint16_t val) 935usbnet_mii_writereg(device_t dev, int phy, int reg, uint16_t val)
937{ 936{
938 USBNETHIST_FUNC(); 937 USBNETHIST_FUNC();
939 struct usbnet * const un = device_private(dev); 938 struct usbnet * const un = device_private(dev);
940 struct usbnet_private * const unp = un->un_pri; 939 struct usbnet_private * const unp = un->un_pri;
941 int err; 940 int err;
942 941
943 /* MII layer ensures core_lock is held. */ 942 /* MII layer ensures core_lock is held. */
944 usbnet_isowned_core(un); 943 usbnet_isowned_core(un);
945 944
946 if (unp->unp_dying) { 945 if (unp->unp_dying) {
947 return EIO; 946 return EIO;
948 } 947 }
949 948
950 usbnet_busy(un); 949 usbnet_busy(un);
951 err = uno_write_reg(un, phy, reg, val); 950 err = uno_write_reg(un, phy, reg, val);
952 usbnet_unbusy(un); 951 usbnet_unbusy(un);
953 952
954 if (err) { 953 if (err) {
955 USBNETHIST_CALLARGS("%jd: write PHY failed: %jd", 954 USBNETHIST_CALLARGS("%jd: write PHY failed: %jd",
956 unp->unp_number, err, 0, 0); 955 unp->unp_number, err, 0, 0);
957 return err; 956 return err;
958 } 957 }
959 958
960 return 0; 959 return 0;
961} 960}
962 961
963void 962void
964usbnet_mii_statchg(struct ifnet *ifp) 963usbnet_mii_statchg(struct ifnet *ifp)
965{ 964{
966 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 965 USBNETHIST_FUNC(); USBNETHIST_CALLED();
967 struct usbnet * const un = ifp->if_softc; 966 struct usbnet * const un = ifp->if_softc;
968 967
969 /* MII layer ensures core_lock is held. */ 968 /* MII layer ensures core_lock is held. */
970 usbnet_isowned_core(un); 969 usbnet_isowned_core(un);
971 970
972 usbnet_busy(un); 971 usbnet_busy(un);
973 uno_mii_statchg(un, ifp); 972 uno_mii_statchg(un, ifp);
974 usbnet_unbusy(un); 973 usbnet_unbusy(un);
975} 974}
976 975
977static int 976static int
978usbnet_media_upd(struct ifnet *ifp) 977usbnet_media_upd(struct ifnet *ifp)
979{ 978{
980 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 979 USBNETHIST_FUNC(); USBNETHIST_CALLED();
981 struct usbnet * const un = ifp->if_softc; 980 struct usbnet * const un = ifp->if_softc;
982 struct usbnet_private * const unp = un->un_pri; 981 struct usbnet_private * const unp = un->un_pri;
983 struct mii_data * const mii = usbnet_mii(un); 982 struct mii_data * const mii = usbnet_mii(un);
984 983
985 /* ifmedia layer ensures core_lock is held. */ 984 /* ifmedia layer ensures core_lock is held. */
986 usbnet_isowned_core(un); 985 usbnet_isowned_core(un);
987 986
988 if (unp->unp_dying) 987 if (unp->unp_dying)
989 return EIO; 988 return EIO;
990 989
991 unp->unp_link = false; 990 unp->unp_link = false;
992 991
993 if (mii->mii_instance) { 992 if (mii->mii_instance) {
994 struct mii_softc *miisc; 993 struct mii_softc *miisc;
995 994
996 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) 995 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
997 mii_phy_reset(miisc); 996 mii_phy_reset(miisc);
998 } 997 }
999 998
1000 return ether_mediachange(ifp); 999 return ether_mediachange(ifp);
1001} 1000}
1002 1001
1003/* ioctl */ 1002/* ioctl */
1004 1003
1005static int 1004static int
1006usbnet_ifflags_cb(struct ethercom *ec) 1005usbnet_ifflags_cb(struct ethercom *ec)
1007{ 1006{
1008 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1007 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1009 struct ifnet *ifp = &ec->ec_if; 1008 struct ifnet *ifp = &ec->ec_if;
1010 struct usbnet *un = ifp->if_softc; 1009 struct usbnet *un = ifp->if_softc;
1011 struct usbnet_private * const unp = un->un_pri; 1010 struct usbnet_private * const unp = un->un_pri;
1012 int rv = 0; 1011 int rv = 0;
1013 1012
1014 KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); 1013 KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
1015 1014
1016 mutex_enter(&unp->unp_core_lock); 1015 mutex_enter(&unp->unp_core_lock);
1017 1016
1018 const u_short changed = ifp->if_flags ^ unp->unp_if_flags; 1017 const u_short changed = ifp->if_flags ^ unp->unp_if_flags;
1019 if ((changed & ~(IFF_CANTCHANGE | IFF_DEBUG)) == 0) { 1018 if ((changed & ~(IFF_CANTCHANGE | IFF_DEBUG)) == 0) {
1020 unp->unp_if_flags = ifp->if_flags; 1019 unp->unp_if_flags = ifp->if_flags;
1021 if ((changed & IFF_PROMISC) != 0) 1020 if ((changed & IFF_PROMISC) != 0)
1022 rv = ENETRESET; 1021 rv = ENETRESET;
1023 } else { 1022 } else {
1024 rv = ENETRESET; 1023 rv = ENETRESET;
1025 } 1024 }
1026 1025
1027 mutex_exit(&unp->unp_core_lock); 1026 mutex_exit(&unp->unp_core_lock);
1028 1027
1029 return rv; 1028 return rv;
1030} 1029}
1031 1030
1032static int 1031static int
1033usbnet_if_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1032usbnet_if_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1034{ 1033{
1035 USBNETHIST_FUNC(); 1034 USBNETHIST_FUNC();
1036 struct usbnet * const un = ifp->if_softc; 1035 struct usbnet * const un = ifp->if_softc;
1037 struct usbnet_private * const unp __unused = un->un_pri; 1036 struct usbnet_private * const unp __unused = un->un_pri;
1038 int error; 1037 int error;
1039 1038
1040 USBNETHIST_CALLARGSN(11, "%jd: enter %#jx data %#jx", 1039 USBNETHIST_CALLARGSN(11, "%jd: enter %#jx data %#jx",
1041 unp->unp_number, cmd, (uintptr_t)data, 0); 1040 unp->unp_number, cmd, (uintptr_t)data, 0);
1042 1041
1043 if (un->un_ops->uno_override_ioctl) 1042 if (un->un_ops->uno_override_ioctl)
1044 return uno_override_ioctl(un, ifp, cmd, data); 1043 return uno_override_ioctl(un, ifp, cmd, data);
1045 1044
1046 error = ether_ioctl(ifp, cmd, data); 1045 error = ether_ioctl(ifp, cmd, data);
1047 if (error == ENETRESET) { 1046 if (error == ENETRESET) {
1048 switch (cmd) { 1047 switch (cmd) {
1049 case SIOCADDMULTI: 1048 case SIOCADDMULTI:
1050 case SIOCDELMULTI: 1049 case SIOCDELMULTI:
1051 usb_add_task(un->un_udev, &unp->unp_mcasttask, 1050 usb_add_task(un->un_udev, &unp->unp_mcasttask,
1052 USB_TASKQ_DRIVER); 1051 USB_TASKQ_DRIVER);
1053 error = 0; 1052 error = 0;
1054 break; 1053 break;
1055 default: 1054 default:
1056 error = uno_ioctl(un, ifp, cmd, data); 1055 error = uno_ioctl(un, ifp, cmd, data);
1057 } 1056 }
1058 } 1057 }
1059 1058
1060 return error; 1059 return error;
1061} 1060}
1062 1061
1063static void 1062static void
1064usbnet_mcast_task(void *arg) 1063usbnet_mcast_task(void *arg)
1065{ 1064{
1066 USBNETHIST_FUNC(); 1065 USBNETHIST_FUNC();
1067 struct usbnet * const un = arg; 1066 struct usbnet * const un = arg;
1068 struct usbnet_private * const unp = un->un_pri; 1067 struct usbnet_private * const unp = un->un_pri;
1069 struct ifnet * const ifp = usbnet_ifp(un); 1068 struct ifnet * const ifp = usbnet_ifp(un);
1070 bool dying; 1069 bool dying;
1071 struct ifreq ifr; 1070 struct ifreq ifr;
1072 1071
1073 USBNETHIST_CALLARGSN(10, "%jd: enter", unp->unp_number, 0, 0, 0); 1072 USBNETHIST_CALLARGSN(10, "%jd: enter", unp->unp_number, 0, 0, 0);
1074 1073
1075 /* 1074 /*
1076 * If we're detaching, we must check unp_dying _before_ 1075 * If we're detaching, we must check unp_dying _before_
1077 * touching IFNET_LOCK -- the ifnet may have been detached by 1076 * touching IFNET_LOCK -- the ifnet may have been detached by
1078 * the time this task runs. This is racy -- unp_dying may be 1077 * the time this task runs. This is racy -- unp_dying may be
1079 * set immediately after we test it -- but nevertheless safe, 1078 * set immediately after we test it -- but nevertheless safe,
1080 * because usbnet_detach waits for the task to complete before 1079 * because usbnet_detach waits for the task to complete before
1081 * issuing if_detach, and necessary, so that we don't touch 1080 * issuing if_detach, and necessary, so that we don't touch
1082 * IFNET_LOCK after if_detach. See usbnet_detach for details. 1081 * IFNET_LOCK after if_detach. See usbnet_detach for details.
1083 */ 1082 */
1084 mutex_enter(&unp->unp_core_lock); 1083 mutex_enter(&unp->unp_core_lock);
1085 dying = unp->unp_dying; 1084 dying = unp->unp_dying;
1086 mutex_exit(&unp->unp_core_lock); 1085 mutex_exit(&unp->unp_core_lock);
1087 if (dying) 1086 if (dying)
1088 return; 1087 return;
1089 1088
1090 /* 1089 /*
1091 * Pass a bogus ifr with SIOCDELMULTI -- the goal is to just 1090 * Pass a bogus ifr with SIOCDELMULTI -- the goal is to just
1092 * notify the driver to reprogram any hardware multicast 1091 * notify the driver to reprogram any hardware multicast
1093 * filter, according to what's already stored in the ethercom. 1092 * filter, according to what's already stored in the ethercom.
1094 * None of the drivers actually examine this argument, so it 1093 * None of the drivers actually examine this argument, so it
1095 * doesn't change the ABI as far as they can tell. 1094 * doesn't change the ABI as far as they can tell.
1096 */ 1095 */
1097 IFNET_LOCK(ifp); 1096 IFNET_LOCK(ifp);
1098 if (ifp->if_flags & IFF_RUNNING) { 1097 if (ifp->if_flags & IFF_RUNNING) {
1099 memset(&ifr, 0, sizeof(ifr)); 1098 memset(&ifr, 0, sizeof(ifr));
1100 (void)uno_ioctl(un, ifp, SIOCDELMULTI, &ifr); 1099 (void)uno_ioctl(un, ifp, SIOCDELMULTI, &ifr);
1101 } 1100 }
1102 IFNET_UNLOCK(ifp); 1101 IFNET_UNLOCK(ifp);
1103} 1102}
1104 1103
1105/* 1104/*
1106 * Generic stop network function: 1105 * Generic stop network function:
1107 * - mark as stopping 1106 * - mark as stopping
1108 * - call DD routine to stop the device 1107 * - call DD routine to stop the device
1109 * - turn off running, timer, statchg callout, link 1108 * - turn off running, timer, statchg callout, link
1110 * - stop transfers 1109 * - stop transfers
1111 * - free RX and TX resources 1110 * - free RX and TX resources
1112 * - close pipes 1111 * - close pipes
1113 * 1112 *
1114 * usbnet_stop() is exported for drivers to use, expects lock held. 1113 * usbnet_stop() is exported for drivers to use, expects lock held.
1115 * 1114 *
1116 * usbnet_if_stop() is for the if_stop handler. 1115 * usbnet_if_stop() is for the if_stop handler.
1117 */ 1116 */
1118void 1117void
1119usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable) 1118usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
1120{ 1119{
1121 struct usbnet_private * const unp = un->un_pri; 1120 struct usbnet_private * const unp = un->un_pri;
1122 1121
1123 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1122 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1124 1123
1125 KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), 1124 KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp),
1126 "%s", ifp->if_xname); 1125 "%s", ifp->if_xname);
1127 usbnet_isowned_core(un); 1126 usbnet_isowned_core(un);
1128 1127
1129 usbnet_busy(un); 1128 usbnet_busy(un);
1130 1129
1131 mutex_enter(&unp->unp_rxlock); 1130 mutex_enter(&unp->unp_rxlock);
1132 mutex_enter(&unp->unp_txlock); 1131 mutex_enter(&unp->unp_txlock);
1133 unp->unp_stopping = true; 1132 unp->unp_stopping = true;
1134 mutex_exit(&unp->unp_txlock); 1133 mutex_exit(&unp->unp_txlock);
1135 mutex_exit(&unp->unp_rxlock); 1134 mutex_exit(&unp->unp_rxlock);
1136 1135
1137 uno_stop(un, ifp, disable); 1136 uno_stop(un, ifp, disable);
1138 1137
1139 mutex_enter(&unp->unp_txlock); 1138 mutex_enter(&unp->unp_txlock);
1140 unp->unp_timer = 0; 1139 unp->unp_timer = 0;
1141 mutex_exit(&unp->unp_txlock); 1140 mutex_exit(&unp->unp_txlock);
1142 1141
1143 callout_halt(&unp->unp_stat_ch, &unp->unp_core_lock); 1142 callout_halt(&unp->unp_stat_ch, &unp->unp_core_lock);
1144 usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, 1143 usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER,
1145 &unp->unp_core_lock); 1144 &unp->unp_core_lock);
1146 1145
1147 /* Stop transfers. */ 1146 /* Stop transfers. */
1148 usbnet_ep_stop_pipes(un); 1147 usbnet_ep_stop_pipes(un);
1149 1148
1150 /* Free RX/TX resources. */ 1149 /* Free RX/TX resources. */
1151 usbnet_rx_list_fini(un); 1150 usbnet_rx_list_fini(un);
1152 usbnet_tx_list_fini(un); 1151 usbnet_tx_list_fini(un);
1153 1152
1154 /* Close pipes. */ 1153 /* Close pipes. */
1155 usbnet_ep_close_pipes(un); 1154 usbnet_ep_close_pipes(un);
1156 1155
1157 /* Everything is quesced now. */ 1156 /* Everything is quesced now. */
1158 KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), 1157 KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp),
1159 "%s", ifp->if_xname); 1158 "%s", ifp->if_xname);
1160 ifp->if_flags &= ~IFF_RUNNING; 1159 ifp->if_flags &= ~IFF_RUNNING;
1161 1160
1162 usbnet_unbusy(un); 1161 usbnet_unbusy(un);
1163} 1162}
1164 1163
1165static void 1164static void
1166usbnet_if_stop(struct ifnet *ifp, int disable) 1165usbnet_if_stop(struct ifnet *ifp, int disable)
1167{ 1166{
1168 struct usbnet * const un = ifp->if_softc; 1167 struct usbnet * const un = ifp->if_softc;
1169 struct usbnet_private * const unp = un->un_pri; 1168 struct usbnet_private * const unp = un->un_pri;
1170 1169
1171 KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); 1170 KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
1172 1171
1173 mutex_enter(&unp->unp_core_lock); 1172 mutex_enter(&unp->unp_core_lock);
1174 usbnet_stop(un, ifp, disable); 1173 usbnet_stop(un, ifp, disable);
1175 mutex_exit(&unp->unp_core_lock); 1174 mutex_exit(&unp->unp_core_lock);
1176} 1175}
1177 1176
1178/* 1177/*
1179 * Generic tick task function. 1178 * Generic tick task function.
1180 * 1179 *
1181 * usbnet_tick() is triggered from a callout, and triggers a call to 1180 * usbnet_tick() is triggered from a callout, and triggers a call to
1182 * usbnet_tick_task() from the usb_task subsystem. 1181 * usbnet_tick_task() from the usb_task subsystem.
1183 */ 1182 */
1184static void 1183static void
1185usbnet_tick(void *arg) 1184usbnet_tick(void *arg)
1186{ 1185{
1187 USBNETHIST_FUNC(); 1186 USBNETHIST_FUNC();
1188 struct usbnet * const un = arg; 1187 struct usbnet * const un = arg;
1189 struct usbnet_private * const unp = un->un_pri; 1188 struct usbnet_private * const unp = un->un_pri;
1190 1189
1191 USBNETHIST_CALLARGSN(10, "%jd: enter", unp->unp_number, 0, 0, 0); 1190 USBNETHIST_CALLARGSN(10, "%jd: enter", unp->unp_number, 0, 0, 0);
1192 1191
1193 if (unp != NULL && !unp->unp_stopping && !unp->unp_dying) { 1192 if (unp != NULL && !unp->unp_stopping && !unp->unp_dying) {
1194 /* Perform periodic stuff in process context */ 1193 /* Perform periodic stuff in process context */
1195 usb_add_task(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER); 1194 usb_add_task(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER);
1196 } 1195 }
1197} 1196}
1198 1197
1199static void 1198static void
1200usbnet_watchdog(struct ifnet *ifp) 1199usbnet_watchdog(struct ifnet *ifp)
1201{ 1200{
1202 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1201 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1203 struct usbnet * const un = ifp->if_softc; 1202 struct usbnet * const un = ifp->if_softc;
1204 struct usbnet_private * const unp = un->un_pri; 1203 struct usbnet_private * const unp = un->un_pri;
1205 struct usbnet_cdata * const cd = un_cdata(un); 1204 struct usbnet_cdata * const cd = un_cdata(un);
1206 usbd_status err; 1205 usbd_status err;
1207 1206
1208 if_statinc(ifp, if_oerrors); 1207 if_statinc(ifp, if_oerrors);
1209 device_printf(un->un_dev, "watchdog timeout\n"); 1208 device_printf(un->un_dev, "watchdog timeout\n");
1210 1209
1211 if (cd->uncd_tx_cnt > 0) { 1210 if (cd->uncd_tx_cnt > 0) {
1212 DPRINTF("uncd_tx_cnt=%ju non zero, aborting pipe", 0, 0, 0, 0); 1211 DPRINTF("uncd_tx_cnt=%ju non zero, aborting pipe", 0, 0, 0, 0);
1213 err = usbd_abort_pipe(unp->unp_ep[USBNET_ENDPT_TX]); 1212 err = usbd_abort_pipe(unp->unp_ep[USBNET_ENDPT_TX]);
1214 if (err) 1213 if (err)
1215 device_printf(un->un_dev, "pipe abort failed: %s\n", 1214 device_printf(un->un_dev, "pipe abort failed: %s\n",
1216 usbd_errstr(err)); 1215 usbd_errstr(err));
1217 if (cd->uncd_tx_cnt != 0) 1216 if (cd->uncd_tx_cnt != 0)
1218 DPRINTF("uncd_tx_cnt now %ju", cd->uncd_tx_cnt, 0, 0, 0); 1217 DPRINTF("uncd_tx_cnt now %ju", cd->uncd_tx_cnt, 0, 0, 0);
1219 } 1218 }
1220 1219
1221 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 1220 if (!IFQ_IS_EMPTY(&ifp->if_snd))
1222 (*ifp->if_start)(ifp); 1221 (*ifp->if_start)(ifp);
1223} 1222}
1224 1223
1225static void 1224static void
1226usbnet_tick_task(void *arg) 1225usbnet_tick_task(void *arg)
1227{ 1226{
1228 USBNETHIST_FUNC(); 1227 USBNETHIST_FUNC();
1229 struct usbnet * const un = arg; 1228 struct usbnet * const un = arg;
1230 struct usbnet_private * const unp = un->un_pri; 1229 struct usbnet_private * const unp = un->un_pri;
1231 1230
1232 if (unp == NULL) 1231 if (unp == NULL)
1233 return; 1232 return;
1234 1233
1235 USBNETHIST_CALLARGSN(8, "%jd: enter", unp->unp_number, 0, 0, 0); 1234 USBNETHIST_CALLARGSN(8, "%jd: enter", unp->unp_number, 0, 0, 0);
1236 1235
1237 mutex_enter(&unp->unp_core_lock); 1236 mutex_enter(&unp->unp_core_lock);
1238 if (unp->unp_stopping || unp->unp_dying) { 1237 if (unp->unp_stopping || unp->unp_dying) {
1239 mutex_exit(&unp->unp_core_lock); 1238 mutex_exit(&unp->unp_core_lock);
1240 return; 1239 return;
1241 } 1240 }
1242 1241
1243 struct ifnet * const ifp = usbnet_ifp(un); 1242 struct ifnet * const ifp = usbnet_ifp(un);
1244 struct mii_data * const mii = usbnet_mii(un); 1243 struct mii_data * const mii = usbnet_mii(un);
1245 1244
1246 KASSERT(ifp != NULL); /* embedded member */ 1245 KASSERT(ifp != NULL); /* embedded member */
1247 1246
1248 usbnet_busy(un); 1247 usbnet_busy(un);
1249 mutex_exit(&unp->unp_core_lock); 1248 mutex_exit(&unp->unp_core_lock);
1250 1249
1251 mutex_enter(&unp->unp_txlock); 1250 mutex_enter(&unp->unp_txlock);
1252 const bool timeout = unp->unp_timer != 0 && --unp->unp_timer == 0; 1251 const bool timeout = unp->unp_timer != 0 && --unp->unp_timer == 0;
1253 mutex_exit(&unp->unp_txlock); 1252 mutex_exit(&unp->unp_txlock);
1254 if (timeout) 1253 if (timeout)
1255 usbnet_watchdog(ifp); 1254 usbnet_watchdog(ifp);
1256 1255
1257 DPRINTFN(8, "mii %#jx ifp %#jx", (uintptr_t)mii, (uintptr_t)ifp, 0, 0); 1256 DPRINTFN(8, "mii %#jx ifp %#jx", (uintptr_t)mii, (uintptr_t)ifp, 0, 0);
1258 if (mii) { 1257 if (mii) {
1259 mutex_enter(&unp->unp_core_lock); 1258 mutex_enter(&unp->unp_core_lock);
1260 mii_tick(mii); 1259 mii_tick(mii);
1261 if (!unp->unp_link) 1260 if (!unp->unp_link)
1262 (*mii->mii_statchg)(ifp); 1261 (*mii->mii_statchg)(ifp);
1263 mutex_exit(&unp->unp_core_lock); 1262 mutex_exit(&unp->unp_core_lock);
1264 } 1263 }
1265 1264
1266 /* Call driver if requested. */ 1265 /* Call driver if requested. */
1267 uno_tick(un); 1266 uno_tick(un);
1268 1267
1269 mutex_enter(&unp->unp_core_lock); 1268 mutex_enter(&unp->unp_core_lock);
1270 usbnet_unbusy(un); 1269 usbnet_unbusy(un);
1271 if (!unp->unp_stopping && !unp->unp_dying) 1270 if (!unp->unp_stopping && !unp->unp_dying)
1272 callout_schedule(&unp->unp_stat_ch, hz); 1271 callout_schedule(&unp->unp_stat_ch, hz);
1273 mutex_exit(&unp->unp_core_lock); 1272 mutex_exit(&unp->unp_core_lock);
1274} 1273}
1275 1274
1276static int 1275static int
1277usbnet_if_init(struct ifnet *ifp) 1276usbnet_if_init(struct ifnet *ifp)
1278{ 1277{
1279 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1278 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1280 struct usbnet * const un = ifp->if_softc; 1279 struct usbnet * const un = ifp->if_softc;
1281 1280
1282 KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); 1281 KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
1283 1282
1284 return uno_init(un, ifp); 1283 return uno_init(un, ifp);
1285} 1284}
1286 1285
1287 1286
1288/* Various accessors. */ 1287/* Various accessors. */
1289 1288
1290void 1289void
1291usbnet_set_link(struct usbnet *un, bool link) 1290usbnet_set_link(struct usbnet *un, bool link)
1292{ 1291{
1293 un->un_pri->unp_link = link; 1292 un->un_pri->unp_link = link;
1294} 1293}
1295 1294
1296void 1295void
1297usbnet_set_dying(struct usbnet *un, bool link) 1296usbnet_set_dying(struct usbnet *un, bool link)
1298{ 1297{
1299 un->un_pri->unp_dying = link; 1298 un->un_pri->unp_dying = link;
1300} 1299}
1301 1300
1302struct ifnet * 1301struct ifnet *
1303usbnet_ifp(struct usbnet *un) 1302usbnet_ifp(struct usbnet *un)
1304{ 1303{
1305 return &un->un_pri->unp_ec.ec_if; 1304 return &un->un_pri->unp_ec.ec_if;
1306} 1305}
1307 1306
1308struct ethercom * 1307struct ethercom *
1309usbnet_ec(struct usbnet *un) 1308usbnet_ec(struct usbnet *un)
1310{ 1309{
1311 return &un->un_pri->unp_ec; 1310 return &un->un_pri->unp_ec;
1312} 1311}
1313 1312
1314struct mii_data * 1313struct mii_data *
1315usbnet_mii(struct usbnet *un) 1314usbnet_mii(struct usbnet *un)
1316{ 1315{
1317 return un->un_pri->unp_ec.ec_mii; 1316 return un->un_pri->unp_ec.ec_mii;
1318} 1317}
1319 1318
1320krndsource_t * 1319krndsource_t *
1321usbnet_rndsrc(struct usbnet *un) 1320usbnet_rndsrc(struct usbnet *un)
1322{ 1321{
1323 return &un->un_pri->unp_rndsrc; 1322 return &un->un_pri->unp_rndsrc;
1324} 1323}
1325 1324
1326void * 1325void *
1327usbnet_softc(struct usbnet *un) 1326usbnet_softc(struct usbnet *un)
1328{ 1327{
1329 return un->un_sc; 1328 return un->un_sc;
1330} 1329}
1331 1330
1332bool 1331bool
1333usbnet_havelink(struct usbnet *un) 1332usbnet_havelink(struct usbnet *un)
1334{ 1333{
1335 return un->un_pri->unp_link; 1334 return un->un_pri->unp_link;
1336} 1335}
1337 1336
1338bool 1337bool
1339usbnet_isdying(struct usbnet *un) 1338usbnet_isdying(struct usbnet *un)
1340{ 1339{
1341 return un->un_pri->unp_dying; 1340 return un->un_pri->unp_dying;
1342} 1341}
1343 1342
1344 1343
1345/* Locking. */ 1344/* Locking. */
1346 1345
1347void 1346void
1348usbnet_lock_core(struct usbnet *un) 1347usbnet_lock_core(struct usbnet *un)
1349{ 1348{