Thu Mar 3 05:53:23 2022 UTC ()
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.


(riastradh)
diff -r1.180 -r1.181 src/sys/dev/usb/if_aue.c
diff -r1.141 -r1.142 src/sys/dev/usb/if_axe.c
diff -r1.83 -r1.84 src/sys/dev/usb/if_axen.c
diff -r1.82 -r1.83 src/sys/dev/usb/if_smsc.c
diff -r1.87 -r1.88 src/sys/dev/usb/if_udav.c
diff -r1.87 -r1.88 src/sys/dev/usb/if_url.c
diff -r1.48 -r1.49 src/sys/dev/usb/if_ure.c
diff -r1.81 -r1.82 src/sys/dev/usb/usbnet.c

cvs diff -r1.180 -r1.181 src/sys/dev/usb/if_aue.c (expand / switch to unified diff)

--- 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
279static int 279static int
280aue_csr_read_1(struct aue_softc *sc, int reg) 280aue_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
310static int 308static int
311aue_csr_read_2(struct aue_softc *sc, int reg) 309aue_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
341static int 337static int
342aue_csr_write_1(struct aue_softc *sc, int reg, int aval) 338aue_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
373static int 367static int
374aue_csr_write_2(struct aue_softc *sc, int reg, int aval) 368aue_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
614aue_uno_mcast(struct ifnet *ifp) 606aue_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);
631allmulti: 621allmulti:
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) {

cvs diff -r1.141 -r1.142 src/sys/dev/usb/if_axe.c (expand / switch to unified diff)

--- 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
103struct axe_type { 103struct 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
288static usbd_status 288static usbd_status
289axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf) 289axe_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));

cvs diff -r1.83 -r1.84 src/sys/dev/usb/if_axen.c (expand / switch to unified diff)

--- 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
105static int 105static int
106axen_cmd(struct usbnet *un, int cmd, int index, int val, void *buf) 106axen_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;
255allmulti: 251allmulti:
256 ETHER_LOCK(ec); 252 ETHER_LOCK(ec);

cvs diff -r1.82 -r1.83 src/sys/dev/usb/if_smsc.c (expand / switch to unified diff)

--- 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
207static int 207static int
208smsc_readreg(struct usbnet *un, uint32_t off, uint32_t *data) 208smsc_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
234static int 232static int
235smsc_writereg(struct usbnet *un, uint32_t off, uint32_t data) 233smsc_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
413static void 409static void
414smsc_uno_mcast(struct ifnet *ifp) 410smsc_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);
432allmulti: 426allmulti:
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;

cvs diff -r1.87 -r1.88 src/sys/dev/usb/if_udav.c (expand / switch to unified diff)

--- 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 */
60static int udav_match(device_t, cfdata_t, void *); 60static int udav_match(device_t, cfdata_t, void *);
61static void udav_attach(device_t, device_t, void *); 61static 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) */
361static int 361static int
362udav_csr_read(struct usbnet *un, int offset, void *buf, int len) 362udav_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) */
392static int 391static int
393udav_csr_write(struct usbnet *un, int offset, void *buf, int len) 392udav_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
422static int 420static int
423udav_csr_read1(struct usbnet *un, int offset) 421udav_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 */
439static int 435static int
440udav_csr_write1(struct usbnet *un, int offset, unsigned char ch) 436udav_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
577static void 572static void
578udav_uno_mcast(struct ifnet *ifp) 573udav_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);

cvs diff -r1.87 -r1.88 src/sys/dev/usb/if_url.c (expand / switch to unified diff)

--- 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 */
265static int 265static int
266url_mem(struct usbnet *un, int cmd, int offset, void *buf, int len) 266url_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
426static void 424static void
427url_uno_mcast(struct ifnet *ifp) 425url_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;

cvs diff -r1.48 -r1.49 src/sys/dev/usb/if_ure.c (expand / switch to unified diff)

--- 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
333static void 333static void
334ure_uno_mcast(struct ifnet *ifp) 334ure_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; /* ??? */

cvs diff -r1.81 -r1.82 src/sys/dev/usb/usbnet.c (expand / switch to unified diff)

--- 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
45struct usbnet_cdata { 45struct usbnet_cdata {
46 struct usbnet_chain *uncd_tx_chain; 46 struct usbnet_chain *uncd_tx_chain;
47 struct usbnet_chain *uncd_rx_chain; 47 struct usbnet_chain *uncd_rx_chain;
@@ -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
53struct usbnet_private { 53struct usbnet_private {
54 /* 54 /*
55 * - unp_core_lock protects most of this structure, the public one, 55 * - unp_core_lock protects most of this structure, the public one,
56 * and the MII / media data. 56 * and the MII / media data.
57 * - unp_rxlock protects the rx path and its data 57 * - unp_rxlock protects the rx path and its data
58 * - unp_txlock protects the tx path and its data 58 * - unp_txlock protects the tx path and its data
59 * 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
874out: 888out:
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
1033static void 
1034usbnet_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 */
1085void 1072void
1086usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable) 1073usbnet_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
1412static void 1410static 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) {