usbnet: Apply hardware multicast filter updates synchronously again. To make this work: 1. Do it only under a new lock, unp_mcastlock. This lock lives at IPL_SOFTCLOCK so it can be taken from network stack callouts. It is forbidden to acquire the usbnet core lock under unp_mcastlock. 2. Do it only after usbnet_init_rx_tx and before usbnet_stop; if issued at any other time, drop the update on the floor. 3. Make usbnet_init_rx_tx apply any pending multicast filter updates under the lock before setting the flag that allows SIOCADDMULTI or SIOCDELMULTI to apply the updates. 4. Remove core lock asserts from various drivers' register access routines. This is necessary because the multicast filter updates are done with register reads/writes, but _cannot_ take the core lock when the caller holds softnet_lock. This now programs the hardware multicast filter redundantly in many drivers which already explicitly call *_uno_mcast from the *_uno_init routines. This is probably harmless, but it will likely be better to remove the explicit calls.diff -r1.180 -r1.181 src/sys/dev/usb/if_aue.c
(riastradh)
--- src/sys/dev/usb/if_aue.c 2022/03/03 05:53:14 1.180
+++ src/sys/dev/usb/if_aue.c 2022/03/03 05:53:23 1.181
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_aue.c,v 1.180 2022/03/03 05:53:14 riastradh Exp $ */ | 1 | /* $NetBSD: if_aue.c,v 1.181 2022/03/03 05:53:23 riastradh Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1997, 1998, 1999, 2000 | 4 | * Copyright (c) 1997, 1998, 1999, 2000 | |
5 | * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. | 5 | * Bill Paul <wpaul@ee.columbia.edu>. 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. | |
@@ -66,27 +66,27 @@ | @@ -66,27 +66,27 @@ | |||
66 | /* | 66 | /* | |
67 | * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. | 67 | * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. | |
68 | */ | 68 | */ | |
69 | 69 | |||
70 | /* | 70 | /* | |
71 | * TODO: | 71 | * TODO: | |
72 | * better error messages from rxstat | 72 | * better error messages from rxstat | |
73 | * more error checks | 73 | * more error checks | |
74 | * investigate short rx problem | 74 | * investigate short rx problem | |
75 | * proper cleanup on errors | 75 | * proper cleanup on errors | |
76 | */ | 76 | */ | |
77 | 77 | |||
78 | #include <sys/cdefs.h> | 78 | #include <sys/cdefs.h> | |
79 | __KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.180 2022/03/03 05:53:14 riastradh Exp $"); | 79 | __KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.181 2022/03/03 05:53:23 riastradh Exp $"); | |
80 | 80 | |||
81 | #ifdef _KERNEL_OPT | 81 | #ifdef _KERNEL_OPT | |
82 | #include "opt_usb.h" | 82 | #include "opt_usb.h" | |
83 | #include "opt_inet.h" | 83 | #include "opt_inet.h" | |
84 | #endif | 84 | #endif | |
85 | 85 | |||
86 | #include <sys/param.h> | 86 | #include <sys/param.h> | |
87 | 87 | |||
88 | #include <dev/usb/usbnet.h> | 88 | #include <dev/usb/usbnet.h> | |
89 | #include <dev/usb/usbhist.h> | 89 | #include <dev/usb/usbhist.h> | |
90 | #include <dev/usb/if_auereg.h> | 90 | #include <dev/usb/if_auereg.h> | |
91 | 91 | |||
92 | #ifdef INET | 92 | #ifdef INET | |
@@ -274,28 +274,26 @@ static int aue_csr_write_2(struct aue_so | @@ -274,28 +274,26 @@ static int aue_csr_write_2(struct aue_so | |||
274 | aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x)) | 274 | aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x)) | |
275 | 275 | |||
276 | #define AUE_CLRBIT(sc, reg, x) \ | 276 | #define AUE_CLRBIT(sc, reg, x) \ | |
277 | aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x)) | 277 | aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x)) | |
278 | 278 | |||
279 | static int | 279 | static int | |
280 | aue_csr_read_1(struct aue_softc *sc, int reg) | 280 | aue_csr_read_1(struct aue_softc *sc, int reg) | |
281 | { | 281 | { | |
282 | struct usbnet * const un = &sc->aue_un; | 282 | struct usbnet * const un = &sc->aue_un; | |
283 | usb_device_request_t req; | 283 | usb_device_request_t req; | |
284 | usbd_status err; | 284 | usbd_status err; | |
285 | uByte val = 0; | 285 | uByte val = 0; | |
286 | 286 | |||
287 | usbnet_isowned_core(un); | |||
288 | ||||
289 | if (usbnet_isdying(un)) | 287 | if (usbnet_isdying(un)) | |
290 | return 0; | 288 | return 0; | |
291 | 289 | |||
292 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | 290 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | |
293 | req.bRequest = AUE_UR_READREG; | 291 | req.bRequest = AUE_UR_READREG; | |
294 | USETW(req.wValue, 0); | 292 | USETW(req.wValue, 0); | |
295 | USETW(req.wIndex, reg); | 293 | USETW(req.wIndex, reg); | |
296 | USETW(req.wLength, 1); | 294 | USETW(req.wLength, 1); | |
297 | 295 | |||
298 | err = usbd_do_request(un->un_udev, &req, &val); | 296 | err = usbd_do_request(un->un_udev, &req, &val); | |
299 | 297 | |||
300 | if (err) { | 298 | if (err) { | |
301 | AUEHIST_FUNC(); | 299 | AUEHIST_FUNC(); | |
@@ -305,28 +303,26 @@ aue_csr_read_1(struct aue_softc *sc, int | @@ -305,28 +303,26 @@ aue_csr_read_1(struct aue_softc *sc, int | |||
305 | } | 303 | } | |
306 | 304 | |||
307 | return val; | 305 | return val; | |
308 | } | 306 | } | |
309 | 307 | |||
310 | static int | 308 | static int | |
311 | aue_csr_read_2(struct aue_softc *sc, int reg) | 309 | aue_csr_read_2(struct aue_softc *sc, int reg) | |
312 | { | 310 | { | |
313 | struct usbnet * const un = &sc->aue_un; | 311 | struct usbnet * const un = &sc->aue_un; | |
314 | usb_device_request_t req; | 312 | usb_device_request_t req; | |
315 | usbd_status err; | 313 | usbd_status err; | |
316 | uWord val; | 314 | uWord val; | |
317 | 315 | |||
318 | usbnet_isowned_core(un); | |||
319 | ||||
320 | if (usbnet_isdying(un)) | 316 | if (usbnet_isdying(un)) | |
321 | return 0; | 317 | return 0; | |
322 | 318 | |||
323 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | 319 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | |
324 | req.bRequest = AUE_UR_READREG; | 320 | req.bRequest = AUE_UR_READREG; | |
325 | USETW(req.wValue, 0); | 321 | USETW(req.wValue, 0); | |
326 | USETW(req.wIndex, reg); | 322 | USETW(req.wIndex, reg); | |
327 | USETW(req.wLength, 2); | 323 | USETW(req.wLength, 2); | |
328 | 324 | |||
329 | err = usbd_do_request(un->un_udev, &req, &val); | 325 | err = usbd_do_request(un->un_udev, &req, &val); | |
330 | 326 | |||
331 | if (err) { | 327 | if (err) { | |
332 | AUEHIST_FUNC(); | 328 | AUEHIST_FUNC(); | |
@@ -336,28 +332,26 @@ aue_csr_read_2(struct aue_softc *sc, int | @@ -336,28 +332,26 @@ aue_csr_read_2(struct aue_softc *sc, int | |||
336 | } | 332 | } | |
337 | 333 | |||
338 | return UGETW(val); | 334 | return UGETW(val); | |
339 | } | 335 | } | |
340 | 336 | |||
341 | static int | 337 | static int | |
342 | aue_csr_write_1(struct aue_softc *sc, int reg, int aval) | 338 | aue_csr_write_1(struct aue_softc *sc, int reg, int aval) | |
343 | { | 339 | { | |
344 | struct usbnet * const un = &sc->aue_un; | 340 | struct usbnet * const un = &sc->aue_un; | |
345 | usb_device_request_t req; | 341 | usb_device_request_t req; | |
346 | usbd_status err; | 342 | usbd_status err; | |
347 | uByte val; | 343 | uByte val; | |
348 | 344 | |||
349 | usbnet_isowned_core(un); | |||
350 | ||||
351 | if (usbnet_isdying(un)) | 345 | if (usbnet_isdying(un)) | |
352 | return 0; | 346 | return 0; | |
353 | 347 | |||
354 | val = aval; | 348 | val = aval; | |
355 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | 349 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | |
356 | req.bRequest = AUE_UR_WRITEREG; | 350 | req.bRequest = AUE_UR_WRITEREG; | |
357 | USETW(req.wValue, val); | 351 | USETW(req.wValue, val); | |
358 | USETW(req.wIndex, reg); | 352 | USETW(req.wIndex, reg); | |
359 | USETW(req.wLength, 1); | 353 | USETW(req.wLength, 1); | |
360 | 354 | |||
361 | err = usbd_do_request(un->un_udev, &req, &val); | 355 | err = usbd_do_request(un->un_udev, &req, &val); | |
362 | 356 | |||
363 | if (err) { | 357 | if (err) { | |
@@ -368,28 +362,26 @@ aue_csr_write_1(struct aue_softc *sc, in | @@ -368,28 +362,26 @@ aue_csr_write_1(struct aue_softc *sc, in | |||
368 | } | 362 | } | |
369 | 363 | |||
370 | return 0; | 364 | return 0; | |
371 | } | 365 | } | |
372 | 366 | |||
373 | static int | 367 | static int | |
374 | aue_csr_write_2(struct aue_softc *sc, int reg, int aval) | 368 | aue_csr_write_2(struct aue_softc *sc, int reg, int aval) | |
375 | { | 369 | { | |
376 | struct usbnet * const un = &sc->aue_un; | 370 | struct usbnet * const un = &sc->aue_un; | |
377 | usb_device_request_t req; | 371 | usb_device_request_t req; | |
378 | usbd_status err; | 372 | usbd_status err; | |
379 | uWord val; | 373 | uWord val; | |
380 | 374 | |||
381 | usbnet_isowned_core(un); | |||
382 | ||||
383 | if (usbnet_isdying(un)) | 375 | if (usbnet_isdying(un)) | |
384 | return 0; | 376 | return 0; | |
385 | 377 | |||
386 | USETW(val, aval); | 378 | USETW(val, aval); | |
387 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | 379 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | |
388 | req.bRequest = AUE_UR_WRITEREG; | 380 | req.bRequest = AUE_UR_WRITEREG; | |
389 | USETW(req.wValue, aval); | 381 | USETW(req.wValue, aval); | |
390 | USETW(req.wIndex, reg); | 382 | USETW(req.wIndex, reg); | |
391 | USETW(req.wLength, 2); | 383 | USETW(req.wLength, 2); | |
392 | 384 | |||
393 | err = usbd_do_request(un->un_udev, &req, &val); | 385 | err = usbd_do_request(un->un_udev, &req, &val); | |
394 | 386 | |||
395 | if (err) { | 387 | if (err) { | |
@@ -614,28 +606,26 @@ static void | @@ -614,28 +606,26 @@ static void | |||
614 | aue_uno_mcast(struct ifnet *ifp) | 606 | aue_uno_mcast(struct ifnet *ifp) | |
615 | { | 607 | { | |
616 | struct usbnet * const un = ifp->if_softc; | 608 | struct usbnet * const un = ifp->if_softc; | |
617 | struct aue_softc * const sc = usbnet_softc(un); | 609 | struct aue_softc * const sc = usbnet_softc(un); | |
618 | struct ethercom * ec = usbnet_ec(un); | 610 | struct ethercom * ec = usbnet_ec(un); | |
619 | struct ether_multi *enm; | 611 | struct ether_multi *enm; | |
620 | struct ether_multistep step; | 612 | struct ether_multistep step; | |
621 | uint32_t h = 0, i; | 613 | uint32_t h = 0, i; | |
622 | uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | 614 | uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | |
623 | 615 | |||
624 | AUEHIST_FUNC(); | 616 | AUEHIST_FUNC(); | |
625 | AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); | 617 | AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); | |
626 | 618 | |||
627 | usbnet_isowned_core(un); | |||
628 | ||||
629 | if (ifp->if_flags & IFF_PROMISC) { | 619 | if (ifp->if_flags & IFF_PROMISC) { | |
630 | ETHER_LOCK(ec); | 620 | ETHER_LOCK(ec); | |
631 | allmulti: | 621 | allmulti: | |
632 | ec->ec_flags |= ETHER_F_ALLMULTI; | 622 | ec->ec_flags |= ETHER_F_ALLMULTI; | |
633 | ETHER_UNLOCK(ec); | 623 | ETHER_UNLOCK(ec); | |
634 | AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); | 624 | AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); | |
635 | return; | 625 | return; | |
636 | } | 626 | } | |
637 | 627 | |||
638 | /* now program new ones */ | 628 | /* now program new ones */ | |
639 | ETHER_LOCK(ec); | 629 | ETHER_LOCK(ec); | |
640 | ETHER_FIRST_MULTI(step, ec, enm); | 630 | ETHER_FIRST_MULTI(step, ec, enm); | |
641 | while (enm != NULL) { | 631 | while (enm != NULL) { |
--- src/sys/dev/usb/if_axe.c 2022/03/03 05:53:04 1.141
+++ src/sys/dev/usb/if_axe.c 2022/03/03 05:53:23 1.142
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_axe.c,v 1.141 2022/03/03 05:53:04 riastradh Exp $ */ | 1 | /* $NetBSD: if_axe.c,v 1.142 2022/03/03 05:53:23 riastradh Exp $ */ | |
2 | /* $OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */ | 2 | /* $OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg@openbsd.org> | 5 | * Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg@openbsd.org> | |
6 | * | 6 | * | |
7 | * Permission to use, copy, modify, and distribute this software for any | 7 | * Permission to use, copy, modify, and distribute this software for any | |
8 | * purpose with or without fee is hereby granted, provided that the above | 8 | * purpose with or without fee is hereby granted, provided that the above | |
9 | * copyright notice and this permission notice appear in all copies. | 9 | * copyright notice and this permission notice appear in all copies. | |
10 | * | 10 | * | |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
@@ -77,27 +77,27 @@ | @@ -77,27 +77,27 @@ | |||
77 | * (Adam Weinberger wanted me to name this driver if_gir.c.) | 77 | * (Adam Weinberger wanted me to name this driver if_gir.c.) | |
78 | */ | 78 | */ | |
79 | 79 | |||
80 | /* | 80 | /* | |
81 | * Ax88178 and Ax88772 support backported from the OpenBSD driver. | 81 | * Ax88178 and Ax88772 support backported from the OpenBSD driver. | |
82 | * 2007/02/12, J.R. Oldroyd, fbsd@opal.com | 82 | * 2007/02/12, J.R. Oldroyd, fbsd@opal.com | |
83 | * | 83 | * | |
84 | * Manual here: | 84 | * Manual here: | |
85 | * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf | 85 | * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf | |
86 | * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf | 86 | * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf | |
87 | */ | 87 | */ | |
88 | 88 | |||
89 | #include <sys/cdefs.h> | 89 | #include <sys/cdefs.h> | |
90 | __KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.141 2022/03/03 05:53:04 riastradh Exp $"); | 90 | __KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.142 2022/03/03 05:53:23 riastradh Exp $"); | |
91 | 91 | |||
92 | #ifdef _KERNEL_OPT | 92 | #ifdef _KERNEL_OPT | |
93 | #include "opt_usb.h" | 93 | #include "opt_usb.h" | |
94 | #include "opt_net_mpsafe.h" | 94 | #include "opt_net_mpsafe.h" | |
95 | #endif | 95 | #endif | |
96 | 96 | |||
97 | #include <sys/param.h> | 97 | #include <sys/param.h> | |
98 | 98 | |||
99 | #include <dev/usb/usbnet.h> | 99 | #include <dev/usb/usbnet.h> | |
100 | #include <dev/usb/usbhist.h> | 100 | #include <dev/usb/usbhist.h> | |
101 | #include <dev/usb/if_axereg.h> | 101 | #include <dev/usb/if_axereg.h> | |
102 | 102 | |||
103 | struct axe_type { | 103 | struct axe_type { | |
@@ -283,28 +283,26 @@ static const struct usbnet_ops axe_ops = | @@ -283,28 +283,26 @@ static const struct usbnet_ops axe_ops = | |||
283 | .uno_tx_prepare = axe_uno_tx_prepare, | 283 | .uno_tx_prepare = axe_uno_tx_prepare, | |
284 | .uno_rx_loop = axe_uno_rx_loop, | 284 | .uno_rx_loop = axe_uno_rx_loop, | |
285 | .uno_init = axe_uno_init, | 285 | .uno_init = axe_uno_init, | |
286 | }; | 286 | }; | |
287 | 287 | |||
288 | static usbd_status | 288 | static usbd_status | |
289 | axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf) | 289 | axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf) | |
290 | { | 290 | { | |
291 | AXEHIST_FUNC(); AXEHIST_CALLED(); | 291 | AXEHIST_FUNC(); AXEHIST_CALLED(); | |
292 | struct usbnet * const un = &sc->axe_un; | 292 | struct usbnet * const un = &sc->axe_un; | |
293 | usb_device_request_t req; | 293 | usb_device_request_t req; | |
294 | usbd_status err; | 294 | usbd_status err; | |
295 | 295 | |||
296 | usbnet_isowned_core(un); | |||
297 | ||||
298 | if (usbnet_isdying(un)) | 296 | if (usbnet_isdying(un)) | |
299 | return -1; | 297 | return -1; | |
300 | 298 | |||
301 | DPRINTFN(20, "cmd %#jx index %#jx val %#jx", cmd, index, val, 0); | 299 | DPRINTFN(20, "cmd %#jx index %#jx val %#jx", cmd, index, val, 0); | |
302 | 300 | |||
303 | if (AXE_CMD_DIR(cmd)) | 301 | if (AXE_CMD_DIR(cmd)) | |
304 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | 302 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | |
305 | else | 303 | else | |
306 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | 304 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | |
307 | req.bRequest = AXE_CMD_CMD(cmd); | 305 | req.bRequest = AXE_CMD_CMD(cmd); | |
308 | USETW(req.wValue, val); | 306 | USETW(req.wValue, val); | |
309 | USETW(req.wIndex, index); | 307 | USETW(req.wIndex, index); | |
310 | USETW(req.wLength, AXE_CMD_LEN(cmd)); | 308 | USETW(req.wLength, AXE_CMD_LEN(cmd)); |
--- src/sys/dev/usb/if_axen.c 2022/03/03 05:53:04 1.83
+++ src/sys/dev/usb/if_axen.c 2022/03/03 05:53:23 1.84
@@ -1,39 +1,39 @@ | @@ -1,39 +1,39 @@ | |||
1 | /* $NetBSD: if_axen.c,v 1.83 2022/03/03 05:53:04 riastradh Exp $ */ | 1 | /* $NetBSD: if_axen.c,v 1.84 2022/03/03 05:53:23 riastradh Exp $ */ | |
2 | /* $OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $ */ | 2 | /* $OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 2013 Yojiro UO <yuo@openbsd.org> | 5 | * Copyright (c) 2013 Yojiro UO <yuo@openbsd.org> | |
6 | * | 6 | * | |
7 | * Permission to use, copy, modify, and distribute this software for any | 7 | * Permission to use, copy, modify, and distribute this software for any | |
8 | * purpose with or without fee is hereby granted, provided that the above | 8 | * purpose with or without fee is hereby granted, provided that the above | |
9 | * copyright notice and this permission notice appear in all copies. | 9 | * copyright notice and this permission notice appear in all copies. | |
10 | * | 10 | * | |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
18 | */ | 18 | */ | |
19 | 19 | |||
20 | /* | 20 | /* | |
21 | * ASIX Electronics AX88178a USB 2.0 ethernet and AX88179 USB 3.0 Ethernet | 21 | * ASIX Electronics AX88178a USB 2.0 ethernet and AX88179 USB 3.0 Ethernet | |
22 | * driver. | 22 | * driver. | |
23 | */ | 23 | */ | |
24 | 24 | |||
25 | #include <sys/cdefs.h> | 25 | #include <sys/cdefs.h> | |
26 | __KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.83 2022/03/03 05:53:04 riastradh Exp $"); | 26 | __KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.84 2022/03/03 05:53:23 riastradh Exp $"); | |
27 | 27 | |||
28 | #ifdef _KERNEL_OPT | 28 | #ifdef _KERNEL_OPT | |
29 | #include "opt_usb.h" | 29 | #include "opt_usb.h" | |
30 | #endif | 30 | #endif | |
31 | 31 | |||
32 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
33 | 33 | |||
34 | #include <netinet/in.h> /* XXX for netinet/ip.h */ | 34 | #include <netinet/in.h> /* XXX for netinet/ip.h */ | |
35 | #include <netinet/ip.h> /* XXX for IP_MAXPACKET */ | 35 | #include <netinet/ip.h> /* XXX for IP_MAXPACKET */ | |
36 | 36 | |||
37 | #include <dev/usb/usbnet.h> | 37 | #include <dev/usb/usbnet.h> | |
38 | 38 | |||
39 | #include <dev/usb/if_axenreg.h> | 39 | #include <dev/usb/if_axenreg.h> | |
@@ -98,28 +98,26 @@ static const struct usbnet_ops axen_ops | @@ -98,28 +98,26 @@ static const struct usbnet_ops axen_ops | |||
98 | .uno_write_reg = axen_uno_mii_write_reg, | 98 | .uno_write_reg = axen_uno_mii_write_reg, | |
99 | .uno_statchg = axen_uno_mii_statchg, | 99 | .uno_statchg = axen_uno_mii_statchg, | |
100 | .uno_tx_prepare = axen_uno_tx_prepare, | 100 | .uno_tx_prepare = axen_uno_tx_prepare, | |
101 | .uno_rx_loop = axen_uno_rx_loop, | 101 | .uno_rx_loop = axen_uno_rx_loop, | |
102 | .uno_init = axen_uno_init, | 102 | .uno_init = axen_uno_init, | |
103 | }; | 103 | }; | |
104 | 104 | |||
105 | static int | 105 | static int | |
106 | axen_cmd(struct usbnet *un, int cmd, int index, int val, void *buf) | 106 | axen_cmd(struct usbnet *un, int cmd, int index, int val, void *buf) | |
107 | { | 107 | { | |
108 | usb_device_request_t req; | 108 | usb_device_request_t req; | |
109 | usbd_status err; | 109 | usbd_status err; | |
110 | 110 | |||
111 | usbnet_isowned_core(un); | |||
112 | ||||
113 | if (usbnet_isdying(un)) | 111 | if (usbnet_isdying(un)) | |
114 | return 0; | 112 | return 0; | |
115 | 113 | |||
116 | if (AXEN_CMD_DIR(cmd)) | 114 | if (AXEN_CMD_DIR(cmd)) | |
117 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | 115 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | |
118 | else | 116 | else | |
119 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | 117 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | |
120 | req.bRequest = AXEN_CMD_CMD(cmd); | 118 | req.bRequest = AXEN_CMD_CMD(cmd); | |
121 | USETW(req.wValue, val); | 119 | USETW(req.wValue, val); | |
122 | USETW(req.wIndex, index); | 120 | USETW(req.wIndex, index); | |
123 | USETW(req.wLength, AXEN_CMD_LEN(cmd)); | 121 | USETW(req.wLength, AXEN_CMD_LEN(cmd)); | |
124 | 122 | |||
125 | err = usbd_do_request(un->un_udev, &req, buf); | 123 | err = usbd_do_request(un->un_udev, &req, buf); | |
@@ -229,28 +227,26 @@ axen_uno_mcast(struct ifnet *ifp) | @@ -229,28 +227,26 @@ axen_uno_mcast(struct ifnet *ifp) | |||
229 | { | 227 | { | |
230 | struct usbnet * const un = ifp->if_softc; | 228 | struct usbnet * const un = ifp->if_softc; | |
231 | struct ethercom *ec = usbnet_ec(un); | 229 | struct ethercom *ec = usbnet_ec(un); | |
232 | struct ether_multi *enm; | 230 | struct ether_multi *enm; | |
233 | struct ether_multistep step; | 231 | struct ether_multistep step; | |
234 | uint32_t h = 0; | 232 | uint32_t h = 0; | |
235 | uint16_t rxmode; | 233 | uint16_t rxmode; | |
236 | uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | 234 | uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | |
237 | uint16_t wval; | 235 | uint16_t wval; | |
238 | 236 | |||
239 | if (usbnet_isdying(un)) | 237 | if (usbnet_isdying(un)) | |
240 | return; | 238 | return; | |
241 | 239 | |||
242 | usbnet_isowned_core(un); | |||
243 | ||||
244 | rxmode = 0; | 240 | rxmode = 0; | |
245 | 241 | |||
246 | /* Enable receiver, set RX mode */ | 242 | /* Enable receiver, set RX mode */ | |
247 | axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); | 243 | axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); | |
248 | rxmode = le16toh(wval); | 244 | rxmode = le16toh(wval); | |
249 | rxmode &= ~(AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_PROMISC | | 245 | rxmode &= ~(AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_PROMISC | | |
250 | AXEN_RXCTL_ACPT_MCAST); | 246 | AXEN_RXCTL_ACPT_MCAST); | |
251 | 247 | |||
252 | if (ifp->if_flags & IFF_PROMISC) { | 248 | if (ifp->if_flags & IFF_PROMISC) { | |
253 | DPRINTF(("%s: promisc\n", device_xname(un->un_dev))); | 249 | DPRINTF(("%s: promisc\n", device_xname(un->un_dev))); | |
254 | rxmode |= AXEN_RXCTL_PROMISC; | 250 | rxmode |= AXEN_RXCTL_PROMISC; | |
255 | allmulti: | 251 | allmulti: | |
256 | ETHER_LOCK(ec); | 252 | ETHER_LOCK(ec); |
--- src/sys/dev/usb/if_smsc.c 2022/03/03 05:53:14 1.82
+++ src/sys/dev/usb/if_smsc.c 2022/03/03 05:53:23 1.83
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_smsc.c,v 1.82 2022/03/03 05:53:14 riastradh Exp $ */ | 1 | /* $NetBSD: if_smsc.c,v 1.83 2022/03/03 05:53:23 riastradh Exp $ */ | |
2 | 2 | |||
3 | /* $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */ | 3 | /* $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */ | |
4 | /* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */ | 4 | /* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */ | |
5 | /*- | 5 | /*- | |
6 | * Copyright (c) 2012 | 6 | * Copyright (c) 2012 | |
7 | * Ben Gray <bgray@freebsd.org>. | 7 | * Ben Gray <bgray@freebsd.org>. | |
8 | * All rights reserved. | 8 | * All rights reserved. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -51,27 +51,27 @@ | @@ -51,27 +51,27 @@ | |||
51 | * the H/W checksum will be incorrect, however the rx code compensates for this. | 51 | * the H/W checksum will be incorrect, however the rx code compensates for this. | |
52 | * | 52 | * | |
53 | * TX checksuming is more complicated, the device requires a special header to | 53 | * TX checksuming is more complicated, the device requires a special header to | |
54 | * be prefixed onto the start of the frame which indicates the start and end | 54 | * be prefixed onto the start of the frame which indicates the start and end | |
55 | * positions of the UDP or TCP frame. This requires the driver to manually | 55 | * positions of the UDP or TCP frame. This requires the driver to manually | |
56 | * go through the packet data and decode the headers prior to sending. | 56 | * go through the packet data and decode the headers prior to sending. | |
57 | * On Linux they generally provide cues to the location of the csum and the | 57 | * On Linux they generally provide cues to the location of the csum and the | |
58 | * area to calculate it over, on FreeBSD we seem to have to do it all ourselves, | 58 | * area to calculate it over, on FreeBSD we seem to have to do it all ourselves, | |
59 | * hence this is not as optimal and therefore h/w TX checksum is currently not | 59 | * hence this is not as optimal and therefore h/w TX checksum is currently not | |
60 | * implemented. | 60 | * implemented. | |
61 | */ | 61 | */ | |
62 | 62 | |||
63 | #include <sys/cdefs.h> | 63 | #include <sys/cdefs.h> | |
64 | __KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.82 2022/03/03 05:53:14 riastradh Exp $"); | 64 | __KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.83 2022/03/03 05:53:23 riastradh Exp $"); | |
65 | 65 | |||
66 | #ifdef _KERNEL_OPT | 66 | #ifdef _KERNEL_OPT | |
67 | #include "opt_usb.h" | 67 | #include "opt_usb.h" | |
68 | #endif | 68 | #endif | |
69 | 69 | |||
70 | #include <sys/param.h> | 70 | #include <sys/param.h> | |
71 | 71 | |||
72 | #include <dev/usb/usbnet.h> | 72 | #include <dev/usb/usbnet.h> | |
73 | #include <dev/usb/usbhist.h> | 73 | #include <dev/usb/usbhist.h> | |
74 | 74 | |||
75 | #include <dev/usb/if_smscreg.h> | 75 | #include <dev/usb/if_smscreg.h> | |
76 | 76 | |||
77 | #include "ioconf.h" | 77 | #include "ioconf.h" | |
@@ -201,55 +201,51 @@ static const struct usbnet_ops smsc_ops | @@ -201,55 +201,51 @@ static const struct usbnet_ops smsc_ops | |||
201 | .uno_statchg = smsc_uno_miibus_statchg, | 201 | .uno_statchg = smsc_uno_miibus_statchg, | |
202 | .uno_tx_prepare = smsc_uno_tx_prepare, | 202 | .uno_tx_prepare = smsc_uno_tx_prepare, | |
203 | .uno_rx_loop = smsc_uno_rx_loop, | 203 | .uno_rx_loop = smsc_uno_rx_loop, | |
204 | .uno_init = smsc_uno_init, | 204 | .uno_init = smsc_uno_init, | |
205 | }; | 205 | }; | |
206 | 206 | |||
207 | static int | 207 | static int | |
208 | smsc_readreg(struct usbnet *un, uint32_t off, uint32_t *data) | 208 | smsc_readreg(struct usbnet *un, uint32_t off, uint32_t *data) | |
209 | { | 209 | { | |
210 | usb_device_request_t req; | 210 | usb_device_request_t req; | |
211 | uint32_t buf; | 211 | uint32_t buf; | |
212 | usbd_status err; | 212 | usbd_status err; | |
213 | 213 | |||
214 | usbnet_isowned_core(un); | |||
215 | ||||
216 | if (usbnet_isdying(un)) | 214 | if (usbnet_isdying(un)) | |
217 | return 0; | 215 | return 0; | |
218 | 216 | |||
219 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | 217 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | |
220 | req.bRequest = SMSC_UR_READ_REG; | 218 | req.bRequest = SMSC_UR_READ_REG; | |
221 | USETW(req.wValue, 0); | 219 | USETW(req.wValue, 0); | |
222 | USETW(req.wIndex, off); | 220 | USETW(req.wIndex, off); | |
223 | USETW(req.wLength, 4); | 221 | USETW(req.wLength, 4); | |
224 | 222 | |||
225 | err = usbd_do_request(un->un_udev, &req, &buf); | 223 | err = usbd_do_request(un->un_udev, &req, &buf); | |
226 | if (err != 0) | 224 | if (err != 0) | |
227 | smsc_warn_printf(un, "Failed to read register 0x%0x\n", off); | 225 | smsc_warn_printf(un, "Failed to read register 0x%0x\n", off); | |
228 | 226 | |||
229 | *data = le32toh(buf); | 227 | *data = le32toh(buf); | |
230 | 228 | |||
231 | return err; | 229 | return err; | |
232 | } | 230 | } | |
233 | 231 | |||
234 | static int | 232 | static int | |
235 | smsc_writereg(struct usbnet *un, uint32_t off, uint32_t data) | 233 | smsc_writereg(struct usbnet *un, uint32_t off, uint32_t data) | |
236 | { | 234 | { | |
237 | usb_device_request_t req; | 235 | usb_device_request_t req; | |
238 | uint32_t buf; | 236 | uint32_t buf; | |
239 | usbd_status err; | 237 | usbd_status err; | |
240 | 238 | |||
241 | usbnet_isowned_core(un); | |||
242 | ||||
243 | if (usbnet_isdying(un)) | 239 | if (usbnet_isdying(un)) | |
244 | return 0; | 240 | return 0; | |
245 | 241 | |||
246 | buf = htole32(data); | 242 | buf = htole32(data); | |
247 | 243 | |||
248 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | 244 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | |
249 | req.bRequest = SMSC_UR_WRITE_REG; | 245 | req.bRequest = SMSC_UR_WRITE_REG; | |
250 | USETW(req.wValue, 0); | 246 | USETW(req.wValue, 0); | |
251 | USETW(req.wIndex, off); | 247 | USETW(req.wIndex, off); | |
252 | USETW(req.wLength, 4); | 248 | USETW(req.wLength, 4); | |
253 | 249 | |||
254 | err = usbd_do_request(un->un_udev, &req, &buf); | 250 | err = usbd_do_request(un->un_udev, &req, &buf); | |
255 | if (err != 0) | 251 | if (err != 0) | |
@@ -412,28 +408,26 @@ smsc_hash(uint8_t addr[ETHER_ADDR_LEN]) | @@ -412,28 +408,26 @@ smsc_hash(uint8_t addr[ETHER_ADDR_LEN]) | |||
412 | 408 | |||
413 | static void | 409 | static void | |
414 | smsc_uno_mcast(struct ifnet *ifp) | 410 | smsc_uno_mcast(struct ifnet *ifp) | |
415 | { | 411 | { | |
416 | USMSCHIST_FUNC(); USMSCHIST_CALLED(); | 412 | USMSCHIST_FUNC(); USMSCHIST_CALLED(); | |
417 | struct usbnet * const un = ifp->if_softc; | 413 | struct usbnet * const un = ifp->if_softc; | |
418 | struct smsc_softc * const sc = usbnet_softc(un); | 414 | struct smsc_softc * const sc = usbnet_softc(un); | |
419 | struct ethercom *ec = usbnet_ec(un); | 415 | struct ethercom *ec = usbnet_ec(un); | |
420 | struct ether_multi *enm; | 416 | struct ether_multi *enm; | |
421 | struct ether_multistep step; | 417 | struct ether_multistep step; | |
422 | uint32_t hashtbl[2] = { 0, 0 }; | 418 | uint32_t hashtbl[2] = { 0, 0 }; | |
423 | uint32_t hash; | 419 | uint32_t hash; | |
424 | 420 | |||
425 | usbnet_isowned_core(un); | |||
426 | ||||
427 | if (usbnet_isdying(un)) | 421 | if (usbnet_isdying(un)) | |
428 | return; | 422 | return; | |
429 | 423 | |||
430 | if (ifp->if_flags & IFF_PROMISC) { | 424 | if (ifp->if_flags & IFF_PROMISC) { | |
431 | ETHER_LOCK(ec); | 425 | ETHER_LOCK(ec); | |
432 | allmulti: | 426 | allmulti: | |
433 | ec->ec_flags |= ETHER_F_ALLMULTI; | 427 | ec->ec_flags |= ETHER_F_ALLMULTI; | |
434 | ETHER_UNLOCK(ec); | 428 | ETHER_UNLOCK(ec); | |
435 | DPRINTF("receive all multicast enabled", 0, 0, 0, 0); | 429 | DPRINTF("receive all multicast enabled", 0, 0, 0, 0); | |
436 | sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS; | 430 | sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS; | |
437 | sc->sc_mac_csr &= ~SMSC_MAC_CSR_HPFILT; | 431 | sc->sc_mac_csr &= ~SMSC_MAC_CSR_HPFILT; | |
438 | smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); | 432 | smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr); | |
439 | return; | 433 | return; |
--- src/sys/dev/usb/if_udav.c 2022/03/03 05:53:14 1.87
+++ src/sys/dev/usb/if_udav.c 2022/03/03 05:53:23 1.88
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_udav.c,v 1.87 2022/03/03 05:53:14 riastradh Exp $ */ | 1 | /* $NetBSD: if_udav.c,v 1.88 2022/03/03 05:53:23 riastradh Exp $ */ | |
2 | /* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */ | 2 | /* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 2003 | 5 | * Copyright (c) 2003 | |
6 | * Shingo WATANABE <nabe@nabechan.org>. All rights reserved. | 6 | * Shingo WATANABE <nabe@nabechan.org>. All rights reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
@@ -35,27 +35,27 @@ | @@ -35,27 +35,27 @@ | |||
35 | * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY) | 35 | * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY) | |
36 | * The spec can be found at the following url. | 36 | * The spec can be found at the following url. | |
37 | * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-F01-062202s.pdf | 37 | * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-F01-062202s.pdf | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | /* | 40 | /* | |
41 | * TODO: | 41 | * TODO: | |
42 | * Interrupt Endpoint support | 42 | * Interrupt Endpoint support | |
43 | * External PHYs | 43 | * External PHYs | |
44 | * powerhook() support? | 44 | * powerhook() support? | |
45 | */ | 45 | */ | |
46 | 46 | |||
47 | #include <sys/cdefs.h> | 47 | #include <sys/cdefs.h> | |
48 | __KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.87 2022/03/03 05:53:14 riastradh Exp $"); | 48 | __KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.88 2022/03/03 05:53:23 riastradh Exp $"); | |
49 | 49 | |||
50 | #ifdef _KERNEL_OPT | 50 | #ifdef _KERNEL_OPT | |
51 | #include "opt_usb.h" | 51 | #include "opt_usb.h" | |
52 | #endif | 52 | #endif | |
53 | 53 | |||
54 | #include <sys/param.h> | 54 | #include <sys/param.h> | |
55 | 55 | |||
56 | #include <dev/usb/usbnet.h> | 56 | #include <dev/usb/usbnet.h> | |
57 | #include <dev/usb/if_udavreg.h> | 57 | #include <dev/usb/if_udavreg.h> | |
58 | 58 | |||
59 | /* Function declarations */ | 59 | /* Function declarations */ | |
60 | static int udav_match(device_t, cfdata_t, void *); | 60 | static int udav_match(device_t, cfdata_t, void *); | |
61 | static void udav_attach(device_t, device_t, void *); | 61 | static void udav_attach(device_t, device_t, void *); | |
@@ -354,27 +354,26 @@ udav_mem_write1(struct usbnet *un, int o | @@ -354,27 +354,26 @@ udav_mem_write1(struct usbnet *un, int o | |||
354 | } | 354 | } | |
355 | 355 | |||
356 | return err; | 356 | return err; | |
357 | } | 357 | } | |
358 | #endif | 358 | #endif | |
359 | 359 | |||
360 | /* read register(s) */ | 360 | /* read register(s) */ | |
361 | static int | 361 | static int | |
362 | udav_csr_read(struct usbnet *un, int offset, void *buf, int len) | 362 | udav_csr_read(struct usbnet *un, int offset, void *buf, int len) | |
363 | { | 363 | { | |
364 | usb_device_request_t req; | 364 | usb_device_request_t req; | |
365 | usbd_status err; | 365 | usbd_status err; | |
366 | 366 | |||
367 | usbnet_isowned_core(un); | |||
368 | KASSERT(!usbnet_isdying(un)); | 367 | KASSERT(!usbnet_isdying(un)); | |
369 | 368 | |||
370 | DPRINTFN(0x200, | 369 | DPRINTFN(0x200, | |
371 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | 370 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | |
372 | 371 | |||
373 | offset &= 0xff; | 372 | offset &= 0xff; | |
374 | len &= 0xff; | 373 | len &= 0xff; | |
375 | 374 | |||
376 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | 375 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | |
377 | req.bRequest = UDAV_REQ_REG_READ; | 376 | req.bRequest = UDAV_REQ_REG_READ; | |
378 | USETW(req.wValue, 0x0000); | 377 | USETW(req.wValue, 0x0000); | |
379 | USETW(req.wIndex, offset); | 378 | USETW(req.wIndex, offset); | |
380 | USETW(req.wLength, len); | 379 | USETW(req.wLength, len); | |
@@ -385,27 +384,26 @@ udav_csr_read(struct usbnet *un, int off | @@ -385,27 +384,26 @@ udav_csr_read(struct usbnet *un, int off | |||
385 | device_xname(un->un_dev), __func__, offset, err)); | 384 | device_xname(un->un_dev), __func__, offset, err)); | |
386 | } | 385 | } | |
387 | 386 | |||
388 | return err; | 387 | return err; | |
389 | } | 388 | } | |
390 | 389 | |||
391 | /* write register(s) */ | 390 | /* write register(s) */ | |
392 | static int | 391 | static int | |
393 | udav_csr_write(struct usbnet *un, int offset, void *buf, int len) | 392 | udav_csr_write(struct usbnet *un, int offset, void *buf, int len) | |
394 | { | 393 | { | |
395 | usb_device_request_t req; | 394 | usb_device_request_t req; | |
396 | usbd_status err; | 395 | usbd_status err; | |
397 | 396 | |||
398 | usbnet_isowned_core(un); | |||
399 | KASSERT(!usbnet_isdying(un)); | 397 | KASSERT(!usbnet_isdying(un)); | |
400 | 398 | |||
401 | DPRINTFN(0x200, | 399 | DPRINTFN(0x200, | |
402 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | 400 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | |
403 | 401 | |||
404 | offset &= 0xff; | 402 | offset &= 0xff; | |
405 | len &= 0xff; | 403 | len &= 0xff; | |
406 | 404 | |||
407 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | 405 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | |
408 | req.bRequest = UDAV_REQ_REG_WRITE; | 406 | req.bRequest = UDAV_REQ_REG_WRITE; | |
409 | USETW(req.wValue, 0x0000); | 407 | USETW(req.wValue, 0x0000); | |
410 | USETW(req.wIndex, offset); | 408 | USETW(req.wIndex, offset); | |
411 | USETW(req.wLength, len); | 409 | USETW(req.wLength, len); | |
@@ -414,45 +412,42 @@ udav_csr_write(struct usbnet *un, int of | @@ -414,45 +412,42 @@ udav_csr_write(struct usbnet *un, int of | |||
414 | if (err) { | 412 | if (err) { | |
415 | DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", | 413 | DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", | |
416 | device_xname(un->un_dev), __func__, offset, err)); | 414 | device_xname(un->un_dev), __func__, offset, err)); | |
417 | } | 415 | } | |
418 | 416 | |||
419 | return err; | 417 | return err; | |
420 | } | 418 | } | |
421 | 419 | |||
422 | static int | 420 | static int | |
423 | udav_csr_read1(struct usbnet *un, int offset) | 421 | udav_csr_read1(struct usbnet *un, int offset) | |
424 | { | 422 | { | |
425 | uint8_t val = 0; | 423 | uint8_t val = 0; | |
426 | 424 | |||
427 | usbnet_isowned_core(un); | |||
428 | ||||
429 | DPRINTFN(0x200, | 425 | DPRINTFN(0x200, | |
430 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | 426 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | |
431 | 427 | |||
432 | if (usbnet_isdying(un)) | 428 | if (usbnet_isdying(un)) | |
433 | return 0; | 429 | return 0; | |
434 | 430 | |||
435 | return udav_csr_read(un, offset, &val, 1) ? 0 : val; | 431 | return udav_csr_read(un, offset, &val, 1) ? 0 : val; | |
436 | } | 432 | } | |
437 | 433 | |||
438 | /* write a register */ | 434 | /* write a register */ | |
439 | static int | 435 | static int | |
440 | udav_csr_write1(struct usbnet *un, int offset, unsigned char ch) | 436 | udav_csr_write1(struct usbnet *un, int offset, unsigned char ch) | |
441 | { | 437 | { | |
442 | usb_device_request_t req; | 438 | usb_device_request_t req; | |
443 | usbd_status err; | 439 | usbd_status err; | |
444 | 440 | |||
445 | usbnet_isowned_core(un); | |||
446 | KASSERT(!usbnet_isdying(un)); | 441 | KASSERT(!usbnet_isdying(un)); | |
447 | 442 | |||
448 | DPRINTFN(0x200, | 443 | DPRINTFN(0x200, | |
449 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | 444 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | |
450 | 445 | |||
451 | offset &= 0xff; | 446 | offset &= 0xff; | |
452 | 447 | |||
453 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | 448 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | |
454 | req.bRequest = UDAV_REQ_REG_WRITE1; | 449 | req.bRequest = UDAV_REQ_REG_WRITE1; | |
455 | USETW(req.wValue, ch); | 450 | USETW(req.wValue, ch); | |
456 | USETW(req.wIndex, offset); | 451 | USETW(req.wIndex, offset); | |
457 | USETW(req.wLength, 0x0000); | 452 | USETW(req.wLength, 0x0000); | |
458 | 453 | |||
@@ -576,28 +571,26 @@ udav_chip_init(struct usbnet *un) | @@ -576,28 +571,26 @@ udav_chip_init(struct usbnet *un) | |||
576 | 571 | |||
577 | static void | 572 | static void | |
578 | udav_uno_mcast(struct ifnet *ifp) | 573 | udav_uno_mcast(struct ifnet *ifp) | |
579 | { | 574 | { | |
580 | struct usbnet * const un = ifp->if_softc; | 575 | struct usbnet * const un = ifp->if_softc; | |
581 | struct ethercom *ec = usbnet_ec(un); | 576 | struct ethercom *ec = usbnet_ec(un); | |
582 | struct ether_multi *enm; | 577 | struct ether_multi *enm; | |
583 | struct ether_multistep step; | 578 | struct ether_multistep step; | |
584 | uint8_t hashes[8]; | 579 | uint8_t hashes[8]; | |
585 | int h = 0; | 580 | int h = 0; | |
586 | 581 | |||
587 | DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | 582 | DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | |
588 | 583 | |||
589 | usbnet_isowned_core(un); | |||
590 | ||||
591 | if (usbnet_isdying(un)) | 584 | if (usbnet_isdying(un)) | |
592 | return; | 585 | return; | |
593 | 586 | |||
594 | if (ISSET(un->un_flags, UDAV_NO_PHY)) { | 587 | if (ISSET(un->un_flags, UDAV_NO_PHY)) { | |
595 | UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL); | 588 | UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL); | |
596 | UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_PRMSC); | 589 | UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_PRMSC); | |
597 | return; | 590 | return; | |
598 | } | 591 | } | |
599 | 592 | |||
600 | if (ifp->if_flags & IFF_PROMISC) { | 593 | if (ifp->if_flags & IFF_PROMISC) { | |
601 | ETHER_LOCK(ec); | 594 | ETHER_LOCK(ec); | |
602 | ec->ec_flags |= ETHER_F_ALLMULTI; | 595 | ec->ec_flags |= ETHER_F_ALLMULTI; | |
603 | ETHER_UNLOCK(ec); | 596 | ETHER_UNLOCK(ec); |
--- src/sys/dev/usb/if_url.c 2022/03/03 05:53:04 1.87
+++ src/sys/dev/usb/if_url.c 2022/03/03 05:53:23 1.88
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_url.c,v 1.87 2022/03/03 05:53:04 riastradh Exp $ */ | 1 | /* $NetBSD: if_url.c,v 1.88 2022/03/03 05:53:23 riastradh Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2001, 2002 | 4 | * Copyright (c) 2001, 2002 | |
5 | * Shingo WATANABE <nabe@nabechan.org>. All rights reserved. | 5 | * Shingo WATANABE <nabe@nabechan.org>. 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. | |
@@ -34,27 +34,27 @@ | @@ -34,27 +34,27 @@ | |||
34 | * The RTL8150L(Realtek USB to fast ethernet controller) spec can be found at | 34 | * The RTL8150L(Realtek USB to fast ethernet controller) spec can be found at | |
35 | * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/8150v14.pdf | 35 | * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/8150v14.pdf | |
36 | * ftp://152.104.125.40/lancard/data_sheet/8150/8150v14.pdf | 36 | * ftp://152.104.125.40/lancard/data_sheet/8150/8150v14.pdf | |
37 | */ | 37 | */ | |
38 | 38 | |||
39 | /* | 39 | /* | |
40 | * TODO: | 40 | * TODO: | |
41 | * Interrupt Endpoint support | 41 | * Interrupt Endpoint support | |
42 | * External PHYs | 42 | * External PHYs | |
43 | * powerhook() support? | 43 | * powerhook() support? | |
44 | */ | 44 | */ | |
45 | 45 | |||
46 | #include <sys/cdefs.h> | 46 | #include <sys/cdefs.h> | |
47 | __KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.87 2022/03/03 05:53:04 riastradh Exp $"); | 47 | __KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.88 2022/03/03 05:53:23 riastradh Exp $"); | |
48 | 48 | |||
49 | #ifdef _KERNEL_OPT | 49 | #ifdef _KERNEL_OPT | |
50 | #include "opt_inet.h" | 50 | #include "opt_inet.h" | |
51 | #include "opt_usb.h" | 51 | #include "opt_usb.h" | |
52 | #endif | 52 | #endif | |
53 | 53 | |||
54 | #include <sys/param.h> | 54 | #include <sys/param.h> | |
55 | 55 | |||
56 | #include <net/if_ether.h> | 56 | #include <net/if_ether.h> | |
57 | #ifdef INET | 57 | #ifdef INET | |
58 | #include <netinet/in.h> | 58 | #include <netinet/in.h> | |
59 | #include <netinet/if_inarp.h> | 59 | #include <netinet/if_inarp.h> | |
60 | #endif | 60 | #endif | |
@@ -258,28 +258,26 @@ url_attach(device_t parent, device_t sel | @@ -258,28 +258,26 @@ url_attach(device_t parent, device_t sel | |||
258 | 258 | |||
259 | /* initialize interface information */ | 259 | /* initialize interface information */ | |
260 | usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, | 260 | usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, | |
261 | 0, &unm); | 261 | 0, &unm); | |
262 | } | 262 | } | |
263 | 263 | |||
264 | /* read/write memory */ | 264 | /* read/write memory */ | |
265 | static int | 265 | static int | |
266 | url_mem(struct usbnet *un, int cmd, int offset, void *buf, int len) | 266 | url_mem(struct usbnet *un, int cmd, int offset, void *buf, int len) | |
267 | { | 267 | { | |
268 | usb_device_request_t req; | 268 | usb_device_request_t req; | |
269 | usbd_status err; | 269 | usbd_status err; | |
270 | 270 | |||
271 | usbnet_isowned_core(un); | |||
272 | ||||
273 | DPRINTFN(0x200, | 271 | DPRINTFN(0x200, | |
274 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | 272 | ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | |
275 | 273 | |||
276 | if (usbnet_isdying(un)) | 274 | if (usbnet_isdying(un)) | |
277 | return 0; | 275 | return 0; | |
278 | 276 | |||
279 | if (cmd == URL_CMD_READMEM) | 277 | if (cmd == URL_CMD_READMEM) | |
280 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | 278 | req.bmRequestType = UT_READ_VENDOR_DEVICE; | |
281 | else | 279 | else | |
282 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | 280 | req.bmRequestType = UT_WRITE_VENDOR_DEVICE; | |
283 | req.bRequest = URL_REQ_MEM; | 281 | req.bRequest = URL_REQ_MEM; | |
284 | USETW(req.wValue, offset); | 282 | USETW(req.wValue, offset); | |
285 | USETW(req.wIndex, 0x0000); | 283 | USETW(req.wIndex, 0x0000); | |
@@ -425,28 +423,26 @@ url_reset(struct usbnet *un) | @@ -425,28 +423,26 @@ url_reset(struct usbnet *un) | |||
425 | 423 | |||
426 | static void | 424 | static void | |
427 | url_uno_mcast(struct ifnet *ifp) | 425 | url_uno_mcast(struct ifnet *ifp) | |
428 | { | 426 | { | |
429 | struct usbnet * const un = ifp->if_softc; | 427 | struct usbnet * const un = ifp->if_softc; | |
430 | struct ethercom *ec = usbnet_ec(un); | 428 | struct ethercom *ec = usbnet_ec(un); | |
431 | struct ether_multi *enm; | 429 | struct ether_multi *enm; | |
432 | struct ether_multistep step; | 430 | struct ether_multistep step; | |
433 | uint32_t mchash[2] = { 0, 0 }; | 431 | uint32_t mchash[2] = { 0, 0 }; | |
434 | int h = 0, rcr; | 432 | int h = 0, rcr; | |
435 | 433 | |||
436 | DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | 434 | DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); | |
437 | 435 | |||
438 | usbnet_isowned_core(un); | |||
439 | ||||
440 | if (usbnet_isdying(un)) | 436 | if (usbnet_isdying(un)) | |
441 | return; | 437 | return; | |
442 | 438 | |||
443 | rcr = url_csr_read_2(un, URL_RCR); | 439 | rcr = url_csr_read_2(un, URL_RCR); | |
444 | rcr &= ~(URL_RCR_AAP | URL_RCR_AAM | URL_RCR_AM); | 440 | rcr &= ~(URL_RCR_AAP | URL_RCR_AAM | URL_RCR_AM); | |
445 | 441 | |||
446 | ETHER_LOCK(ec); | 442 | ETHER_LOCK(ec); | |
447 | if (ifp->if_flags & IFF_PROMISC) { | 443 | if (ifp->if_flags & IFF_PROMISC) { | |
448 | ec->ec_flags |= ETHER_F_ALLMULTI; | 444 | ec->ec_flags |= ETHER_F_ALLMULTI; | |
449 | ETHER_UNLOCK(ec); | 445 | ETHER_UNLOCK(ec); | |
450 | /* run promisc. mode */ | 446 | /* run promisc. mode */ | |
451 | rcr |= URL_RCR_AAM; /* ??? */ | 447 | rcr |= URL_RCR_AAM; /* ??? */ | |
452 | rcr |= URL_RCR_AAP; | 448 | rcr |= URL_RCR_AAP; |
--- src/sys/dev/usb/if_ure.c 2022/03/03 05:53:04 1.48
+++ src/sys/dev/usb/if_ure.c 2022/03/03 05:53:23 1.49
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_ure.c,v 1.48 2022/03/03 05:53:04 riastradh Exp $ */ | 1 | /* $NetBSD: if_ure.c,v 1.49 2022/03/03 05:53:23 riastradh Exp $ */ | |
2 | /* $OpenBSD: if_ure.c,v 1.10 2018/11/02 21:32:30 jcs Exp $ */ | 2 | /* $OpenBSD: if_ure.c,v 1.10 2018/11/02 21:32:30 jcs Exp $ */ | |
3 | 3 | |||
4 | /*- | 4 | /*- | |
5 | * Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org> | 5 | * Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org> | |
6 | * All rights reserved. | 6 | * All rights reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
@@ -20,27 +20,27 @@ | @@ -20,27 +20,27 @@ | |||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
27 | * SUCH DAMAGE. | 27 | * SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | /* RealTek RTL8152/RTL8153 10/100/Gigabit USB Ethernet device */ | 30 | /* RealTek RTL8152/RTL8153 10/100/Gigabit USB Ethernet device */ | |
31 | 31 | |||
32 | #include <sys/cdefs.h> | 32 | #include <sys/cdefs.h> | |
33 | __KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.48 2022/03/03 05:53:04 riastradh Exp $"); | 33 | __KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.49 2022/03/03 05:53:23 riastradh Exp $"); | |
34 | 34 | |||
35 | #ifdef _KERNEL_OPT | 35 | #ifdef _KERNEL_OPT | |
36 | #include "opt_usb.h" | 36 | #include "opt_usb.h" | |
37 | #include "opt_inet.h" | 37 | #include "opt_inet.h" | |
38 | #endif | 38 | #endif | |
39 | 39 | |||
40 | #include <sys/param.h> | 40 | #include <sys/param.h> | |
41 | #include <sys/cprng.h> | 41 | #include <sys/cprng.h> | |
42 | 42 | |||
43 | #include <net/route.h> | 43 | #include <net/route.h> | |
44 | 44 | |||
45 | #include <dev/usb/usbnet.h> | 45 | #include <dev/usb/usbnet.h> | |
46 | 46 | |||
@@ -330,28 +330,26 @@ ure_uno_miibus_statchg(struct ifnet *ifp | @@ -330,28 +330,26 @@ ure_uno_miibus_statchg(struct ifnet *ifp | |||
330 | } | 330 | } | |
331 | } | 331 | } | |
332 | 332 | |||
333 | static void | 333 | static void | |
334 | ure_uno_mcast(struct ifnet *ifp) | 334 | ure_uno_mcast(struct ifnet *ifp) | |
335 | { | 335 | { | |
336 | struct usbnet *un = ifp->if_softc; | 336 | struct usbnet *un = ifp->if_softc; | |
337 | struct ethercom *ec = usbnet_ec(un); | 337 | struct ethercom *ec = usbnet_ec(un); | |
338 | struct ether_multi *enm; | 338 | struct ether_multi *enm; | |
339 | struct ether_multistep step; | 339 | struct ether_multistep step; | |
340 | uint32_t mchash[2] = { 0, 0 }; | 340 | uint32_t mchash[2] = { 0, 0 }; | |
341 | uint32_t h = 0, rxmode; | 341 | uint32_t h = 0, rxmode; | |
342 | 342 | |||
343 | usbnet_isowned_core(un); | |||
344 | ||||
345 | if (usbnet_isdying(un)) | 343 | if (usbnet_isdying(un)) | |
346 | return; | 344 | return; | |
347 | 345 | |||
348 | rxmode = ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA); | 346 | rxmode = ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA); | |
349 | rxmode &= ~(URE_RCR_AAP | URE_RCR_AM); | 347 | rxmode &= ~(URE_RCR_AAP | URE_RCR_AM); | |
350 | /* continue to accept my own DA and bcast frames */ | 348 | /* continue to accept my own DA and bcast frames */ | |
351 | 349 | |||
352 | ETHER_LOCK(ec); | 350 | ETHER_LOCK(ec); | |
353 | if (ifp->if_flags & IFF_PROMISC) { | 351 | if (ifp->if_flags & IFF_PROMISC) { | |
354 | ec->ec_flags |= ETHER_F_ALLMULTI; | 352 | ec->ec_flags |= ETHER_F_ALLMULTI; | |
355 | ETHER_UNLOCK(ec); | 353 | ETHER_UNLOCK(ec); | |
356 | /* run promisc. mode */ | 354 | /* run promisc. mode */ | |
357 | rxmode |= URE_RCR_AM; /* ??? */ | 355 | rxmode |= URE_RCR_AM; /* ??? */ |
--- src/sys/dev/usb/usbnet.c 2022/03/03 05:52:46 1.81
+++ src/sys/dev/usb/usbnet.c 2022/03/03 05:53:23 1.82
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: usbnet.c,v 1.81 2022/03/03 05:52:46 riastradh Exp $ */ | 1 | /* $NetBSD: usbnet.c,v 1.82 2022/03/03 05:53:23 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. | |
@@ -21,27 +21,27 @@ | @@ -21,27 +21,27 @@ | |||
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.81 2022/03/03 05:52:46 riastradh Exp $"); | 34 | __KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.82 2022/03/03 05:53:23 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 | |||
45 | struct usbnet_cdata { | 45 | struct 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; | |
@@ -49,38 +49,41 @@ struct usbnet_cdata { | @@ -49,38 +49,41 @@ struct usbnet_cdata { | |||
49 | int uncd_tx_prod; | 49 | int uncd_tx_prod; | |
50 | int uncd_tx_cnt; | 50 | int uncd_tx_cnt; | |
51 | }; | 51 | }; | |
52 | 52 | |||
53 | struct usbnet_private { | 53 | struct 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 | * | 59 | * | |
60 | * the lock ordering is: | 60 | * the lock ordering is: | |
61 | * ifnet lock -> unp_core_lock -> unp_rxlock -> unp_txlock | 61 | * ifnet lock -> unp_core_lock -> unp_rxlock -> unp_txlock | |
62 | * -> unp_mcastlock | |||
62 | * - 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 | |
63 | * involved, it must be taken first | 64 | * involved, it must be taken first | |
64 | */ | 65 | */ | |
65 | kmutex_t unp_core_lock; | 66 | kmutex_t unp_core_lock; | |
66 | kmutex_t unp_rxlock; | 67 | kmutex_t unp_rxlock; | |
67 | kmutex_t unp_txlock; | 68 | kmutex_t unp_txlock; | |
68 | 69 | |||
70 | kmutex_t unp_mcastlock; | |||
71 | bool unp_mcastactive; | |||
72 | ||||
69 | struct usbnet_cdata unp_cdata; | 73 | struct usbnet_cdata unp_cdata; | |
70 | 74 | |||
71 | struct ethercom unp_ec; | 75 | struct ethercom unp_ec; | |
72 | struct mii_data unp_mii; | 76 | struct mii_data unp_mii; | |
73 | struct usb_task unp_mcasttask; | |||
74 | struct usb_task unp_ticktask; | 77 | struct usb_task unp_ticktask; | |
75 | struct callout unp_stat_ch; | 78 | struct callout unp_stat_ch; | |
76 | struct usbd_pipe *unp_ep[USBNET_ENDPT_MAX]; | 79 | struct usbd_pipe *unp_ep[USBNET_ENDPT_MAX]; | |
77 | 80 | |||
78 | volatile bool unp_dying; | 81 | volatile bool unp_dying; | |
79 | bool unp_stopping; | 82 | bool unp_stopping; | |
80 | bool unp_attached; | 83 | bool unp_attached; | |
81 | bool unp_ifp_attached; | 84 | bool unp_ifp_attached; | |
82 | bool unp_link; | 85 | bool unp_link; | |
83 | 86 | |||
84 | int unp_timer; | 87 | int unp_timer; | |
85 | unsigned short unp_if_flags; | 88 | unsigned short unp_if_flags; | |
86 | unsigned unp_number; | 89 | unsigned unp_number; | |
@@ -856,26 +859,37 @@ usbnet_init_rx_tx(struct usbnet * const | @@ -856,26 +859,37 @@ usbnet_init_rx_tx(struct usbnet * const | |||
856 | /* Init TX ring. */ | 859 | /* Init TX ring. */ | |
857 | if (usbnet_tx_list_init(un)) { | 860 | if (usbnet_tx_list_init(un)) { | |
858 | aprint_error_dev(un->un_dev, "tx list init failed\n"); | 861 | aprint_error_dev(un->un_dev, "tx list init failed\n"); | |
859 | error = ENOBUFS; | 862 | error = ENOBUFS; | |
860 | goto out; | 863 | goto out; | |
861 | } | 864 | } | |
862 | 865 | |||
863 | /* Indicate we are up and running. */ | 866 | /* Indicate we are up and running. */ | |
864 | /* XXX urndis calls usbnet_init_rx_tx before usbnet_attach_ifp. */ | 867 | /* XXX urndis calls usbnet_init_rx_tx before usbnet_attach_ifp. */ | |
865 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), | 868 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), | |
866 | "%s", ifp->if_xname); | 869 | "%s", ifp->if_xname); | |
867 | ifp->if_flags |= IFF_RUNNING; | 870 | ifp->if_flags |= IFF_RUNNING; | |
868 | 871 | |||
872 | /* | |||
873 | * If the hardware has a multicast filter, program it and then | |||
874 | * allow updates to it while we're running. | |||
875 | */ | |||
876 | if (un->un_ops->uno_mcast) { | |||
877 | mutex_enter(&unp->unp_mcastlock); | |||
878 | (*un->un_ops->uno_mcast)(ifp); | |||
879 | unp->unp_mcastactive = true; | |||
880 | mutex_exit(&unp->unp_mcastlock); | |||
881 | } | |||
882 | ||||
869 | /* Start up the receive pipe(s). */ | 883 | /* Start up the receive pipe(s). */ | |
870 | usbnet_rx_start_pipes(un); | 884 | usbnet_rx_start_pipes(un); | |
871 | 885 | |||
872 | callout_schedule(&unp->unp_stat_ch, hz); | 886 | callout_schedule(&unp->unp_stat_ch, hz); | |
873 | 887 | |||
874 | out: | 888 | out: | |
875 | if (error) { | 889 | if (error) { | |
876 | usbnet_rx_list_fini(un); | 890 | usbnet_rx_list_fini(un); | |
877 | usbnet_tx_list_fini(un); | 891 | usbnet_tx_list_fini(un); | |
878 | usbnet_ep_close_pipes(un); | 892 | usbnet_ep_close_pipes(un); | |
879 | } | 893 | } | |
880 | 894 | |||
881 | usbnet_isowned_core(un); | 895 | usbnet_isowned_core(un); | |
@@ -1008,102 +1022,87 @@ usbnet_if_ioctl(struct ifnet *ifp, u_lon | @@ -1008,102 +1022,87 @@ usbnet_if_ioctl(struct ifnet *ifp, u_lon | |||
1008 | int error; | 1022 | int error; | |
1009 | 1023 | |||
1010 | USBNETHIST_CALLARGSN(11, "%jd: enter %#jx data %#jx", | 1024 | USBNETHIST_CALLARGSN(11, "%jd: enter %#jx data %#jx", | |
1011 | unp->unp_number, cmd, (uintptr_t)data, 0); | 1025 | unp->unp_number, cmd, (uintptr_t)data, 0); | |
1012 | 1026 | |||
1013 | if (un->un_ops->uno_override_ioctl) | 1027 | if (un->un_ops->uno_override_ioctl) | |
1014 | return uno_override_ioctl(un, ifp, cmd, data); | 1028 | return uno_override_ioctl(un, ifp, cmd, data); | |
1015 | 1029 | |||
1016 | error = ether_ioctl(ifp, cmd, data); | 1030 | error = ether_ioctl(ifp, cmd, data); | |
1017 | if (error == ENETRESET) { | 1031 | if (error == ENETRESET) { | |
1018 | switch (cmd) { | 1032 | switch (cmd) { | |
1019 | case SIOCADDMULTI: | 1033 | case SIOCADDMULTI: | |
1020 | case SIOCDELMULTI: | 1034 | case SIOCDELMULTI: | |
1021 | usb_add_task(un->un_udev, &unp->unp_mcasttask, | 1035 | /* | |
1022 | USB_TASKQ_DRIVER); | 1036 | * If there's a hardware multicast filter, and | |
1037 | * it has been programmed by usbnet_init_rx_tx | |||
1038 | * and is active, update it now. Otherwise, | |||
1039 | * drop the update on the floor -- it will be | |||
1040 | * observed by usbnet_init_rx_tx next time we | |||
1041 | * bring the interface up. | |||
1042 | */ | |||
1043 | if (un->un_ops->uno_mcast) { | |||
1044 | mutex_enter(&unp->unp_mcastlock); | |||
1045 | if (unp->unp_mcastactive) | |||
1046 | (*un->un_ops->uno_mcast)(ifp); | |||
1047 | mutex_exit(&unp->unp_mcastlock); | |||
1048 | } | |||
1023 | error = 0; | 1049 | error = 0; | |
1024 | break; | 1050 | break; | |
1025 | default: | 1051 | default: | |
1026 | error = uno_ioctl(un, ifp, cmd, data); | 1052 | error = uno_ioctl(un, ifp, cmd, data); | |
1027 | } | 1053 | } | |
1028 | } | 1054 | } | |
1029 | 1055 | |||
1030 | return error; | 1056 | return error; | |
1031 | } | 1057 | } | |
1032 | 1058 | |||
1033 | static void | |||
1034 | usbnet_mcast_task(void *arg) | |||
1035 | { | |||
1036 | USBNETHIST_FUNC(); | |||
1037 | struct usbnet * const un = arg; | |||
1038 | struct ifnet * const ifp = usbnet_ifp(un); | |||
1039 | ||||
1040 | USBNETHIST_CALLARGSN(10, "%jd: enter", | |||
1041 | un->un_pri->unp_number, 0, 0, 0); | |||
1042 | ||||
1043 | /* | |||
1044 | * If we're detaching, we must check usbnet_isdying _before_ | |||
1045 | * touching IFNET_LOCK -- the ifnet may have been detached by | |||
1046 | * the time this task runs. This is racy -- unp_dying may be | |||
1047 | * set immediately after we test it -- but nevertheless safe, | |||
1048 | * because usbnet_detach waits for the task to complete before | |||
1049 | * issuing if_detach, and necessary, so that we don't touch | |||
1050 | * IFNET_LOCK after if_detach. See usbnet_detach for details. | |||
1051 | */ | |||
1052 | if (usbnet_isdying(un)) | |||
1053 | return; | |||
1054 | ||||
1055 | /* | |||
1056 | * If the hardware is running, ask the driver to reprogram the | |||
1057 | * multicast filter. If the hardware is not running, the | |||
1058 | * driver is responsible for programming the multicast filter | |||
1059 | * as part of its uno_init routine to bring the hardware up. | |||
1060 | */ | |||
1061 | IFNET_LOCK(ifp); | |||
1062 | if (ifp->if_flags & IFF_RUNNING) { | |||
1063 | if (un->un_ops->uno_mcast) { | |||
1064 | mutex_enter(&un->un_pri->unp_core_lock); | |||
1065 | (*un->un_ops->uno_mcast)(ifp); | |||
1066 | mutex_exit(&un->un_pri->unp_core_lock); | |||
1067 | } | |||
1068 | } | |||
1069 | IFNET_UNLOCK(ifp); | |||
1070 | } | |||
1071 | ||||
1072 | /* | 1059 | /* | |
1073 | * Generic stop network function: | 1060 | * Generic stop network function: | |
1074 | * - mark as stopping | 1061 | * - mark as stopping | |
1075 | * - call DD routine to stop the device | 1062 | * - call DD routine to stop the device | |
1076 | * - turn off running, timer, statchg callout, link | 1063 | * - turn off running, timer, statchg callout, link | |
1077 | * - stop transfers | 1064 | * - stop transfers | |
1078 | * - free RX and TX resources | 1065 | * - free RX and TX resources | |
1079 | * - close pipes | 1066 | * - close pipes | |
1080 | * | 1067 | * | |
1081 | * usbnet_stop() is exported for drivers to use, expects lock held. | 1068 | * usbnet_stop() is exported for drivers to use, expects lock held. | |
1082 | * | 1069 | * | |
1083 | * usbnet_if_stop() is for the if_stop handler. | 1070 | * usbnet_if_stop() is for the if_stop handler. | |
1084 | */ | 1071 | */ | |
1085 | void | 1072 | void | |
1086 | usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable) | 1073 | usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable) | |
1087 | { | 1074 | { | |
1088 | struct usbnet_private * const unp = un->un_pri; | 1075 | struct usbnet_private * const unp = un->un_pri; | |
1089 | 1076 | |||
1090 | USBNETHIST_FUNC(); USBNETHIST_CALLED(); | 1077 | USBNETHIST_FUNC(); USBNETHIST_CALLED(); | |
1091 | 1078 | |||
1092 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), | 1079 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), | |
1093 | "%s", ifp->if_xname); | 1080 | "%s", ifp->if_xname); | |
1094 | usbnet_isowned_core(un); | 1081 | usbnet_isowned_core(un); | |
1095 | 1082 | |||
1096 | /* | 1083 | /* | |
1084 | * For drivers with hardware multicast filter update callbacks: | |||
1085 | * Prevent concurrent access to the hardware registers by | |||
1086 | * multicast filter updates, which happens without IFNET_LOCK | |||
1087 | * or the usbnet core lock. | |||
1088 | */ | |||
1089 | if (un->un_ops->uno_mcast) { | |||
1090 | mutex_enter(&unp->unp_mcastlock); | |||
1091 | unp->unp_mcastactive = false; | |||
1092 | mutex_exit(&unp->unp_mcastlock); | |||
1093 | } | |||
1094 | ||||
1095 | /* | |||
1097 | * Prevent new activity (rescheduling ticks, xfers, &c.) and | 1096 | * Prevent new activity (rescheduling ticks, xfers, &c.) and | |
1098 | * clear the watchdog timer. | 1097 | * clear the watchdog timer. | |
1099 | */ | 1098 | */ | |
1100 | mutex_enter(&unp->unp_rxlock); | 1099 | mutex_enter(&unp->unp_rxlock); | |
1101 | mutex_enter(&unp->unp_txlock); | 1100 | mutex_enter(&unp->unp_txlock); | |
1102 | unp->unp_stopping = true; | 1101 | unp->unp_stopping = true; | |
1103 | unp->unp_timer = 0; | 1102 | unp->unp_timer = 0; | |
1104 | mutex_exit(&unp->unp_txlock); | 1103 | mutex_exit(&unp->unp_txlock); | |
1105 | mutex_exit(&unp->unp_rxlock); | 1104 | mutex_exit(&unp->unp_rxlock); | |
1106 | 1105 | |||
1107 | /* | 1106 | /* | |
1108 | * Stop the timer first, then the task -- if the timer was | 1107 | * Stop the timer first, then the task -- if the timer was | |
1109 | * already firing, we stop the task or wait for it complete | 1108 | * already firing, we stop the task or wait for it complete | |
@@ -1377,36 +1376,35 @@ usbnet_attach(struct usbnet *un, | @@ -1377,36 +1376,35 @@ usbnet_attach(struct usbnet *un, | |||
1377 | KASSERT(un->un_ops->uno_rx_loop); | 1376 | KASSERT(un->un_ops->uno_rx_loop); | |
1378 | KASSERT(un->un_ops->uno_init); | 1377 | KASSERT(un->un_ops->uno_init); | |
1379 | KASSERT(un->un_rx_bufsz); | 1378 | KASSERT(un->un_rx_bufsz); | |
1380 | KASSERT(un->un_tx_bufsz); | 1379 | KASSERT(un->un_tx_bufsz); | |
1381 | KASSERT(un->un_rx_list_cnt); | 1380 | KASSERT(un->un_rx_list_cnt); | |
1382 | KASSERT(un->un_tx_list_cnt); | 1381 | KASSERT(un->un_tx_list_cnt); | |
1383 | 1382 | |||
1384 | /* Unfortunate fact. */ | 1383 | /* Unfortunate fact. */ | |
1385 | KASSERT(un == device_private(un->un_dev)); | 1384 | KASSERT(un == device_private(un->un_dev)); | |
1386 | 1385 | |||
1387 | un->un_pri = kmem_zalloc(sizeof(*un->un_pri), KM_SLEEP); | 1386 | un->un_pri = kmem_zalloc(sizeof(*un->un_pri), KM_SLEEP); | |
1388 | struct usbnet_private * const unp = un->un_pri; | 1387 | struct usbnet_private * const unp = un->un_pri; | |
1389 | 1388 | |||
1390 | usb_init_task(&unp->unp_mcasttask, usbnet_mcast_task, un, | |||
1391 | USB_TASKQ_MPSAFE); | |||
1392 | usb_init_task(&unp->unp_ticktask, usbnet_tick_task, un, | 1389 | usb_init_task(&unp->unp_ticktask, usbnet_tick_task, un, | |
1393 | USB_TASKQ_MPSAFE); | 1390 | USB_TASKQ_MPSAFE); | |
1394 | callout_init(&unp->unp_stat_ch, CALLOUT_MPSAFE); | 1391 | callout_init(&unp->unp_stat_ch, CALLOUT_MPSAFE); | |
1395 | callout_setfunc(&unp->unp_stat_ch, usbnet_tick, un); | 1392 | callout_setfunc(&unp->unp_stat_ch, usbnet_tick, un); | |
1396 | 1393 | |||
1397 | mutex_init(&unp->unp_txlock, MUTEX_DEFAULT, IPL_SOFTUSB); | 1394 | mutex_init(&unp->unp_txlock, MUTEX_DEFAULT, IPL_SOFTUSB); | |
1398 | mutex_init(&unp->unp_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB); | 1395 | mutex_init(&unp->unp_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB); | |
1399 | mutex_init(&unp->unp_core_lock, MUTEX_DEFAULT, IPL_NONE); | 1396 | mutex_init(&unp->unp_core_lock, MUTEX_DEFAULT, IPL_NONE); | |
1397 | mutex_init(&unp->unp_mcastlock, MUTEX_DEFAULT, IPL_SOFTCLOCK); | |||
1400 | 1398 | |||
1401 | rnd_attach_source(&unp->unp_rndsrc, device_xname(un->un_dev), | 1399 | rnd_attach_source(&unp->unp_rndsrc, device_xname(un->un_dev), | |
1402 | RND_TYPE_NET, RND_FLAG_DEFAULT); | 1400 | RND_TYPE_NET, RND_FLAG_DEFAULT); | |
1403 | 1401 | |||
1404 | usbnet_rx_list_alloc(un); | 1402 | usbnet_rx_list_alloc(un); | |
1405 | usbnet_tx_list_alloc(un); | 1403 | usbnet_tx_list_alloc(un); | |
1406 | 1404 | |||
1407 | unp->unp_number = atomic_inc_uint_nv(&usbnet_number); | 1405 | unp->unp_number = atomic_inc_uint_nv(&usbnet_number); | |
1408 | 1406 | |||
1409 | unp->unp_attached = true; | 1407 | unp->unp_attached = true; | |
1410 | } | 1408 | } | |
1411 | 1409 | |||
1412 | static void | 1410 | static void | |
@@ -1529,81 +1527,45 @@ usbnet_detach(device_t self, int flags) | @@ -1529,81 +1527,45 @@ usbnet_detach(device_t self, int flags) | |||
1529 | if (ifp->if_flags & IFF_RUNNING) { | 1527 | if (ifp->if_flags & IFF_RUNNING) { | |
1530 | usbnet_if_stop(ifp, 1); | 1528 | usbnet_if_stop(ifp, 1); | |
1531 | } | 1529 | } | |
1532 | IFNET_UNLOCK(ifp); | 1530 | IFNET_UNLOCK(ifp); | |
1533 | } | 1531 | } | |
1534 | 1532 | |||
1535 | /* | 1533 | /* | |
1536 | * The callout and tick task can't be scheduled anew at this | 1534 | * The callout and tick task can't be scheduled anew at this | |
1537 | * point, and usbnet_if_stop has waited for them to complete. | 1535 | * point, and usbnet_if_stop has waited for them to complete. | |
1538 | */ | 1536 | */ | |
1539 | KASSERT(!callout_pending(&unp->unp_stat_ch)); | 1537 | KASSERT(!callout_pending(&unp->unp_stat_ch)); | |
1540 | KASSERT(!usb_task_pending(un->un_udev, &unp->unp_ticktask)); | 1538 | KASSERT(!usb_task_pending(un->un_udev, &unp->unp_ticktask)); | |
1541 | 1539 | |||
1542 | usb_rem_task_wait(un->un_udev, &unp->unp_mcasttask, USB_TASKQ_DRIVER, | |||
1543 | NULL); | |||
1544 | ||||
1545 | if (mii) { | 1540 | if (mii) { | |
1546 | mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY); | 1541 | mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY); | |
1547 | ifmedia_fini(&mii->mii_media); | 1542 | ifmedia_fini(&mii->mii_media); | |
1548 | } | 1543 | } | |
1549 | if (unp->unp_ifp_attached) { | 1544 | if (unp->unp_ifp_attached) { | |
1550 | if (!usbnet_empty_eaddr(un)) | 1545 | if (!usbnet_empty_eaddr(un)) | |
1551 | ether_ifdetach(ifp); | 1546 | ether_ifdetach(ifp); | |
1552 | else | 1547 | else | |
1553 | bpf_detach(ifp); | 1548 | bpf_detach(ifp); | |
1554 | if_detach(ifp); | 1549 | if_detach(ifp); | |
1555 | } | 1550 | } | |
1556 | usbnet_ec(un)->ec_mii = NULL; | 1551 | usbnet_ec(un)->ec_mii = NULL; | |
1557 | 1552 | |||
1558 | /* | |||
1559 | * We have already waited for the multicast task to complete. | |||
1560 | * Unfortunately, until if_detach, nothing has prevented it | |||
1561 | * from running again -- another thread might issue if_mcast_op | |||
1562 | * between the time of our first usb_rem_task_wait and the time | |||
1563 | * we actually get around to if_detach. | |||
1564 | * | |||
1565 | * Fortunately, the first usb_rem_task_wait ensures that if the | |||
1566 | * task is scheduled again, it will witness our setting of | |||
1567 | * unp_dying to true[*]. So after that point, if the task is | |||
1568 | * scheduled again, it will decline to touch IFNET_LOCK and do | |||
1569 | * nothing. But we still need to wait for it to complete. | |||
1570 | * | |||
1571 | * It would be nice if we could write | |||
1572 | * | |||
1573 | * if_pleasestopissuingmcastopsthanks(ifp); | |||
1574 | * usb_rem_task_wait(..., &unp->unp_mcasttask, ...); | |||
1575 | * if_detach(ifp); | |||
1576 | * | |||
1577 | * and then we would need only one usb_rem_task_wait. | |||
1578 | * | |||
1579 | * Unfortunately, there is no such operation available in | |||
1580 | * sys/net at the moment, and it would require a bit of | |||
1581 | * coordination with if_mcast_op and doifioctl probably under a | |||
1582 | * new lock. So we'll use this kludge until that mechanism is | |||
1583 | * invented. | |||
1584 | * | |||
1585 | * [*] This is not exactly a documented property of the API, | |||
1586 | * but it is implied by the single lock in the task queue | |||
1587 | * serializing changes to the task state. | |||
1588 | */ | |||
1589 | usb_rem_task_wait(un->un_udev, &unp->unp_mcasttask, USB_TASKQ_DRIVER, | |||
1590 | NULL); | |||
1591 | ||||
1592 | usbnet_rx_list_free(un); | 1553 | usbnet_rx_list_free(un); | |
1593 | usbnet_tx_list_free(un); | 1554 | usbnet_tx_list_free(un); | |
1594 | 1555 | |||
1595 | rnd_detach_source(&unp->unp_rndsrc); | 1556 | rnd_detach_source(&unp->unp_rndsrc); | |
1596 | 1557 | |||
1558 | mutex_destroy(&unp->unp_mcastlock); | |||
1597 | mutex_destroy(&unp->unp_core_lock); | 1559 | mutex_destroy(&unp->unp_core_lock); | |
1598 | mutex_destroy(&unp->unp_rxlock); | 1560 | mutex_destroy(&unp->unp_rxlock); | |
1599 | mutex_destroy(&unp->unp_txlock); | 1561 | mutex_destroy(&unp->unp_txlock); | |
1600 | 1562 | |||
1601 | callout_destroy(&unp->unp_stat_ch); | 1563 | callout_destroy(&unp->unp_stat_ch); | |
1602 | 1564 | |||
1603 | pmf_device_deregister(un->un_dev); | 1565 | pmf_device_deregister(un->un_dev); | |
1604 | 1566 | |||
1605 | /* | 1567 | /* | |
1606 | * Notify userland that we're going away, if we arrived in the | 1568 | * Notify userland that we're going away, if we arrived in the | |
1607 | * first place. | 1569 | * first place. | |
1608 | */ | 1570 | */ | |
1609 | if (unp->unp_ifp_attached) { | 1571 | if (unp->unp_ifp_attached) { |