usbnet.c revision 1.1 1 /* $NetBSD: usbnet.c,v 1.1 2019/07/31 09:13:16 mrg Exp $ */
2
3 /*
4 * Copyright (c) 2019 Matthew R. Green
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 /*
32 * Common code shared between USB ethernet drivers.
33 */
34
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.1 2019/07/31 09:13:16 mrg Exp $");
37
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/kmem.h>
41 #include <sys/module.h>
42
43 #include <dev/usb/usbnet.h>
44
45 static int usbnet_modcmd(modcmd_t, void *);
46
47 #define DPRINTF(fmt, ...) \
48 printf("%s:%d: " fmt "\n", __func__, __LINE__, ## __VA_ARGS__)
49
50 /* Interrupt handling. */
51
52 static struct mbuf *
53 usbnet_newbuf(void)
54 {
55 struct mbuf *m;
56
57 MGETHDR(m, M_DONTWAIT, MT_DATA);
58 if (m == NULL)
59 return NULL;
60
61 MCLGET(m, M_DONTWAIT);
62 if (!(m->m_flags & M_EXT)) {
63 m_freem(m);
64 return NULL;
65 }
66
67 m->m_len = m->m_pkthdr.len = MCLBYTES;
68 m_adj(m, ETHER_ALIGN);
69
70 return m;
71 }
72
73 /*
74 * usbnet_rxeof() is designed to be the done callback for rx completion.
75 * it provides generic setup and finalisation, calls a different usbnet
76 * rx_loop callback in the middle, which can use usbnet_enqueue() to
77 * enqueue a packet for higher levels.
78 */
79 void
80 usbnet_enqueue(struct usbnet * const un, uint8_t *buf, size_t buflen,
81 int flags)
82 {
83 struct ifnet *ifp = &un->un_ec.ec_if;
84 struct mbuf *m;
85
86 //DPRINTF("enter");
87 KASSERT(mutex_owned(&un->un_rxlock));
88
89 m = usbnet_newbuf();
90 if (m == NULL) {
91 ifp->if_ierrors++;
92 return;
93 }
94
95 m_set_rcvif(m, ifp);
96 m->m_pkthdr.len = m->m_len = buflen;
97 m->m_pkthdr.csum_flags = flags;
98 memcpy(mtod(m, char *), buf, buflen);
99
100 /* push the packet up */
101 if_percpuq_enqueue(ifp->if_percpuq, m);
102 }
103
104 /*
105 * A frame has been uploaded: pass the resulting mbuf chain up to
106 * the higher level protocols.
107 */
108 static void
109 usbnet_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status)
110 {
111 struct usbnet_chain *c = (struct usbnet_chain *)priv;
112 struct usbnet * const un = c->unc_un;
113 struct ifnet *ifp = &un->un_ec.ec_if;
114 uint32_t total_len;
115
116 //DPRINTF("enter");
117 mutex_enter(&un->un_rxlock);
118
119 if (un->un_dying || un->un_stopping ||
120 status == USBD_INVAL || status == USBD_NOT_STARTED ||
121 status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING))
122 goto out;
123
124 if (status != USBD_NORMAL_COMPLETION) {
125 if (usbd_ratecheck(&un->un_rx_notice))
126 aprint_error_dev(un->un_dev, "usb errors on rx: %s\n",
127 usbd_errstr(status));
128 if (status == USBD_STALLED)
129 usbd_clear_endpoint_stall_async(un->un_ep[USBNET_ENDPT_RX]);
130 goto done;
131 }
132
133 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
134
135 if (total_len > un->un_cdata.uncd_rx_bufsz) {
136 aprint_error_dev(un->un_dev,
137 "rxeof: too large transfer (%u > %u)\n",
138 total_len, un->un_cdata.uncd_rx_bufsz);
139 goto done;
140 }
141
142 (*un->un_rx_loop_cb)(un, xfer, c, total_len);
143 KASSERT(mutex_owned(&un->un_rxlock));
144
145 done:
146 if (un->un_dying || un->un_stopping)
147 goto out;
148
149 mutex_exit(&un->un_rxlock);
150
151 /* Setup new transfer. */
152 usbd_setup_xfer(xfer, c, c->unc_buf, un->un_cdata.uncd_rx_bufsz,
153 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof);
154 usbd_transfer(xfer);
155 return;
156
157 out:
158 mutex_exit(&un->un_rxlock);
159 }
160
161 static void
162 usbnet_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status)
163 {
164 struct usbnet_chain *c = (struct usbnet_chain *)priv;
165 struct usbnet * const un = c->unc_un;
166 struct usbnet_cdata *cd = &un->un_cdata;
167 struct ifnet * const ifp = usbnet_ifp(un);
168
169 //DPRINTF("enter");
170 mutex_enter(&un->un_txlock);
171 if (un->un_stopping || un->un_dying) {
172 mutex_exit(&un->un_txlock);
173 return;
174 }
175
176 KASSERT(cd->uncd_tx_cnt > 0);
177 cd->uncd_tx_cnt--;
178
179 un->un_timer = 0;
180
181 switch (status) {
182 case USBD_NOT_STARTED:
183 case USBD_CANCELLED:
184 break;
185
186 case USBD_NORMAL_COMPLETION:
187 ifp->if_opackets++;
188 break;
189
190 default:
191
192 ifp->if_oerrors++;
193 if (usbd_ratecheck(&un->un_tx_notice))
194 aprint_error_dev(un->un_dev, "usb error on tx: %s\n",
195 usbd_errstr(status));
196 if (status == USBD_STALLED)
197 usbd_clear_endpoint_stall_async(un->un_ep[USBNET_ENDPT_TX]);
198 break;
199 }
200
201 mutex_exit(&un->un_txlock);
202
203 if (status == USBD_NORMAL_COMPLETION && !IFQ_IS_EMPTY(&ifp->if_snd))
204 (*ifp->if_start)(ifp);
205 }
206
207 static void
208 usbnet_start_locked(struct ifnet *ifp)
209 {
210 struct usbnet * const un = ifp->if_softc;
211 struct usbnet_cdata *cd = &un->un_cdata;
212 struct mbuf *m;
213 unsigned length;
214 int idx;
215
216 //DPRINTF("enter");
217 KASSERT(mutex_owned(&un->un_txlock));
218 KASSERT(cd->uncd_tx_cnt <= cd->uncd_tx_list_cnt);
219
220 if (!un->un_link || (ifp->if_flags & IFF_RUNNING) == 0)
221 return;
222
223 idx = cd->uncd_tx_prod;
224 //DPRINTF("idx %d", idx);
225 while (cd->uncd_tx_cnt < cd->uncd_tx_list_cnt) {
226 IFQ_POLL(&ifp->if_snd, m);
227 if (m == NULL)
228 break;
229
230 struct usbnet_chain *c = &un->un_cdata.uncd_tx_chain[idx];
231
232 length = (*un->un_tx_prepare_cb)(un, m, c);
233 if (length == 0) {
234 ifp->if_oerrors++;
235 break;
236 }
237
238 if (__predict_false(c->unc_xfer == NULL)) {
239 ifp->if_oerrors++;
240 break;
241 }
242
243 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, length,
244 un->un_tx_xfer_flags, 10000, usbnet_txeof);
245
246 /* Transmit */
247 usbd_status err = usbd_transfer(c->unc_xfer);
248 if (err != USBD_IN_PROGRESS) {
249 ifp->if_oerrors++;
250 break;
251 }
252
253 IFQ_DEQUEUE(&ifp->if_snd, m);
254
255 /*
256 * If there's a BPF listener, bounce a copy of this frame
257 * to him.
258 */
259 bpf_mtap(ifp, m, BPF_D_OUT);
260 m_freem(m);
261
262 idx = (idx + 1) % cd->uncd_tx_list_cnt;
263 cd->uncd_tx_cnt++;
264 }
265 //DPRINTF("idx %d", idx);
266 cd->uncd_tx_prod = idx;
267
268 /*
269 * Set a timeout in case the chip goes out to lunch.
270 */
271 un->un_timer = 5;
272 }
273
274 static void
275 usbnet_start(struct ifnet *ifp)
276 {
277 struct usbnet * const un = ifp->if_softc;
278
279 //DPRINTF("enter");
280 mutex_enter(&un->un_txlock);
281 if (!un->un_stopping)
282 usbnet_start_locked(ifp);
283 mutex_exit(&un->un_txlock);
284 }
285
286 /*
287 * Chain management.
288 *
289 * RX and TX are identical. Keep them that way.
290 */
291
292 /* Start of common RX functions */
293
294 static size_t
295 usbnet_rx_list_size(struct usbnet_cdata *cd)
296 {
297 return sizeof(*cd->uncd_rx_chain) * cd->uncd_rx_list_cnt;
298 }
299
300 static void
301 usbnet_rx_list_alloc(struct usbnet *un, unsigned cnt)
302 {
303 struct usbnet_cdata *cd = &un->un_cdata;
304
305 cd->uncd_rx_list_cnt = cnt;
306 cd->uncd_rx_chain = kmem_zalloc(usbnet_rx_list_size(cd), KM_SLEEP);
307 }
308
309 static void
310 usbnet_rx_list_free(struct usbnet *un)
311 {
312 struct usbnet_cdata *cd = &un->un_cdata;
313
314 if (cd->uncd_rx_chain) {
315 kmem_free(cd->uncd_rx_chain, usbnet_rx_list_size(cd));
316 cd->uncd_rx_chain = NULL;
317 }
318 }
319
320 static int
321 usbnet_rx_list_init(struct usbnet *un, unsigned xfer_flags)
322 {
323 struct usbnet_cdata *cd = &un->un_cdata;
324
325 for (size_t i = 0; i < cd->uncd_rx_list_cnt; i++) {
326 struct usbnet_chain *c = &cd->uncd_rx_chain[i];
327
328 c->unc_un = un;
329 if (c->unc_xfer == NULL) {
330 int err = usbd_create_xfer(un->un_ep[USBNET_ENDPT_RX],
331 cd->uncd_rx_bufsz, xfer_flags, 0, &c->unc_xfer);
332 if (err)
333 return err;
334 c->unc_buf = usbd_get_buffer(c->unc_xfer);
335 }
336 }
337
338 return 0;
339 }
340
341 static void
342 usbnet_rx_list_fini(struct usbnet *un)
343 {
344 struct usbnet_cdata *cd = &un->un_cdata;
345
346 for (size_t i = 0; i < cd->uncd_rx_list_cnt; i++) {
347 struct usbnet_chain *c = &cd->uncd_rx_chain[i];
348
349 if (c->unc_xfer != NULL) {
350 usbd_destroy_xfer(c->unc_xfer);
351 c->unc_xfer = NULL;
352 c->unc_buf = NULL;
353 }
354 }
355 }
356
357 /* End of common RX functions */
358
359 static void
360 usbnet_rx_start_pipes(struct usbnet *un, usbd_callback cb)
361 {
362 struct usbnet_cdata *cd = &un->un_cdata;
363
364 mutex_enter(&un->un_rxlock);
365 mutex_enter(&un->un_txlock);
366 un->un_stopping = false;
367
368 for (size_t i = 0; i < cd->uncd_rx_list_cnt; i++) {
369 struct usbnet_chain *c = &cd->uncd_rx_chain[i];
370
371 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, cd->uncd_rx_bufsz,
372 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, cb);
373 usbd_transfer(c->unc_xfer);
374 }
375
376 mutex_exit(&un->un_txlock);
377 mutex_exit(&un->un_rxlock);
378 }
379
380 /* Start of common TX functions */
381
382 static size_t
383 usbnet_tx_list_size(struct usbnet_cdata *cd)
384 {
385 return sizeof(*cd->uncd_tx_chain) * cd->uncd_tx_list_cnt;
386 }
387
388 static void
389 usbnet_tx_list_alloc(struct usbnet *un, unsigned cnt)
390 {
391 struct usbnet_cdata *cd = &un->un_cdata;
392
393 cd->uncd_tx_list_cnt = cnt;
394 cd->uncd_tx_chain = kmem_zalloc(usbnet_tx_list_size(cd), KM_SLEEP);
395 }
396
397 static void
398 usbnet_tx_list_free(struct usbnet *un)
399 {
400 struct usbnet_cdata *cd = &un->un_cdata;
401
402 if (cd->uncd_tx_chain) {
403 kmem_free(cd->uncd_tx_chain, usbnet_tx_list_size(cd));
404 cd->uncd_tx_chain = NULL;
405 }
406 }
407
408 static int
409 usbnet_tx_list_init(struct usbnet *un, unsigned xfer_flags)
410 {
411 struct usbnet_cdata *cd = &un->un_cdata;
412
413 for (size_t i = 0; i < cd->uncd_tx_list_cnt; i++) {
414 struct usbnet_chain *c = &cd->uncd_tx_chain[i];
415
416 c->unc_un = un;
417 if (c->unc_xfer == NULL) {
418 int err = usbd_create_xfer(un->un_ep[USBNET_ENDPT_TX],
419 cd->uncd_tx_bufsz, xfer_flags, 0, &c->unc_xfer);
420 if (err)
421 return err;
422 c->unc_buf = usbd_get_buffer(c->unc_xfer);
423 }
424 }
425
426 return 0;
427 }
428
429 static void
430 usbnet_tx_list_fini(struct usbnet *un)
431 {
432 struct usbnet_cdata *cd = &un->un_cdata;
433
434 for (size_t i = 0; i < cd->uncd_tx_list_cnt; i++) {
435 struct usbnet_chain *c = &cd->uncd_tx_chain[i];
436
437 if (c->unc_xfer != NULL) {
438 usbd_destroy_xfer(c->unc_xfer);
439 c->unc_xfer = NULL;
440 c->unc_buf = NULL;
441 }
442 }
443 }
444
445 /* End of common TX functions */
446
447 /* Endpoint pipe management. */
448
449 static void
450 usbnet_ep_close_pipes(struct usbnet *un)
451 {
452 for (size_t i = 0; i < __arraycount(un->un_ep); i++) {
453 if (un->un_ep[i] == NULL)
454 continue;
455 usbd_status err = usbd_close_pipe(un->un_ep[i]);
456 if (err)
457 aprint_error_dev(un->un_dev, "close pipe %zu: %s\n", i,
458 usbd_errstr(err));
459 un->un_ep[i] = NULL;
460 }
461 }
462
463 static usbd_status
464 usbnet_ep_open_pipes(struct usbnet *un)
465 {
466 for (size_t i = 0; i < __arraycount(un->un_ep); i++) {
467 if (un->un_ed[i] == 0)
468 continue;
469 usbd_status err = usbd_open_pipe(un->un_iface, un->un_ed[i],
470 USBD_EXCLUSIVE_USE | USBD_MPSAFE, &un->un_ep[i]);
471 if (err) {
472 usbnet_ep_close_pipes(un);
473 return err;
474 }
475 }
476
477 return USBD_NORMAL_COMPLETION;
478 }
479
480 static usbd_status
481 usbnet_ep_stop_pipes(struct usbnet *un)
482 {
483 for (size_t i = 0; i < __arraycount(un->un_ep); i++) {
484 if (un->un_ep[i] == NULL)
485 continue;
486 usbd_status err = usbd_abort_pipe(un->un_ep[i]);
487 if (err)
488 return err;
489 }
490
491 return USBD_NORMAL_COMPLETION;
492 }
493
494 int
495 usbnet_init_rx_tx(struct usbnet * const un, unsigned rxflags, unsigned txflags)
496 {
497 struct ifnet * const ifp = usbnet_ifp(un);
498 usbd_status err;
499
500 /* Open RX and TX pipes. */
501 err = usbnet_ep_open_pipes(un);
502 if (err) {
503 aprint_error_dev(un->un_dev, "open rx/tx pipes failed: %s\n",
504 usbd_errstr(err));
505 return EIO;
506 }
507
508 /* Init RX ring. */
509 if (usbnet_rx_list_init(un, rxflags)) {
510 aprint_error_dev(un->un_dev, "rx list init failed\n");
511 goto nobufs;
512 }
513
514 /* Init TX ring. */
515 if (usbnet_tx_list_init(un, txflags)) {
516 aprint_error_dev(un->un_dev, "tx list init failed\n");
517 goto nobufs;
518 }
519
520 /* Start up the receive pipe(s). */
521 usbnet_rx_start_pipes(un, usbnet_rxeof);
522
523 /* Indicate we are up and running. */
524 KASSERT(IFNET_LOCKED(ifp));
525 ifp->if_flags |= IFF_RUNNING;
526
527 callout_schedule(&un->un_stat_ch, hz);
528 return 0;
529
530 nobufs:
531 usbnet_rx_list_fini(un);
532 usbnet_tx_list_fini(un);
533 usbnet_ep_close_pipes(un);
534
535 return ENOBUFS;
536 }
537
538 /* MII management. */
539
540 /*
541 * Access functions for MII. Take the MII lock to call access MII regs.
542 * Two forms: usbnet (softc) lock currently held or not.
543 */
544 void
545 usbnet_lock_mii(struct usbnet *un)
546 {
547
548 mutex_enter(&un->un_lock);
549 un->un_refcnt++;
550 mutex_exit(&un->un_lock);
551
552 mutex_enter(&un->un_miilock);
553 }
554
555 void
556 usbnet_lock_mii_un_locked(struct usbnet *un)
557 {
558 KASSERT(mutex_owned(&un->un_lock));
559
560 un->un_refcnt++;
561 mutex_enter(&un->un_miilock);
562 }
563
564 void
565 usbnet_unlock_mii(struct usbnet *un)
566 {
567
568 mutex_exit(&un->un_miilock);
569 mutex_enter(&un->un_lock);
570 if (--un->un_refcnt < 0)
571 cv_broadcast(&un->un_detachcv);
572 mutex_exit(&un->un_lock);
573 }
574
575 void
576 usbnet_unlock_mii_un_locked(struct usbnet *un)
577 {
578 KASSERT(mutex_owned(&un->un_lock));
579
580 mutex_exit(&un->un_miilock);
581 if (--un->un_refcnt < 0)
582 cv_broadcast(&un->un_detachcv);
583 }
584
585 int
586 usbnet_miibus_readreg(device_t dev, int phy, int reg, uint16_t *val)
587 {
588 struct usbnet * const un = device_private(dev);
589 usbd_status err;
590
591 mutex_enter(&un->un_lock);
592 if (un->un_dying || un->un_phyno != phy) {
593 mutex_exit(&un->un_lock);
594 return EIO;
595 }
596 mutex_exit(&un->un_lock);
597
598 usbnet_lock_mii(un);
599 err = (*un->un_read_reg_cb)(un, reg, phy, val);
600 usbnet_unlock_mii(un);
601
602 if (err) {
603 aprint_error_dev(un->un_dev, "read PHY failed: %d\n", err);
604 return EIO;
605 }
606
607 return 0;
608 }
609
610 int
611 usbnet_miibus_writereg(device_t dev, int phy, int reg, uint16_t val)
612 {
613 struct usbnet * const un = device_private(dev);
614 usbd_status err;
615
616 mutex_enter(&un->un_lock);
617 if (un->un_dying || un->un_phyno != phy) {
618 mutex_exit(&un->un_lock);
619 return EIO;
620 }
621 mutex_exit(&un->un_lock);
622
623 usbnet_lock_mii(un);
624 err = (*un->un_write_reg_cb)(un, reg, phy, val);
625 usbnet_unlock_mii(un);
626
627 if (err) {
628 aprint_error_dev(un->un_dev, "write PHY failed: %d\n", err);
629 return EIO;
630 }
631
632 return 0;
633 }
634
635 void
636 usbnet_miibus_statchg(struct ifnet *ifp)
637 {
638 struct usbnet * const un = ifp->if_softc;
639
640 (*un->un_statchg_cb)(ifp);
641 }
642
643 static int
644 usbnet_media_upd(struct ifnet *ifp)
645 {
646 struct usbnet * const un = ifp->if_softc;
647 struct mii_data * const mii = usbnet_mii(un);
648
649 if (un->un_dying)
650 return EIO;
651
652 un->un_link = false;
653
654 if (mii->mii_instance) {
655 struct mii_softc *miisc;
656
657 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
658 mii_phy_reset(miisc);
659 }
660
661 return ether_mediachange(ifp);
662 }
663
664 /* ioctl */
665
666 static int
667 usbnet_ifflags_cb(struct ethercom *ec)
668 {
669 struct ifnet *ifp = &ec->ec_if;
670 struct usbnet *un = ifp->if_softc;
671 int rv = 0;
672
673 mutex_enter(&un->un_lock);
674
675 const int changed = ifp->if_flags ^ un->un_if_flags;
676 if ((changed & ~(IFF_CANTCHANGE | IFF_DEBUG)) == 0) {
677 un->un_if_flags = ifp->if_flags;
678 if ((changed & IFF_PROMISC) != 0)
679 rv = ENETRESET;
680 } else {
681 rv = ENETRESET;
682 }
683
684 mutex_exit(&un->un_lock);
685
686 return rv;
687 }
688
689 static int
690 usbnet_ioctl(struct ifnet *ifp, u_long cmd, void *data)
691 {
692 struct usbnet * const un = ifp->if_softc;
693 int error;
694
695 error = ether_ioctl(ifp, cmd, data);
696 if (error == ENETRESET && un->un_ioctl_cb)
697 error = (*un->un_ioctl_cb)(ifp, cmd, data);
698
699 return error;
700 }
701
702 /*
703 * Generic stop network function:
704 * - mark as stopping
705 * - call DD routine to stop the device
706 * - turn off running, timer, statchg callout, link
707 * - stop transfers
708 * - free RX and TX resources
709 * - close pipes
710 *
711 * usbnet_stop() is exported for drivers to use, expects lock held.
712 *
713 * usbnet_stop_ifp() is for the if_stop handler.
714 */
715 void
716 usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
717 {
718 KASSERT(mutex_owned(&un->un_lock));
719
720 mutex_enter(&un->un_rxlock);
721 mutex_enter(&un->un_txlock);
722 un->un_stopping = true;
723 mutex_exit(&un->un_txlock);
724 mutex_exit(&un->un_rxlock);
725
726 if (un->un_stop_cb)
727 (*un->un_stop_cb)(ifp, disable);
728
729 /*
730 * XXXSMP Would like to
731 * KASSERT(IFNET_LOCKED(ifp))
732 * here but the locking order is:
733 * ifnet -> unlock -> rxlock -> txlock
734 * and unlock is already held.
735 */
736 ifp->if_flags &= ~IFF_RUNNING;
737 un->un_timer = 0;
738
739 callout_stop(&un->un_stat_ch);
740 un->un_link = false;
741
742 /* Stop transfers. */
743 usbnet_ep_stop_pipes(un);
744
745 /* Free RX/TX resources. */
746 usbnet_rx_list_fini(un);
747 usbnet_tx_list_fini(un);
748
749 /* Close pipes. */
750 usbnet_ep_close_pipes(un);
751 }
752
753 static void
754 usbnet_stop_ifp(struct ifnet *ifp, int disable)
755 {
756 struct usbnet * const un = ifp->if_softc;
757
758 mutex_enter(&un->un_lock);
759 usbnet_stop(un, ifp, disable);
760 mutex_exit(&un->un_lock);
761 }
762
763 /*
764 * Generic tick task function.
765 *
766 * usbnet_tick() is triggered from a callout, and triggers a call to
767 * usbnet_tick_task() from the usb_task subsystem.
768 */
769 static void
770 usbnet_tick(void *arg)
771 {
772 struct usbnet * const un = arg;
773
774 mutex_enter(&un->un_lock);
775 if (!un->un_stopping && !un->un_dying) {
776 /* Perform periodic stuff in process context */
777 usb_add_task(un->un_udev, &un->un_ticktask, USB_TASKQ_DRIVER);
778 }
779 mutex_exit(&un->un_lock);
780 }
781
782 static void
783 usbnet_watchdog(struct ifnet *ifp)
784 {
785 struct usbnet * const un = ifp->if_softc;
786 struct usbnet_cdata *cd = &un->un_cdata;
787 usbd_status stat;
788
789 ifp->if_oerrors++;
790 aprint_error_dev(un->un_dev, "watchdog timeout\n");
791
792 if (cd->uncd_tx_cnt > 0) {
793 /*
794 * XXX index 0
795 */
796 struct usbnet_chain *c = &un->un_cdata.uncd_tx_chain[0];
797 usbd_get_xfer_status(c->unc_xfer, NULL, NULL, NULL, &stat);
798 usbnet_txeof(c->unc_xfer, c, stat);
799 }
800
801 if (!IFQ_IS_EMPTY(&ifp->if_snd))
802 (*ifp->if_start)(ifp);
803 }
804
805 static void
806 usbnet_tick_task(void *arg)
807 {
808 struct usbnet * const un = arg;
809
810 mutex_enter(&un->un_lock);
811 if (un->un_stopping || un->un_dying) {
812 mutex_exit(&un->un_lock);
813 return;
814 }
815
816 struct ifnet * const ifp = usbnet_ifp(un);
817 struct mii_data * const mii = usbnet_mii(un);
818
819 un->un_refcnt++;
820 mutex_exit(&un->un_lock);
821
822 if (ifp && un->un_timer != 0 && --un->un_timer == 0)
823 usbnet_watchdog(ifp);
824
825 if (mii && ifp) {
826 mii_tick(mii);
827
828 if (!un->un_link)
829 (*mii->mii_statchg)(ifp);
830 }
831
832 mutex_enter(&un->un_lock);
833 if (--un->un_refcnt < 0)
834 cv_broadcast(&un->un_detachcv);
835 if (!un->un_stopping && !un->un_dying)
836 callout_schedule(&un->un_stat_ch, hz);
837 mutex_exit(&un->un_lock);
838 }
839
840 static int
841 usbnet_init(struct ifnet *ifp)
842 {
843 struct usbnet * const un = ifp->if_softc;
844
845 return (*un->un_init_cb)(ifp);
846 }
847
848 /* Autoconf management. */
849
850 /*
851 * usbnet_attach() and usbnet_attach_ifp() perform setup of the relevant
852 * 'usbnet'. The first is enough to enable device access (eg, endpoints
853 * are connected and commands can be sent), and the second connects the
854 * device to the system networking.
855 *
856 * Always call usbnet_detach(), even if usbnet_attach_ifp() is skippped.
857 * Also usable as driver detach directly.
858 */
859 void
860 usbnet_attach(struct usbnet *un,
861 const char *detname, /* detach cv name */
862 unsigned rx_list_cnt, /* size of rx chain list */
863 unsigned tx_list_cnt) /* size of tx chain list */
864 {
865
866 KASSERT(un->un_tx_prepare_cb);
867 KASSERT(un->un_rx_loop_cb);
868 KASSERT(un->un_init_cb);
869 KASSERT(un->un_cdata.uncd_rx_bufsz);
870 KASSERT(un->un_cdata.uncd_tx_bufsz);
871 KASSERT(rx_list_cnt);
872 KASSERT(tx_list_cnt);
873
874 ether_set_ifflags_cb(&un->un_ec, usbnet_ifflags_cb);
875
876 usb_init_task(&un->un_ticktask, usbnet_tick_task, un, USB_TASKQ_MPSAFE);
877 callout_init(&un->un_stat_ch, CALLOUT_MPSAFE);
878 callout_setfunc(&un->un_stat_ch, usbnet_tick, un);
879
880 mutex_init(&un->un_miilock, MUTEX_DEFAULT, IPL_NONE);
881 mutex_init(&un->un_txlock, MUTEX_DEFAULT, IPL_SOFTUSB);
882 mutex_init(&un->un_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB);
883 mutex_init(&un->un_lock, MUTEX_DEFAULT, IPL_NONE);
884 cv_init(&un->un_detachcv, detname);
885
886 rnd_attach_source(&un->un_rndsrc, device_xname(un->un_dev),
887 RND_TYPE_NET, RND_FLAG_DEFAULT);
888
889 usbnet_rx_list_alloc(un, rx_list_cnt);
890 usbnet_tx_list_alloc(un, tx_list_cnt);
891
892 un->un_attached = true;
893 }
894
895 static void
896 usbnet_attach_mii(struct usbnet *un)
897 {
898 struct mii_data * const mii = &un->un_mii;
899 struct ifnet *ifp = usbnet_ifp(un);
900
901 mii->mii_ifp = ifp;
902 mii->mii_readreg = usbnet_miibus_readreg;
903 mii->mii_writereg = usbnet_miibus_writereg;
904 mii->mii_statchg = usbnet_miibus_statchg;
905 mii->mii_flags = MIIF_AUTOTSLEEP;
906
907 un->un_ec.ec_mii = mii;
908 ifmedia_init(&mii->mii_media, 0, usbnet_media_upd, ether_mediastatus);
909 mii_attach(un->un_dev, mii, 0xffffffff, MII_PHY_ANY,
910 MII_OFFSET_ANY, 0);
911
912 if (LIST_FIRST(&mii->mii_phys) == NULL) {
913 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
914 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
915 } else
916 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
917
918 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, un->un_udev, un->un_dev);
919
920 if (!pmf_device_register(un->un_dev, NULL, NULL))
921 aprint_error_dev(un->un_dev, "couldn't establish power handler\n");
922 }
923
924 void
925 usbnet_attach_ifp(struct usbnet *un,
926 bool have_mii, /* setup MII */
927 unsigned if_flags, /* additional if_flags */
928 unsigned if_extflags) /* additional if_extflags */
929 {
930 struct ifnet *ifp = usbnet_ifp(un);
931
932 KASSERT(un->un_attached);
933
934 IFQ_SET_READY(&ifp->if_snd);
935
936 ifp->if_softc = un;
937 strlcpy(ifp->if_xname, device_xname(un->un_dev), IFNAMSIZ);
938 ifp->if_flags = if_flags;
939 ifp->if_extflags = IFEF_MPSAFE | if_extflags;
940 ifp->if_ioctl = usbnet_ioctl;
941 ifp->if_start = usbnet_start;
942 ifp->if_init = usbnet_init;
943 ifp->if_stop = usbnet_stop_ifp;
944
945 IFQ_SET_READY(&ifp->if_snd);
946
947 if (have_mii)
948 usbnet_attach_mii(un);
949
950 /* Attach the interface. */
951 if_attach(ifp);
952 ether_ifattach(ifp, un->un_eaddr);
953 }
954
955 int
956 usbnet_detach(device_t self, int flags)
957 {
958 struct usbnet * const un = device_private(self);
959 struct ifnet *ifp = usbnet_ifp(un);
960 struct mii_data *mii = usbnet_mii(un);
961
962 mutex_enter(&un->un_lock);
963 un->un_dying = true;
964 mutex_exit(&un->un_lock);
965
966 /* Detached before attached finished, so just bail out. */
967 if (!un->un_attached)
968 return 0;
969
970 callout_halt(&un->un_stat_ch, NULL);
971 usb_rem_task_wait(un->un_udev, &un->un_ticktask, USB_TASKQ_DRIVER, NULL);
972
973 if (ifp->if_flags & IFF_RUNNING) {
974 IFNET_LOCK(ifp);
975 usbnet_stop_ifp(ifp, 1);
976 IFNET_UNLOCK(ifp);
977 }
978
979 mutex_enter(&un->un_lock);
980 un->un_refcnt--;
981 while (un->un_refcnt > 0) {
982 /* Wait for processes to go away */
983 cv_wait(&un->un_detachcv, &un->un_lock);
984 }
985 mutex_exit(&un->un_lock);
986
987 usbnet_rx_list_free(un);
988 usbnet_tx_list_free(un);
989
990 callout_destroy(&un->un_stat_ch);
991 rnd_detach_source(&un->un_rndsrc);
992
993 if (mii) {
994 mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY);
995 ifmedia_delete_instance(&mii->mii_media, IFM_INST_ANY);
996 }
997 if (ifp->if_softc) {
998 ether_ifdetach(ifp);
999 if_detach(ifp);
1000 }
1001
1002 cv_destroy(&un->un_detachcv);
1003 mutex_destroy(&un->un_lock);
1004 mutex_destroy(&un->un_rxlock);
1005 mutex_destroy(&un->un_txlock);
1006 mutex_destroy(&un->un_miilock);
1007
1008 pmf_device_deregister(un->un_dev);
1009
1010 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, un->un_udev, un->un_dev);
1011
1012 return 0;
1013 }
1014
1015 int
1016 usbnet_activate(device_t self, devact_t act)
1017 {
1018 struct usbnet * const un = device_private(self);
1019 struct ifnet * const ifp = usbnet_ifp(un);
1020
1021 switch (act) {
1022 case DVACT_DEACTIVATE:
1023 if_deactivate(ifp);
1024
1025 mutex_enter(&un->un_lock);
1026 un->un_dying = true;
1027 mutex_exit(&un->un_lock);
1028
1029 mutex_enter(&un->un_rxlock);
1030 mutex_enter(&un->un_txlock);
1031 un->un_stopping = true;
1032 mutex_exit(&un->un_txlock);
1033 mutex_exit(&un->un_rxlock);
1034
1035 return 0;
1036 default:
1037 return EOPNOTSUPP;
1038 }
1039 }
1040
1041 MODULE(MODULE_CLASS_MISC, usbnet, NULL);
1042
1043 static int
1044 usbnet_modcmd(modcmd_t cmd, void *arg)
1045 {
1046 switch (cmd) {
1047 case MODULE_CMD_INIT:
1048 case MODULE_CMD_FINI:
1049 return 0;
1050 case MODULE_CMD_STAT:
1051 case MODULE_CMD_AUTOUNLOAD:
1052 default:
1053 return ENOTTY;
1054 }
1055 }
1056