Bug Summary

File:dev/usb/if_mue.c
Warning:line 547, column 47
The left operand of '<<' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name if_mue.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/usb/if_mue.c
1/* $OpenBSD: if_mue.c,v 1.11 2021/07/25 06:43:04 mglocker Exp $ */
2
3/*
4 * Copyright (c) 2018 Kevin Lo <kevlo@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/* Driver for Microchip LAN7500/LAN7800 chipsets. */
20
21#include "bpfilter.h"
22
23#include <sys/param.h>
24#include <sys/systm.h>
25#include <sys/sockio.h>
26#include <sys/rwlock.h>
27#include <sys/mbuf.h>
28#include <sys/kernel.h>
29#include <sys/socket.h>
30
31#include <sys/device.h>
32
33#include <machine/bus.h>
34
35#include <net/if.h>
36#include <net/if_dl.h>
37#include <net/if_media.h>
38
39#if NBPFILTER1 > 0
40#include <net/bpf.h>
41#endif
42
43#include <netinet/in.h>
44#include <netinet/if_ether.h>
45
46#include <dev/mii/miivar.h>
47
48#include <dev/usb/usb.h>
49#include <dev/usb/usbdi.h>
50#include <dev/usb/usbdi_util.h>
51#include <dev/usb/usbdivar.h>
52#include <dev/usb/usbdevs.h>
53
54#include <dev/usb/if_muereg.h>
55
56#ifdef MUE_DEBUG
57#define DPRINTF(x) do { if (muedebug) printf x; } while (0)
58#define DPRINTFN(n,x) do { if (muedebug >= (n)) printf x; } while (0)
59int muedebug = 0;
60#else
61#define DPRINTF(x)
62#define DPRINTFN(n,x)
63#endif
64
65/*
66 * Various supported device vendors/products.
67 */
68struct mue_type {
69 struct usb_devno mue_dev;
70 uint16_t mue_flags;
71#define LAN75000x0001 0x0001 /* LAN7500 */
72};
73
74const struct mue_type mue_devs[] = {
75 { { USB_VENDOR_SMC20x0424, USB_PRODUCT_SMC2_LAN75000x7500 }, LAN75000x0001 },
76 { { USB_VENDOR_SMC20x0424, USB_PRODUCT_SMC2_LAN75050x7505 }, LAN75000x0001 },
77 { { USB_VENDOR_SMC20x0424, USB_PRODUCT_SMC2_LAN78000x7800 }, 0 },
78 { { USB_VENDOR_SMC20x0424, USB_PRODUCT_SMC2_LAN78010x7801 }, 0 },
79 { { USB_VENDOR_SMC20x0424, USB_PRODUCT_SMC2_LAN78500x7850 }, 0 }
80};
81
82#define mue_lookup(v, p)((struct mue_type *)usbd_match_device((const struct usb_devno
*)(mue_devs), sizeof (mue_devs) / sizeof ((mue_devs)[0]), sizeof
((mue_devs)[0]), (v), (p)))
((struct mue_type *)usb_lookup(mue_devs, v, p)usbd_match_device((const struct usb_devno *)(mue_devs), sizeof
(mue_devs) / sizeof ((mue_devs)[0]), sizeof ((mue_devs)[0]),
(v), (p))
)
83
84int mue_match(struct device *, void *, void *);
85void mue_attach(struct device *, struct device *, void *);
86int mue_detach(struct device *, int);
87
88struct cfdriver mue_cd = {
89 NULL((void *)0), "mue", DV_IFNET
90};
91
92const struct cfattach mue_ca = {
93 sizeof(struct mue_softc), mue_match, mue_attach, mue_detach
94};
95
96uint32_t mue_csr_read(struct mue_softc *, uint32_t);
97int mue_csr_write(struct mue_softc *, uint32_t, uint32_t);
98
99void mue_lock_mii(struct mue_softc *);
100void mue_unlock_mii(struct mue_softc *);
101
102int mue_mii_wait(struct mue_softc *);
103int mue_miibus_readreg(struct device *, int, int);
104void mue_miibus_writereg(struct device *, int, int, int);
105void mue_miibus_statchg(struct device *);
106int mue_ifmedia_upd(struct ifnet *);
107void mue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
108
109int mue_eeprom_wait(struct mue_softc *);
110uint8_t mue_eeprom_getbyte(struct mue_softc *, int, uint8_t *);
111int mue_read_eeprom(struct mue_softc *, caddr_t, int, int);
112int mue_dataport_wait(struct mue_softc *);
113void mue_dataport_write(struct mue_softc *, uint32_t, uint32_t,
114 uint32_t, uint32_t *);
115void mue_init_ltm(struct mue_softc *);
116int mue_chip_init(struct mue_softc *);
117void mue_set_macaddr(struct mue_softc *);
118
119int mue_rx_list_init(struct mue_softc *);
120int mue_tx_list_init(struct mue_softc *);
121int mue_open_pipes(struct mue_softc *);
122int mue_encap(struct mue_softc *, struct mbuf *, int);
123void mue_iff(struct mue_softc *);
124void mue_rxeof(struct usbd_xfer *, void *, usbd_status);
125void mue_txeof(struct usbd_xfer *, void *, usbd_status);
126
127void mue_init(void *);
128int mue_ioctl(struct ifnet *, u_long, caddr_t);
129void mue_watchdog(struct ifnet *);
130void mue_reset(struct mue_softc *);
131void mue_start(struct ifnet *);
132void mue_stop(struct mue_softc *);
133void mue_tick(void *);
134void mue_tick_task(void *);
135
136#define MUE_SETBIT(sc, reg, x)mue_csr_write(sc, reg, mue_csr_read(sc, reg) | (x)) \
137 mue_csr_write(sc, reg, mue_csr_read(sc, reg) | (x))
138
139#define MUE_CLRBIT(sc, reg, x)mue_csr_write(sc, reg, mue_csr_read(sc, reg) & ~(x)) \
140 mue_csr_write(sc, reg, mue_csr_read(sc, reg) & ~(x))
141
142#if defined(__arm__) || defined(__arm64__)
143
144#include <dev/ofw/openfirm.h>
145
146void
147mue_enaddr_OF(struct mue_softc *sc)do {} while(0)
148{
149 char *device = "/axi/usb/hub/ethernet";
150 char prop[64];
151 int node;
152
153 if (sc->mue_dev.dv_unit != 0)
154 return;
155
156 /* Get the Raspberry Pi MAC address from FDT. */
157 if ((node = OF_finddevice("/aliases")) == -1)
158 return;
159 if (OF_getprop(node, "ethernet0", prop, sizeof(prop)) > 0 ||
160 OF_getprop(node, "ethernet", prop, sizeof(prop)) > 0)
161 device = prop;
162
163 if ((node = OF_finddevice(device)) == -1)
164 return;
165 if (OF_getprop(node, "local-mac-address", sc->arpcom.ac_enaddr,
166 sizeof(sc->arpcom.ac_enaddr)) != sizeof(sc->arpcom.ac_enaddr)) {
167 OF_getprop(node, "mac-address", sc->arpcom.ac_enaddr,
168 sizeof(sc->arpcom.ac_enaddr));
169 }
170}
171#else
172#define mue_enaddr_OF(x)do {} while(0) do {} while(0)
173#endif
174
175uint32_t
176mue_csr_read(struct mue_softc *sc, uint32_t reg)
177{
178 usb_device_request_t req;
179 usbd_status err;
180 uDWord val;
181
182 if (usbd_is_dying(sc->mue_udev))
183 return (0);
184
185 USETDW(val, 0)(*(u_int32_t *)(val) = (0));
186 req.bmRequestType = UT_READ_VENDOR_DEVICE(0x80 | 0x40 | 0x00);
187 req.bRequest = MUE_UR_READREG0xa1;
188 USETW(req.wValue, 0)(*(u_int16_t *)(req.wValue) = (0));
189 USETW(req.wIndex, reg)(*(u_int16_t *)(req.wIndex) = (reg));
190 USETW(req.wLength, 4)(*(u_int16_t *)(req.wLength) = (4));
191
192 err = usbd_do_request(sc->mue_udev, &req, &val);
193 if (err) {
194 DPRINTF(("%s: mue_csr_read: reg=0x%x err=%s\n",
195 sc->mue_dev.dv_xname, reg, usbd_errstr(err)));
196 return (0);
197 }
198
199 return (UGETDW(val)(*(u_int32_t *)(val)));
200}
201
202int
203mue_csr_write(struct mue_softc *sc, uint32_t reg, uint32_t aval)
204{
205 usb_device_request_t req;
206 usbd_status err;
207 uDWord val;
208
209 if (usbd_is_dying(sc->mue_udev))
210 return (0);
211
212 USETDW(val, aval)(*(u_int32_t *)(val) = (aval));
213 req.bmRequestType = UT_WRITE_VENDOR_DEVICE(0x00 | 0x40 | 0x00);
214 req.bRequest = MUE_UR_WRITEREG0xa0;
215 USETW(req.wValue, 0)(*(u_int16_t *)(req.wValue) = (0));
216 USETW(req.wIndex, reg)(*(u_int16_t *)(req.wIndex) = (reg));
217 USETW(req.wLength, 4)(*(u_int16_t *)(req.wLength) = (4));
218
219 err = usbd_do_request(sc->mue_udev, &req, &val);
220 if (err) {
221 DPRINTF(("%s: mue_csr_write: reg=0x%x err=%s\n",
222 sc->mue_dev.dv_xname, reg, usbd_errstr(err)));
223 return (-1);
224 }
225
226 return (0);
227}
228
229/*
230 * Get exclusive access to the MII registers.
231 */
232void
233mue_lock_mii(struct mue_softc *sc)
234{
235 sc->mue_refcnt++;
236 rw_enter_write(&sc->mue_mii_lock);
237}
238
239void
240mue_unlock_mii(struct mue_softc *sc)
241{
242 rw_exit_write(&sc->mue_mii_lock);
243 if (--sc->mue_refcnt < 0)
244 usb_detach_wakeup(&sc->mue_dev);
245}
246
247/*
248 * Wait for the MII to become ready.
249 */
250int
251mue_mii_wait(struct mue_softc *sc)
252{
253 int ntries;
254
255 for (ntries = 0; ntries < 100; ntries++) {
256 if (!(mue_csr_read(sc, MUE_MII_ACCESS0x120) & MUE_MII_ACCESS_BUSY0x00000001))
257 return (0);
258 DELAY(5)(*delay_func)(5);
259 }
260
261 printf("%s: MII timed out\n", sc->mue_dev.dv_xname);
262 return (1);
263}
264
265int
266mue_miibus_readreg(struct device *dev, int phy, int reg)
267{
268 struct mue_softc *sc = (void *)dev;
269 uint32_t val;
270
271 if (usbd_is_dying(sc->mue_udev))
272 return (0);
273
274 if (sc->mue_phyno != phy)
275 return (0);
276
277 mue_lock_mii(sc);
278 if (mue_mii_wait(sc) != 0)
279 return (0);
280
281 mue_csr_write(sc, MUE_MII_ACCESS0x120, MUE_MII_ACCESS_READ0x00000000 |
282 MUE_MII_ACCESS_BUSY0x00000001 | MUE_MII_ACCESS_REGADDR(reg)(((reg) << 6) & 0x000007c0) |
283 MUE_MII_ACCESS_PHYADDR(phy)(((phy) << 11) & 0x0000f800));
284
285 if (mue_mii_wait(sc) != 0)
286 printf("%s: MII read timed out\n", sc->mue_dev.dv_xname);
287
288 val = mue_csr_read(sc, MUE_MII_DATA0x124);
289 mue_unlock_mii(sc);
290 return (val & 0xffff);
291}
292
293void
294mue_miibus_writereg(struct device *dev, int phy, int reg, int data)
295{
296 struct mue_softc *sc = (void *)dev;
297
298 if (usbd_is_dying(sc->mue_udev))
299 return;
300
301 if (sc->mue_phyno != phy)
302 return;
303
304 mue_lock_mii(sc);
305 if (mue_mii_wait(sc) != 0)
306 return;
307
308 mue_csr_write(sc, MUE_MII_DATA0x124, data);
309 mue_csr_write(sc, MUE_MII_ACCESS0x120, MUE_MII_ACCESS_WRITE0x00000002 |
310 MUE_MII_ACCESS_BUSY0x00000001 | MUE_MII_ACCESS_REGADDR(reg)(((reg) << 6) & 0x000007c0) |
311 MUE_MII_ACCESS_PHYADDR(phy)(((phy) << 11) & 0x0000f800));
312
313 if (mue_mii_wait(sc) != 0)
314 printf("%s: MII write timed out\n", sc->mue_dev.dv_xname);
315
316 mue_unlock_mii(sc);
317}
318
319void
320mue_miibus_statchg(struct device *dev)
321{
322 struct mue_softc *sc = (void *)dev;
323 struct mii_data *mii = GET_MII(sc)(&(sc)->mue_mii);
324 struct ifnet *ifp = GET_IFP(sc)(&(sc)->arpcom.ac_if);
325 uint32_t flow, threshold;
326
327 if (mii == NULL((void *)0) || ifp == NULL((void *)0) ||
328 (ifp->if_flags & IFF_RUNNING0x40) == 0)
329 return;
330
331 sc->mue_link = 0;
332 if ((mii->mii_media_status & (IFM_ACTIVE0x0000000000000002ULL | IFM_AVALID0x0000000000000001ULL)) ==
333 (IFM_ACTIVE0x0000000000000002ULL | IFM_AVALID0x0000000000000001ULL)) {
334 switch (IFM_SUBTYPE(mii->mii_media_active)((mii->mii_media_active) & 0x00000000000000ffULL)) {
335 case IFM_10_T3:
336 case IFM_100_TX6:
337 case IFM_1000_T16:
338 sc->mue_link++;
339 break;
340 default:
341 break;
342 }
343 }
344
345 /* Lost link, do nothing. */
346 if (sc->mue_link == 0)
347 return;
348
349 if (!(sc->mue_flags & LAN75000x0001)) {
350 if (sc->mue_udev->speed == USB_SPEED_SUPER4) {
351 if (IFM_SUBTYPE(mii->mii_media_active)((mii->mii_media_active) & 0x00000000000000ffULL) == IFM_1000_T16) {
352 /* Disable U2 and enable U1. */
353 MUE_CLRBIT(sc, MUE_USB_CFG1,mue_csr_write(sc, 0x084, mue_csr_read(sc, 0x084) & ~(0x00001000
))
354 MUE_USB_CFG1_DEV_U2_INIT_EN)mue_csr_write(sc, 0x084, mue_csr_read(sc, 0x084) & ~(0x00001000
))
;
355 MUE_SETBIT(sc, MUE_USB_CFG1,mue_csr_write(sc, 0x084, mue_csr_read(sc, 0x084) | (0x00000400
))
356 MUE_USB_CFG1_DEV_U1_INIT_EN)mue_csr_write(sc, 0x084, mue_csr_read(sc, 0x084) | (0x00000400
))
;
357 } else {
358 /* Enable U1 and U2. */
359 MUE_SETBIT(sc, MUE_USB_CFG1,mue_csr_write(sc, 0x084, mue_csr_read(sc, 0x084) | (0x00000400
| 0x00001000))
360 MUE_USB_CFG1_DEV_U1_INIT_EN |mue_csr_write(sc, 0x084, mue_csr_read(sc, 0x084) | (0x00000400
| 0x00001000))
361 MUE_USB_CFG1_DEV_U2_INIT_EN)mue_csr_write(sc, 0x084, mue_csr_read(sc, 0x084) | (0x00000400
| 0x00001000))
;
362 }
363 }
364 }
365
366 threshold = 0;
367 flow = 0;
368 if (IFM_OPTIONS(mii->mii_media_active)((mii->mii_media_active) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL
))
& IFM_FDX0x0000010000000000ULL) {
369 if (IFM_OPTIONS(mii->mii_media_active)((mii->mii_media_active) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL
))
& IFM_ETH_TXPAUSE0x0000000000040000ULL) {
370 flow |= MUE_FLOW_TX_FCEN0x40000000 | MUE_FLOW_PAUSE_TIME0x0000ffff;
371
372 /* XXX magic numbers come from Linux driver. */
373 if (sc->mue_flags & LAN75000x0001) {
374 threshold = 0x820;
375 } else {
376 threshold =
377 (sc->mue_udev->speed == USB_SPEED_SUPER4) ?
378 0x817 : 0x211;
379 }
380 }
381 if (IFM_OPTIONS(mii->mii_media_active)((mii->mii_media_active) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL
))
& IFM_ETH_RXPAUSE0x0000000000020000ULL)
382 flow |= MUE_FLOW_RX_FCEN0x20000000;
383 }
384 mue_csr_write(sc, (sc->mue_flags & LAN75000x0001) ?
385 MUE_FCT_FLOW0x0a0 : MUE_7800_FCT_FLOW0x0d0, threshold);
386
387 /* Threshold value should be set before enabling flow. */
388 mue_csr_write(sc, MUE_FLOW0x10c, flow);
389}
390
391/*
392 * Set media options.
393 */
394int
395mue_ifmedia_upd(struct ifnet *ifp)
396{
397 struct mue_softc *sc = ifp->if_softc;
398 struct mii_data *mii = GET_MII(sc)(&(sc)->mue_mii);
399
400 if (mii->mii_instance) {
401 struct mii_softc *miisc;
402 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)for((miisc) = ((&mii->mii_phys)->lh_first); (miisc)
!= ((void *)0); (miisc) = ((miisc)->mii_list.le_next))
403 mii_phy_reset(miisc);
404 }
405 return (mii_mediachg(mii));
406}
407
408/*
409 * Report current media status.
410 */
411void
412mue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
413{
414 struct mue_softc *sc = ifp->if_softc;
415 struct mii_data *mii = GET_MII(sc)(&(sc)->mue_mii);
416
417 mii_pollstat(mii);
418 ifmr->ifm_active = mii->mii_media_active;
419 ifmr->ifm_status = mii->mii_media_status;
420}
421
422int
423mue_eeprom_wait(struct mue_softc *sc)
424{
425 uint32_t val;
426 int ntries;
427
428 for (ntries = 0; ntries < 100; ntries++) {
429 val = mue_csr_read(sc, MUE_E2P_CMD0x040);
430 if (!(val & MUE_E2P_CMD_BUSY0x80000000) || (val & MUE_E2P_CMD_TIMEOUT0x00000400))
431 return (0);
432 DELAY(5)(*delay_func)(5);
433 }
434
435 return (1);
436}
437
438uint8_t
439mue_eeprom_getbyte(struct mue_softc *sc, int addr, uint8_t *dest)
440{
441 uint32_t byte = 0;
442 int ntries;
443
444 for (ntries = 0; ntries < 100; ntries++) {
445 if (!(mue_csr_read(sc, MUE_E2P_CMD0x040) & MUE_E2P_CMD_BUSY0x80000000))
446 break;
447 DELAY(5)(*delay_func)(5);
448 }
449
450 if (ntries == 100) {
451 printf("%s: EEPROM failed to come ready\n",
452 sc->mue_dev.dv_xname);
453 return (ETIMEDOUT60);
454 }
455
456 mue_csr_write(sc, MUE_E2P_CMD0x040, MUE_E2P_CMD_READ0x00000000 | MUE_E2P_CMD_BUSY0x80000000 |
457 (addr & MUE_E2P_CMD_ADDR_MASK0x000001ff));
458
459 if (mue_eeprom_wait(sc) != 0) {
460 printf("%s: EEPROM read timed out\n", sc->mue_dev.dv_xname);
461 return (ETIMEDOUT60);
462 }
463
464 byte = mue_csr_read(sc, MUE_E2P_DATA0x044);
465 *dest = byte & 0xff;
466
467 return (0);
468}
469
470int
471mue_read_eeprom(struct mue_softc *sc, caddr_t dest, int off, int cnt)
472{
473 uint32_t val;
474 uint8_t byte = 0;
475 int i, err = 0;
476
477 /*
478 * EEPROM pins are muxed with the LED function on LAN7800 device.
479 */
480 val = mue_csr_read(sc, MUE_HW_CFG0x010);
481 if (sc->mue_product
17.1
Field 'mue_product' is not equal to USB_PRODUCT_SMC2_LAN7800
== USB_PRODUCT_SMC2_LAN78000x7800) {
18
Taking false branch
482 MUE_CLRBIT(sc, MUE_HW_CFG,mue_csr_write(sc, 0x010, mue_csr_read(sc, 0x010) & ~(0x00100000
| 0x00200000))
483 MUE_HW_CFG_LED0_EN | MUE_HW_CFG_LED1_EN)mue_csr_write(sc, 0x010, mue_csr_read(sc, 0x010) & ~(0x00100000
| 0x00200000))
;
484 }
485
486 for (i = 0; i < cnt; i++) {
19
Loop condition is true. Entering loop body
22
Loop condition is true. Entering loop body
487 err = mue_eeprom_getbyte(sc, off + i, &byte);
488 if (err)
20
Assuming 'err' is 0
21
Taking false branch
23
Assuming 'err' is not equal to 0
24
Taking true branch
489 break;
25
Execution continues on line 493
490 *(dest + i) = byte;
491 }
492
493 if (sc->mue_product == USB_PRODUCT_SMC2_LAN78000x7800)
26
Assuming field 'mue_product' is not equal to USB_PRODUCT_SMC2_LAN7800
27
Taking false branch
494 mue_csr_write(sc, MUE_HW_CFG0x010, val);
495
496 return (err
27.1
'err' is not equal to 0
? 1 : 0)
;
28
'?' condition is true
29
Returning the value 1, which participates in a condition later
497}
498
499int
500mue_dataport_wait(struct mue_softc *sc)
501{
502 int ntries;
503
504 for (ntries = 0; ntries < 100; ntries++) {
505 if (mue_csr_read(sc, MUE_DP_SEL0x024) & MUE_DP_SEL_DPRDY0x80000000)
506 return (0);
507 DELAY(5)(*delay_func)(5);
508 }
509
510 printf("%s: dataport timed out\n", sc->mue_dev.dv_xname);
511 return (1);
512}
513
514void
515mue_dataport_write(struct mue_softc *sc, uint32_t sel, uint32_t addr,
516 uint32_t cnt, uint32_t *data)
517{
518 int i;
519
520 if (mue_dataport_wait(sc) != 0)
521 return;
522
523 mue_csr_write(sc, MUE_DP_SEL0x024,
524 (mue_csr_read(sc, MUE_DP_SEL0x024) & ~MUE_DP_SEL_RSEL_MASK0x0000000f) | sel);
525
526 for (i = 0; i < cnt; i++) {
527 mue_csr_write(sc, MUE_DP_ADDR0x02c, addr + i);
528 mue_csr_write(sc, MUE_DP_DATA0x030, data[i]);
529 mue_csr_write(sc, MUE_DP_CMD0x028, MUE_DP_CMD_WRITE0x00000001);
530 if (mue_dataport_wait(sc) != 0)
531 return;
532 }
533}
534
535void
536mue_init_ltm(struct mue_softc *sc)
537{
538 uint8_t idx[6] = { 0 };
539 int i;
540
541 if (mue_csr_read(sc, MUE_USB_CFG10x084) & MUE_USB_CFG1_LTM_ENABLE0x00000100) {
15
Assuming the condition is true
16
Taking true branch
542 uint8_t temp[2];
543
544 if (mue_read_eeprom(sc, (caddr_t)&temp, MUE_EE_LTM_OFFSET0x3f, 2)) {
17
Calling 'mue_read_eeprom'
30
Returning from 'mue_read_eeprom'
31
Taking true branch
545 if (temp[0] != 24)
32
Assuming the condition is false
33
Taking false branch
546 goto done;
547 mue_read_eeprom(sc, (caddr_t)&idx, temp[1] << 1, 24);
34
The left operand of '<<' is a garbage value
548 }
549 }
550done:
551 for (i = 0; i < sizeof(idx); i++)
552 mue_csr_write(sc, MUE_LTM_INDEX(i)(0x0e0 + (i) * 4), idx[i]);
553}
554
555int
556mue_chip_init(struct mue_softc *sc)
557{
558 uint32_t val;
559 int ntries;
560
561 if (sc->mue_flags & LAN75000x0001) {
7
Taking false branch
562 for (ntries = 0; ntries < 100; ntries++) {
563 if (mue_csr_read(sc, MUE_PMT_CTL0x014) & MUE_PMT_CTL_READY0x00000080)
564 break;
565 DELAY(1000)(*delay_func)(1000); /* 1 msec */
566 }
567 if (ntries == 100) {
568 printf("%s: timeout waiting for device ready\n",
569 sc->mue_dev.dv_xname);
570 return (ETIMEDOUT60);
571 }
572 }
573
574 MUE_SETBIT(sc, MUE_HW_CFG, MUE_HW_CFG_LRST)mue_csr_write(sc, 0x010, mue_csr_read(sc, 0x010) | (0x00000002
))
;
575
576 for (ntries = 0; ntries < 1000; ntries++) {
8
Loop condition is true. Entering loop body
577 if (!(mue_csr_read(sc, MUE_HW_CFG0x010) & MUE_HW_CFG_LRST0x00000002))
9
Taking true branch
578 break;
10
Execution continues on line 581
579 DELAY(5)(*delay_func)(5);
580 }
581 if (ntries
10.1
'ntries' is not equal to 1000
== 1000) {
11
Taking false branch
582 printf("%s: timeout on lite software reset\n",
583 sc->mue_dev.dv_xname);
584 return (ETIMEDOUT60);
585 }
586
587 /* Respond to the IN token with a NAK. */
588 if (sc->mue_flags & LAN75000x0001)
12
Taking false branch
589 MUE_SETBIT(sc, MUE_HW_CFG, MUE_HW_CFG_BIR)mue_csr_write(sc, 0x010, mue_csr_read(sc, 0x010) | (0x00000080
))
;
590 else
591 MUE_SETBIT(sc, MUE_USB_CFG0, MUE_USB_CFG0_BIR)mue_csr_write(sc, 0x080, mue_csr_read(sc, 0x080) | (0x00000040
))
;
592
593 if (sc->mue_flags & LAN75000x0001) {
13
Taking false branch
594 mue_csr_write(sc, MUE_BURST_CAP0x034,
595 (sc->mue_udev->speed == USB_SPEED_HIGH3) ?
596 MUE_BURST_MIN_BUFSZ37 : MUE_BURST_MAX_BUFSZ129);
597 mue_csr_write(sc, MUE_BULK_IN_DELAY0x03c, MUE_DEFAULT_BULKIN_DELAY0x00002000);
598
599 MUE_SETBIT(sc, MUE_HW_CFG, MUE_HW_CFG_BCE | MUE_HW_CFG_MEF)mue_csr_write(sc, 0x010, mue_csr_read(sc, 0x010) | (0x00000004
| 0x00000010))
;
600
601 /* Set undocumented FIFO sizes. */
602 mue_csr_write(sc, MUE_FCT_RX_FIFO_END0x098, 0x27);
603 mue_csr_write(sc, MUE_FCT_TX_FIFO_END0x098, 0x17);
604 } else {
605 /* Init LTM. */
606 mue_init_ltm(sc);
14
Calling 'mue_init_ltm'
607
608 val = (sc->mue_udev->speed == USB_SPEED_SUPER4) ?
609 MUE_7800_BURST_MIN_BUFSZ12 : MUE_7800_BURST_MAX_BUFSZ24;
610 mue_csr_write(sc, MUE_7800_BURST_CAP0x090, val);
611 mue_csr_write(sc, MUE_7800_BULK_IN_DELAY0x094,
612 MUE_7800_DEFAULT_BULKIN_DELAY0x00000800);
613
614 MUE_SETBIT(sc, MUE_HW_CFG, MUE_HW_CFG_MEF)mue_csr_write(sc, 0x010, mue_csr_read(sc, 0x010) | (0x00000010
))
;
615 MUE_SETBIT(sc, MUE_USB_CFG0, MUE_USB_CFG0_BCE)mue_csr_write(sc, 0x080, mue_csr_read(sc, 0x080) | (0x00000020
))
;
616 }
617
618 mue_csr_write(sc, MUE_INT_STATUS0x00c, 0xffffffff);
619 mue_csr_write(sc, (sc->mue_flags & LAN75000x0001) ?
620 MUE_FCT_FLOW0x0a0 : MUE_7800_FCT_FLOW0x0d0, 0);
621 mue_csr_write(sc, MUE_FLOW0x10c, 0);
622
623 /* Reset PHY. */
624 MUE_SETBIT(sc, MUE_PMT_CTL, MUE_PMT_CTL_PHY_RST)mue_csr_write(sc, 0x014, mue_csr_read(sc, 0x014) | (0x00000010
))
;
625 for (ntries = 0; ntries < 100; ntries++) {
626 val = mue_csr_read(sc, MUE_PMT_CTL0x014);
627 if (!(val & MUE_PMT_CTL_PHY_RST0x00000010) && (val & MUE_PMT_CTL_READY0x00000080))
628 break;
629 DELAY(10000)(*delay_func)(10000);
630 }
631 if (ntries == 100) {
632 printf("%s: timeout waiting for PHY reset\n",
633 sc->mue_dev.dv_xname);
634 return (ETIMEDOUT60);
635 }
636
637 /* LAN7801 only has RGMII mode. */
638 if (sc->mue_product == USB_PRODUCT_SMC2_LAN78010x7801)
639 MUE_CLRBIT(sc, MUE_MAC_CR, MUE_MAC_CR_GMII_EN)mue_csr_write(sc, 0x100, mue_csr_read(sc, 0x100) & ~(0x00080000
))
;
640
641 if (sc->mue_flags & LAN75000x0001 || !sc->mue_eeprom_present) {
642 /* Allow MAC to detect speed and duplex from PHY. */
643 MUE_SETBIT(sc, MUE_MAC_CR, MUE_MAC_CR_AUTO_SPEED |mue_csr_write(sc, 0x100, mue_csr_read(sc, 0x100) | (0x00000800
| 0x00001000))
644 MUE_MAC_CR_AUTO_DUPLEX)mue_csr_write(sc, 0x100, mue_csr_read(sc, 0x100) | (0x00000800
| 0x00001000))
;
645 }
646
647 MUE_SETBIT(sc, MUE_MAC_TX, MUE_MAC_TX_TXEN)mue_csr_write(sc, 0x108, mue_csr_read(sc, 0x108) | (0x00000001
))
;
648 MUE_SETBIT(sc, (sc->mue_flags & LAN7500) ?mue_csr_write(sc, (sc->mue_flags & 0x0001) ? 0x094 : 0x0c4
, mue_csr_read(sc, (sc->mue_flags & 0x0001) ? 0x094 : 0x0c4
) | (0x80000000))
649 MUE_FCT_TX_CTL : MUE_7800_FCT_TX_CTL, MUE_FCT_TX_CTL_EN)mue_csr_write(sc, (sc->mue_flags & 0x0001) ? 0x094 : 0x0c4
, mue_csr_read(sc, (sc->mue_flags & 0x0001) ? 0x094 : 0x0c4
) | (0x80000000))
;
650
651 /* Set the maximum frame size. */
652 MUE_CLRBIT(sc, MUE_MAC_RX, MUE_MAC_RX_RXEN)mue_csr_write(sc, 0x104, mue_csr_read(sc, 0x104) & ~(0x00000001
))
;
653 MUE_SETBIT(sc, MUE_MAC_RX, MUE_MAC_RX_MAX_LEN(ETHER_MAX_LEN))mue_csr_write(sc, 0x104, mue_csr_read(sc, 0x104) | ((((1518) <<
16) & 0x3fff0000)))
;
654 MUE_SETBIT(sc, MUE_MAC_RX, MUE_MAC_RX_RXEN)mue_csr_write(sc, 0x104, mue_csr_read(sc, 0x104) | (0x00000001
))
;
655
656 MUE_SETBIT(sc, (sc->mue_flags & LAN7500) ?mue_csr_write(sc, (sc->mue_flags & 0x0001) ? 0x090 : 0x0c0
, mue_csr_read(sc, (sc->mue_flags & 0x0001) ? 0x090 : 0x0c0
) | (0x80000000))
657 MUE_FCT_RX_CTL : MUE_7800_FCT_RX_CTL, MUE_FCT_RX_CTL_EN)mue_csr_write(sc, (sc->mue_flags & 0x0001) ? 0x090 : 0x0c0
, mue_csr_read(sc, (sc->mue_flags & 0x0001) ? 0x090 : 0x0c0
) | (0x80000000))
;
658
659 /* Enable LEDs. */
660 if (sc->mue_product == USB_PRODUCT_SMC2_LAN78000x7800 &&
661 sc->mue_eeprom_present == 0) {
662 MUE_SETBIT(sc, MUE_HW_CFG,mue_csr_write(sc, 0x010, mue_csr_read(sc, 0x010) | (0x00100000
| 0x00200000))
663 MUE_HW_CFG_LED0_EN | MUE_HW_CFG_LED1_EN)mue_csr_write(sc, 0x010, mue_csr_read(sc, 0x010) | (0x00100000
| 0x00200000))
;
664 }
665
666 return (0);
667}
668
669void
670mue_set_macaddr(struct mue_softc *sc)
671{
672 struct ifnet *ifp = &sc->arpcom.ac_if;
673 const uint8_t *eaddr = LLADDR(ifp->if_sadl)((caddr_t)((ifp->if_sadl)->sdl_data + (ifp->if_sadl)
->sdl_nlen))
;
674 uint32_t val, reg;
675
676 reg = (sc->mue_flags & LAN75000x0001) ? MUE_ADDR_FILTX0x300 : MUE_7800_ADDR_FILTX0x400;
677
678 val = (eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) | eaddr[0];
679 mue_csr_write(sc, MUE_RX_ADDRL0x11c, val);
680 mue_csr_write(sc, reg + 4, val);
681 val = (eaddr[5] << 8) | eaddr[4];
682 mue_csr_write(sc, MUE_RX_ADDRH0x118, val);
683 mue_csr_write(sc, reg, val | MUE_ADDR_FILTX_VALID0x80000000);
684}
685
686/*
687 * Probe for a Microchip chip.
688 */
689int
690mue_match(struct device *parent, void *match, void *aux)
691{
692 struct usb_attach_arg *uaa = aux;
693
694 if (uaa->iface == NULL((void *)0) || uaa->configno != 1)
695 return (UMATCH_NONE0);
696
697 return (mue_lookup(uaa->vendor, uaa->product)((struct mue_type *)usbd_match_device((const struct usb_devno
*)(mue_devs), sizeof (mue_devs) / sizeof ((mue_devs)[0]), sizeof
((mue_devs)[0]), (uaa->vendor), (uaa->product)))
!= NULL((void *)0) ?
698 UMATCH_VENDOR_PRODUCT_CONF_IFACE8 : UMATCH_NONE0);
699}
700
701void
702mue_attach(struct device *parent, struct device *self, void *aux)
703{
704 struct mue_softc *sc = (struct mue_softc *)self;
705 struct usb_attach_arg *uaa = aux;
706 usb_interface_descriptor_t *id;
707 usb_endpoint_descriptor_t *ed;
708 struct mii_data *mii;
709 struct ifnet *ifp;
710 int i, s;
711
712 sc->mue_udev = uaa->device;
713 sc->mue_iface = uaa->iface;
714 sc->mue_product = uaa->product;
715 sc->mue_flags = mue_lookup(uaa->vendor, uaa->product)((struct mue_type *)usbd_match_device((const struct usb_devno
*)(mue_devs), sizeof (mue_devs) / sizeof ((mue_devs)[0]), sizeof
((mue_devs)[0]), (uaa->vendor), (uaa->product)))
->mue_flags;
716
717 usb_init_task(&sc->mue_tick_task, mue_tick_task, sc,((&sc->mue_tick_task)->fun = (mue_tick_task), (&
sc->mue_tick_task)->arg = (sc), (&sc->mue_tick_task
)->type = (0), (&sc->mue_tick_task)->state = 0x0
)
718 USB_TASK_TYPE_GENERIC)((&sc->mue_tick_task)->fun = (mue_tick_task), (&
sc->mue_tick_task)->arg = (sc), (&sc->mue_tick_task
)->type = (0), (&sc->mue_tick_task)->state = 0x0
)
;
719 rw_init(&sc->mue_mii_lock, "muemii")_rw_init_flags(&sc->mue_mii_lock, "muemii", 0, ((void *
)0))
;
720 usb_init_task(&sc->mue_stop_task, (void (*)(void *))mue_stop, sc,((&sc->mue_stop_task)->fun = ((void (*)(void *))mue_stop
), (&sc->mue_stop_task)->arg = (sc), (&sc->mue_stop_task
)->type = (0), (&sc->mue_stop_task)->state = 0x0
)
721 USB_TASK_TYPE_GENERIC)((&sc->mue_stop_task)->fun = ((void (*)(void *))mue_stop
), (&sc->mue_stop_task)->arg = (sc), (&sc->mue_stop_task
)->type = (0), (&sc->mue_stop_task)->state = 0x0
)
;
722
723 /* Decide on what our bufsize will be. */
724 if (sc->mue_flags & LAN75000x0001)
1
Assuming the condition is false
2
Taking false branch
725 sc->mue_bufsz = (sc->mue_udev->speed == USB_SPEED_HIGH3) ?
726 MUE_MAX_BUFSZ18944 : MUE_MIN_BUFSZ8256;
727 else
728 sc->mue_bufsz = MUE_7800_BUFSZ12288;
729
730 /* Find endpoints. */
731 id = usbd_get_interface_descriptor(sc->mue_iface);
732 for (i = 0; i < id->bNumEndpoints; i++) {
3
Assuming 'i' is >= field 'bNumEndpoints'
4
Loop condition is false. Execution continues on line 751
733 ed = usbd_interface2endpoint_descriptor(sc->mue_iface, i);
734 if (ed == NULL((void *)0)) {
735 printf("%s: couldn't get ep %d\n",
736 sc->mue_dev.dv_xname, i);
737 return;
738 }
739 if (UE_GET_DIR(ed->bEndpointAddress)((ed->bEndpointAddress) & 0x80) == UE_DIR_IN0x80 &&
740 UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03) == UE_BULK0x02) {
741 sc->mue_ed[MUE_ENDPT_RX0x0] = ed->bEndpointAddress;
742 } else if (UE_GET_DIR(ed->bEndpointAddress)((ed->bEndpointAddress) & 0x80) == UE_DIR_OUT0x00 &&
743 UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03) == UE_BULK0x02) {
744 sc->mue_ed[MUE_ENDPT_TX0x1] = ed->bEndpointAddress;
745 } else if (UE_GET_DIR(ed->bEndpointAddress)((ed->bEndpointAddress) & 0x80) == UE_DIR_IN0x80 &&
746 UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03) == UE_INTERRUPT0x03) {
747 sc->mue_ed[MUE_ENDPT_INTR0x2] = ed->bEndpointAddress;
748 }
749 }
750
751 s = splnet()splraise(0x7);
752
753 sc->mue_phyno = 1;
754
755 /* Check if the EEPROM programmed indicator is present. */
756 mue_read_eeprom(sc, (caddr_t)&i, MUE_EE_IND_OFFSET0x00, 1);
757 sc->mue_eeprom_present = (i
4.1
'i' is not equal to MUE_EEPROM_INDICATOR
== MUE_EEPROM_INDICATOR0xa5) ? 1 : 0;
5
'?' condition is false
758
759 if (mue_chip_init(sc) != 0) {
6
Calling 'mue_chip_init'
760 printf("%s: chip initialization failed\n",
761 sc->mue_dev.dv_xname);
762 splx(s)spllower(s);
763 return;
764 }
765
766 /* Get station address from the EEPROM. */
767 if (sc->mue_eeprom_present) {
768 if (mue_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr,
769 MUE_EE_MAC_OFFSET0x01, ETHER_ADDR_LEN6)) {
770 printf("%s: failed to read station address\n",
771 sc->mue_dev.dv_xname);
772 splx(s)spllower(s);
773 return;
774 }
775 } else
776 mue_enaddr_OF(sc)do {} while(0);
777
778 /* A Microchip chip was detected. Inform the world. */
779 printf("%s:", sc->mue_dev.dv_xname);
780 if (sc->mue_flags & LAN75000x0001)
781 printf(" LAN7500");
782 else
783 printf(" LAN7800");
784 printf(", address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
785
786 /* Initialize interface info.*/
787 ifp = GET_IFP(sc)(&(sc)->arpcom.ac_if);
788 ifp->if_softc = sc;
789 ifp->if_flags = IFF_BROADCAST0x2 | IFF_SIMPLEX0x800 | IFF_MULTICAST0x8000;
790 ifp->if_ioctl = mue_ioctl;
791 ifp->if_start = mue_start;
792 ifp->if_watchdog = mue_watchdog;
793 strlcpy(ifp->if_xname, sc->mue_dev.dv_xname, IFNAMSIZ16);
794
795 ifp->if_capabilitiesif_data.ifi_capabilities = IFCAP_VLAN_MTU0x00000010;
796
797 /* Initialize MII/media info. */
798 mii = GET_MII(sc)(&(sc)->mue_mii);
799 mii->mii_ifp = ifp;
800 mii->mii_readreg = mue_miibus_readreg;
801 mii->mii_writereg = mue_miibus_writereg;
802 mii->mii_statchg = mue_miibus_statchg;
803 mii->mii_flags = MIIF_AUTOTSLEEP0x0010;
804
805 ifmedia_init(&mii->mii_media, 0, mue_ifmedia_upd, mue_ifmedia_sts);
806 mii_attach(self, mii, 0xffffffff, MII_PHY_ANY-1, MII_OFFSET_ANY-1,
807 MIIF_DOPAUSE0x0100);
808
809 if (LIST_FIRST(&mii->mii_phys)((&mii->mii_phys)->lh_first) == NULL((void *)0)) {
810 ifmedia_add(&mii->mii_media, IFM_ETHER0x0000000000000100ULL | IFM_NONE2ULL, 0, NULL((void *)0));
811 ifmedia_set(&mii->mii_media, IFM_ETHER0x0000000000000100ULL | IFM_NONE2ULL);
812 } else
813 ifmedia_set(&mii->mii_media, IFM_ETHER0x0000000000000100ULL | IFM_AUTO0ULL);
814
815 /* Attach the interface. */
816 if_attach(ifp);
817 ether_ifattach(ifp);
818
819 timeout_set(&sc->mue_stat_ch, mue_tick, sc);
820
821 splx(s)spllower(s);
822}
823
824int
825mue_detach(struct device *self, int flags)
826{
827 struct mue_softc *sc = (struct mue_softc *)self;
828 struct ifnet *ifp = GET_IFP(sc)(&(sc)->arpcom.ac_if);
829 int s;
830
831 if (timeout_initialized(&sc->mue_stat_ch)((&sc->mue_stat_ch)->to_flags & 0x04))
832 timeout_del(&sc->mue_stat_ch);
833
834 if (sc->mue_ep[MUE_ENDPT_TX0x1] != NULL((void *)0))
835 usbd_abort_pipe(sc->mue_ep[MUE_ENDPT_TX0x1]);
836 if (sc->mue_ep[MUE_ENDPT_RX0x0] != NULL((void *)0))
837 usbd_abort_pipe(sc->mue_ep[MUE_ENDPT_RX0x0]);
838 if (sc->mue_ep[MUE_ENDPT_INTR0x2] != NULL((void *)0))
839 usbd_abort_pipe(sc->mue_ep[MUE_ENDPT_INTR0x2]);
840
841 /*
842 * Remove any pending tasks. They cannot be executing because they run
843 * in the same thread as detach.
844 */
845 usb_rem_task(sc->mue_udev, &sc->mue_tick_task);
846 usb_rem_task(sc->mue_udev, &sc->mue_stop_task);
847
848 s = splusb()splraise(0x5);
849
850 if (--sc->mue_refcnt >= 0) {
851 /* Wait for processes to go away */
852 usb_detach_wait(&sc->mue_dev);
853 }
854
855 if (ifp->if_flags & IFF_RUNNING0x40)
856 mue_stop(sc);
857
858 mii_detach(&sc->mue_mii, MII_PHY_ANY-1, MII_OFFSET_ANY-1);
859 ifmedia_delete_instance(&sc->mue_mii.mii_media, IFM_INST_ANY((uint64_t) -1));
860 if (ifp->if_softc != NULL((void *)0)) {
861 ether_ifdetach(ifp);
862 if_detach(ifp);
863 }
864
865 splx(s)spllower(s);
866
867 return (0);
868}
869
870int
871mue_rx_list_init(struct mue_softc *sc)
872{
873 struct mue_cdata *cd;
874 struct mue_chain *c;
875 int i;
876
877 DPRINTF(("%s: %s: enter\n", sc->mue_dev.dv_xname, __func__));
878
879 cd = &sc->mue_cdata;
880 for (i = 0; i < MUE_RX_LIST_CNT1; i++) {
881 c = &cd->mue_rx_chain[i];
882 c->mue_sc = sc;
883 c->mue_idx = i;
884 c->mue_mbuf = NULL((void *)0);
885 if (c->mue_xfer == NULL((void *)0)) {
886 c->mue_xfer = usbd_alloc_xfer(sc->mue_udev);
887 if (c->mue_xfer == NULL((void *)0))
888 return (ENOBUFS55);
889 c->mue_buf = usbd_alloc_buffer(c->mue_xfer,
890 sc->mue_bufsz);
891 if (c->mue_buf == NULL((void *)0)) {
892 usbd_free_xfer(c->mue_xfer);
893 return (ENOBUFS55);
894 }
895 }
896 }
897
898 return (0);
899}
900
901int
902mue_tx_list_init(struct mue_softc *sc)
903{
904 struct mue_cdata *cd;
905 struct mue_chain *c;
906 int i;
907
908 DPRINTF(("%s: %s: enter\n", sc->mue_dev.dv_xname, __func__));
909
910 cd = &sc->mue_cdata;
911 for (i = 0; i < MUE_TX_LIST_CNT1; i++) {
912 c = &cd->mue_tx_chain[i];
913 c->mue_sc = sc;
914 c->mue_idx = i;
915 c->mue_mbuf = NULL((void *)0);
916 if (c->mue_xfer == NULL((void *)0)) {
917 c->mue_xfer = usbd_alloc_xfer(sc->mue_udev);
918 if (c->mue_xfer == NULL((void *)0))
919 return (ENOBUFS55);
920 c->mue_buf = usbd_alloc_buffer(c->mue_xfer,
921 sc->mue_bufsz);
922 if (c->mue_buf == NULL((void *)0)) {
923 usbd_free_xfer(c->mue_xfer);
924 return (ENOBUFS55);
925 }
926 }
927 }
928
929 return (0);
930}
931
932int
933mue_open_pipes(struct mue_softc *sc)
934{
935 struct mue_chain *c;
936 usbd_status err;
937 int i;
938
939 /* Open RX and TX pipes. */
940 err = usbd_open_pipe(sc->mue_iface, sc->mue_ed[MUE_ENDPT_RX0x0],
941 USBD_EXCLUSIVE_USE0x01, &sc->mue_ep[MUE_ENDPT_RX0x0]);
942 if (err) {
943 printf("%s: open rx pipe failed: %s\n",
944 sc->mue_dev.dv_xname, usbd_errstr(err));
945 return (EIO5);
946 }
947 err = usbd_open_pipe(sc->mue_iface, sc->mue_ed[MUE_ENDPT_TX0x1],
948 USBD_EXCLUSIVE_USE0x01, &sc->mue_ep[MUE_ENDPT_TX0x1]);
949 if (err) {
950 printf("%s: open tx pipe failed: %s\n",
951 sc->mue_dev.dv_xname, usbd_errstr(err));
952 return (EIO5);
953 }
954
955 /* Start up the receive pipe. */
956 for (i = 0; i < MUE_RX_LIST_CNT1; i++) {
957 c = &sc->mue_cdata.mue_rx_chain[i];
958 usbd_setup_xfer(c->mue_xfer, sc->mue_ep[MUE_ENDPT_RX0x0],
959 c, c->mue_buf, sc->mue_bufsz,
960 USBD_SHORT_XFER_OK0x04 | USBD_NO_COPY0x01, USBD_NO_TIMEOUT0,
961 mue_rxeof);
962 usbd_transfer(c->mue_xfer);
963 }
964
965 return (0);
966}
967
968int
969mue_encap(struct mue_softc *sc, struct mbuf *m, int idx)
970{
971 struct mue_chain *c;
972 usbd_status err;
973 struct mue_txbuf_hdr hdr;
974 int length;
975
976 c = &sc->mue_cdata.mue_tx_chain[idx];
977
978 hdr.tx_cmd_a = htole32((m->m_pkthdr.len & MUE_TX_CMD_A_LEN_MASK) |((__uint32_t)((m->M_dat.MH.MH_pkthdr.len & 0x000fffff)
| 0x00400000))
979 MUE_TX_CMD_A_FCS)((__uint32_t)((m->M_dat.MH.MH_pkthdr.len & 0x000fffff)
| 0x00400000))
;
980 /* Disable segmentation offload. */
981 hdr.tx_cmd_b = htole32(0)((__uint32_t)(0));
982 memcpy(c->mue_buf, &hdr, sizeof(hdr))__builtin_memcpy((c->mue_buf), (&hdr), (sizeof(hdr)));
983 length = sizeof(hdr);
984
985 m_copydata(m, 0, m->m_pkthdrM_dat.MH.MH_pkthdr.len, c->mue_buf + length);
986 length += m->m_pkthdrM_dat.MH.MH_pkthdr.len;
987
988 c->mue_mbuf = m;
989
990 usbd_setup_xfer(c->mue_xfer, sc->mue_ep[MUE_ENDPT_TX0x1],
991 c, c->mue_buf, length, USBD_FORCE_SHORT_XFER0x08 | USBD_NO_COPY0x01,
992 10000, mue_txeof);
993
994 /* Transmit */
995 err = usbd_transfer(c->mue_xfer);
996 if (err != USBD_IN_PROGRESS) {
997 c->mue_mbuf = NULL((void *)0);
998 mue_stop(sc);
999 return(EIO5);
1000 }
1001
1002 sc->mue_cdata.mue_tx_cnt++;
1003
1004 return(0);
1005}
1006
1007void
1008mue_iff(struct mue_softc *sc)
1009{
1010 struct ifnet *ifp = GET_IFP(sc)(&(sc)->arpcom.ac_if);
1011 struct arpcom *ac = &sc->arpcom;
1012 struct ether_multi *enm;
1013 struct ether_multistep step;
1014 uint32_t h = 0, hashtbl[MUE_DP_SEL_VHF_HASH_LEN16], reg, rxfilt;
1015
1016 if (usbd_is_dying(sc->mue_udev))
1017 return;
1018
1019 reg = (sc->mue_flags & LAN75000x0001) ? MUE_RFE_CTL0x060 : MUE_7800_RFE_CTL0x0b0;
1020 rxfilt = mue_csr_read(sc, reg);
1021 rxfilt &= ~(MUE_RFE_CTL_PERFECT0x00000002 | MUE_RFE_CTL_MULTICAST_HASH0x00000008 |
1022 MUE_RFE_CTL_UNICAST0x00000100 | MUE_RFE_CTL_MULTICAST0x00000200);
1023 memset(hashtbl, 0, sizeof(hashtbl))__builtin_memset((hashtbl), (0), (sizeof(hashtbl)));
1024 ifp->if_flags &= ~IFF_ALLMULTI0x200;
1025
1026 /* Always accept broadcast frames. */
1027 rxfilt |= MUE_RFE_CTL_BROADCAST0x00000400;
1028
1029 if (ifp->if_flags & IFF_PROMISC0x100 || ac->ac_multirangecnt > 0) {
1030 ifp->if_flags |= IFF_ALLMULTI0x200;
1031 rxfilt |= MUE_RFE_CTL_MULTICAST0x00000200;
1032 if (ifp->if_flags & IFF_PROMISC0x100)
1033 rxfilt |= MUE_RFE_CTL_UNICAST0x00000100 | MUE_RFE_CTL_MULTICAST0x00000200;
1034 } else {
1035 rxfilt |= MUE_RFE_CTL_PERFECT0x00000002 | MUE_RFE_CTL_MULTICAST_HASH0x00000008;
1036
1037 /* Now program new ones. */
1038 ETHER_FIRST_MULTI(step, ac, enm)do { (step).e_enm = ((&(ac)->ac_multiaddrs)->lh_first
); do { if ((((enm)) = ((step)).e_enm) != ((void *)0)) ((step
)).e_enm = ((((enm)))->enm_list.le_next); } while ( 0); } while
( 0)
;
1039 while (enm != NULL((void *)0)) {
1040 h = ether_crc32_be(enm->enm_addrlo,
1041 ETHER_ADDR_LEN6) >> 23;
1042 hashtbl[h / 32] |= 1 << (h % 32);
1043 ETHER_NEXT_MULTI(step, enm)do { if (((enm) = (step).e_enm) != ((void *)0)) (step).e_enm =
(((enm))->enm_list.le_next); } while ( 0)
;
1044 }
1045 }
1046
1047 mue_dataport_write(sc, MUE_DP_SEL_VHF0x00000001, MUE_DP_SEL_VHF_VLAN_LEN128,
1048 MUE_DP_SEL_VHF_HASH_LEN16, hashtbl);
1049 mue_csr_write(sc, reg, rxfilt);
1050}
1051
1052void
1053mue_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1054{
1055 struct mue_chain *c = (struct mue_chain *)priv;
1056 struct mue_softc *sc = c->mue_sc;
1057 struct ifnet *ifp = GET_IFP(sc)(&(sc)->arpcom.ac_if);
1058 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
1059 struct mbuf *m;
1060 struct mue_rxbuf_hdr hdr;
1061 u_char *buf = c->mue_buf;
1062 uint32_t total_len;
1063 int pktlen = 0;
1064 int s;
1065
1066 if (usbd_is_dying(sc->mue_udev))
1067 return;
1068
1069 if (!(ifp->if_flags & IFF_RUNNING0x40))
1070 return;
1071
1072 if (status != USBD_NORMAL_COMPLETION) {
1073 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1074 return;
1075 if (usbd_ratecheck(&sc->mue_rx_notice)) {
1076 printf("%s: usb errors on rx: %s\n",
1077 sc->mue_dev.dv_xname, usbd_errstr(status));
1078 }
1079 if (status == USBD_STALLED)
1080 usbd_clear_endpoint_stall_async(sc->mue_ep[MUE_ENDPT_RX0x0]);
1081 goto done;
1082 }
1083
1084 usbd_get_xfer_status(xfer, NULL((void *)0), NULL((void *)0), &total_len, NULL((void *)0));
1085
1086 do {
1087 if (total_len < sizeof(hdr)) {
1088 ifp->if_ierrorsif_data.ifi_ierrors++;
1089 goto done;
1090 }
1091
1092 buf += pktlen;
1093
1094 memcpy(&hdr, buf, sizeof(hdr))__builtin_memcpy((&hdr), (buf), (sizeof(hdr)));
1095 total_len -= sizeof(hdr);
1096
1097 if (letoh32(hdr.rx_cmd_a)((__uint32_t)(hdr.rx_cmd_a)) & MUE_RX_CMD_A_RED0x00400000) {
1098 ifp->if_ierrorsif_data.ifi_ierrors++;
1099 goto done;
1100 }
1101
1102 pktlen = letoh32(hdr.rx_cmd_a)((__uint32_t)(hdr.rx_cmd_a)) & MUE_RX_CMD_A_LEN_MASK0x00003fff;
1103 if (sc->mue_flags & LAN75000x0001)
1104 pktlen -= 2;
1105
1106 if (pktlen > total_len) {
1107 ifp->if_ierrorsif_data.ifi_ierrors++;
1108 goto done;
1109 }
1110
1111 buf += sizeof(hdr);
1112
1113 if (total_len < pktlen)
1114 total_len = 0;
1115 else
1116 total_len -= pktlen;
1117
1118 m = m_devget(buf, pktlen - ETHER_CRC_LEN4, ETHER_ALIGN2);
1119 if (m == NULL((void *)0)) {
1120 DPRINTF(("unable to allocate mbuf for next packet\n"));
1121 ifp->if_ierrorsif_data.ifi_ierrors++;
1122 goto done;
1123 }
1124 ml_enqueue(&ml, m);
1125 } while (total_len > 0);
1126
1127done:
1128 s = splnet()splraise(0x7);
1129 if_input(ifp, &ml);
1130 splx(s)spllower(s);
1131
1132 memset(c->mue_buf, 0, sc->mue_bufsz)__builtin_memset((c->mue_buf), (0), (sc->mue_bufsz));
1133
1134 /* Setup new transfer. */
1135 usbd_setup_xfer(xfer, sc->mue_ep[MUE_ENDPT_RX0x0],
1136 c, c->mue_buf, sc->mue_bufsz, USBD_SHORT_XFER_OK0x04 | USBD_NO_COPY0x01,
1137 USBD_NO_TIMEOUT0, mue_rxeof);
1138 usbd_transfer(xfer);
1139
1140 DPRINTFN(10,("%s: %s: start rx\n", sc->mue_dev.dv_xname, __func__));
1141}
1142
1143void
1144mue_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1145{
1146 struct mue_chain *c = priv;
1147 struct mue_softc *sc = c->mue_sc;
1148 struct ifnet *ifp = GET_IFP(sc)(&(sc)->arpcom.ac_if);
1149 int s;
1150
1151 if (usbd_is_dying(sc->mue_udev))
1152 return;
1153
1154 s = splnet()splraise(0x7);
1155
1156 DPRINTFN(10,("%s: %s: enter status=%d\n", sc->mue_dev.dv_xname,
1157 __func__, status));
1158
1159 if (status != USBD_NORMAL_COMPLETION) {
1160 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1161 splx(s)spllower(s);
1162 return;
1163 }
1164 ifp->if_oerrorsif_data.ifi_oerrors++;
1165 printf("%s: usb error on tx: %s\n", sc->mue_dev.dv_xname,
1166 usbd_errstr(status));
1167 if (status == USBD_STALLED)
1168 usbd_clear_endpoint_stall_async(sc->mue_ep[MUE_ENDPT_TX0x1]);
1169 splx(s)spllower(s);
1170 return;
1171 }
1172
1173 ifp->if_timer = 0;
1174 ifq_clr_oactive(&ifp->if_snd);
1175
1176 m_freem(c->mue_mbuf);
1177 c->mue_mbuf = NULL((void *)0);
1178
1179 if (ifq_empty(&ifp->if_snd)(((&ifp->if_snd)->ifq_len) == 0) == 0)
1180 mue_start(ifp);
1181
1182 splx(s)spllower(s);
1183}
1184
1185void
1186mue_init(void *xsc)
1187{
1188 struct mue_softc *sc = xsc;
1189 struct ifnet *ifp = GET_IFP(sc)(&(sc)->arpcom.ac_if);
1190 int s;
1191
1192 s = splnet()splraise(0x7);
1193
1194 /* Cancel pending I/O and free all TX/RX buffers. */
1195 mue_reset(sc);
1196
1197 /* Set MAC address. */
1198 mue_set_macaddr(sc);
1199
1200 /* Init RX ring. */
1201 if (mue_rx_list_init(sc) == ENOBUFS55) {
1202 printf("%s: rx list init failed\n", sc->mue_dev.dv_xname);
1203 splx(s)spllower(s);
1204 return;
1205 }
1206
1207 /* Init TX ring. */
1208 if (mue_tx_list_init(sc) == ENOBUFS55) {
1209 printf("%s: tx list init failed\n", sc->mue_dev.dv_xname);
1210 splx(s)spllower(s);
1211 return;
1212 }
1213
1214 /* Program promiscuous mode and multicast filters. */
1215 mue_iff(sc);
1216
1217 if (mue_open_pipes(sc) != 0) {
1218 splx(s)spllower(s);
1219 return;
1220 }
1221
1222 sc->mue_link = 0;
1223 ifp->if_flags |= IFF_RUNNING0x40;
1224 ifq_clr_oactive(&ifp->if_snd);
1225
1226 splx(s)spllower(s);
1227
1228 timeout_add_sec(&sc->mue_stat_ch, 1);
1229}
1230
1231int
1232mue_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1233{
1234 struct mue_softc *sc = ifp->if_softc;
1235 struct ifreq *ifr = (struct ifreq *)data;
1236 int s, error = 0;
1237
1238 s = splnet()splraise(0x7);
1239
1240 switch(cmd) {
1241 case SIOCSIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((12)))
:
1242 ifp->if_flags |= IFF_UP0x1;
1243 if (!(ifp->if_flags & IFF_RUNNING0x40))
1244 mue_init(sc);
1245 break;
1246 case SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
:
1247 if (ifp->if_flags & IFF_UP0x1) {
1248 if (ifp->if_flags & IFF_RUNNING0x40)
1249 error = ENETRESET52;
1250 else
1251 mue_init(sc);
1252 } else {
1253 if (ifp->if_flags & IFF_RUNNING0x40)
1254 mue_stop(sc);
1255 }
1256 break;
1257 case SIOCGIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifmediareq) & 0x1fff) << 16) | ((('i')) <<
8) | ((56)))
:
1258 case SIOCSIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((55)))
:
1259 error = ifmedia_ioctl(ifp, ifr, &sc->mue_mii.mii_media, cmd);
1260 break;
1261 default:
1262 error = ether_ioctl(ifp, &sc->arpcom, cmd, data);
1263 }
1264
1265 if (error == ENETRESET52) {
1266 if (ifp->if_flags & IFF_RUNNING0x40)
1267 mue_iff(sc);
1268 error = 0;
1269 }
1270
1271 splx(s)spllower(s);
1272
1273 return(error);
1274}
1275
1276void
1277mue_watchdog(struct ifnet *ifp)
1278{
1279 struct mue_softc *sc = ifp->if_softc;
1280 struct mue_chain *c;
1281 usbd_status stat;
1282 int s;
1283
1284 ifp->if_oerrorsif_data.ifi_oerrors++;
1285 printf("%s: watchdog timeout\n", sc->mue_dev.dv_xname);
1286
1287 s = splusb()splraise(0x5);
1288 c = &sc->mue_cdata.mue_tx_chain[0];
1289 usbd_get_xfer_status(c->mue_xfer, NULL((void *)0), NULL((void *)0), NULL((void *)0), &stat);
1290 mue_txeof(c->mue_xfer, c, stat);
1291
1292 if (!ifq_empty(&ifp->if_snd)(((&ifp->if_snd)->ifq_len) == 0))
1293 mue_start(ifp);
1294 splx(s)spllower(s);
1295}
1296
1297void
1298mue_reset(struct mue_softc *sc)
1299{
1300 if (usbd_is_dying(sc->mue_udev))
1301 return;
1302
1303 /* Wait a little while for the chip to get its brains in order. */
1304 DELAY(1000)(*delay_func)(1000);
1305}
1306
1307void
1308mue_start(struct ifnet *ifp)
1309{
1310 struct mue_softc *sc = ifp->if_softc;
1311 struct mbuf *m_head = NULL((void *)0);
1312
1313 if (!sc->mue_link)
1314 return;
1315
1316 if (ifq_is_oactive(&ifp->if_snd))
1317 return;
1318
1319 m_head = ifq_dequeue(&ifp->if_snd);
1320 if (m_head == NULL((void *)0))
1321 return;
1322
1323 if (mue_encap(sc, m_head, 0)) {
1324 m_freem(m_head);
1325 ifq_set_oactive(&ifp->if_snd);
1326 return;
1327 }
1328
1329 /* If there's a BPF listener, bounce a copy of this frame to him. */
1330#if NBPFILTER1 > 0
1331 if (ifp->if_bpf)
1332 bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT(1 << 1));
1333#endif
1334
1335 ifq_set_oactive(&ifp->if_snd);
1336
1337 /* Set a timeout in case the chip goes out to lunch. */
1338 ifp->if_timer = 5;
1339}
1340
1341void
1342mue_stop(struct mue_softc *sc)
1343{
1344 struct ifnet *ifp;
1345 usbd_status err;
1346 int i;
1347
1348 ifp = GET_IFP(sc)(&(sc)->arpcom.ac_if);
1349 ifp->if_timer = 0;
1350 ifp->if_flags &= ~IFF_RUNNING0x40;
1351 ifq_clr_oactive(&ifp->if_snd);
1352
1353 timeout_del(&sc->mue_stat_ch);
1354
1355 /* Stop transfers. */
1356 if (sc->mue_ep[MUE_ENDPT_RX0x0] != NULL((void *)0)) {
1357 err = usbd_close_pipe(sc->mue_ep[MUE_ENDPT_RX0x0]);
1358 if (err) {
1359 printf("%s: close rx pipe failed: %s\n",
1360 sc->mue_dev.dv_xname, usbd_errstr(err));
1361 }
1362 sc->mue_ep[MUE_ENDPT_RX0x0] = NULL((void *)0);
1363 }
1364
1365 if (sc->mue_ep[MUE_ENDPT_TX0x1] != NULL((void *)0)) {
1366 err = usbd_close_pipe(sc->mue_ep[MUE_ENDPT_TX0x1]);
1367 if (err) {
1368 printf("%s: close tx pipe failed: %s\n",
1369 sc->mue_dev.dv_xname, usbd_errstr(err));
1370 }
1371 sc->mue_ep[MUE_ENDPT_TX0x1] = NULL((void *)0);
1372 }
1373
1374 if (sc->mue_ep[MUE_ENDPT_INTR0x2] != NULL((void *)0)) {
1375 err = usbd_close_pipe(sc->mue_ep[MUE_ENDPT_INTR0x2]);
1376 if (err) {
1377 printf("%s: close intr pipe failed: %s\n",
1378 sc->mue_dev.dv_xname, usbd_errstr(err));
1379 }
1380 sc->mue_ep[MUE_ENDPT_INTR0x2] = NULL((void *)0);
1381 }
1382
1383 /* Free RX resources. */
1384 for (i = 0; i < MUE_RX_LIST_CNT1; i++) {
1385 if (sc->mue_cdata.mue_rx_chain[i].mue_mbuf != NULL((void *)0)) {
1386 m_freem(sc->mue_cdata.mue_rx_chain[i].mue_mbuf);
1387 sc->mue_cdata.mue_rx_chain[i].mue_mbuf = NULL((void *)0);
1388 }
1389 if (sc->mue_cdata.mue_rx_chain[i].mue_xfer != NULL((void *)0)) {
1390 usbd_free_xfer(sc->mue_cdata.mue_rx_chain[i].mue_xfer);
1391 sc->mue_cdata.mue_rx_chain[i].mue_xfer = NULL((void *)0);
1392 }
1393 }
1394
1395 /* Free TX resources. */
1396 for (i = 0; i < MUE_TX_LIST_CNT1; i++) {
1397 if (sc->mue_cdata.mue_tx_chain[i].mue_mbuf != NULL((void *)0)) {
1398 m_freem(sc->mue_cdata.mue_tx_chain[i].mue_mbuf);
1399 sc->mue_cdata.mue_tx_chain[i].mue_mbuf = NULL((void *)0);
1400 }
1401 if (sc->mue_cdata.mue_tx_chain[i].mue_xfer != NULL((void *)0)) {
1402 usbd_free_xfer(sc->mue_cdata.mue_tx_chain[i].mue_xfer);
1403 sc->mue_cdata.mue_tx_chain[i].mue_xfer = NULL((void *)0);
1404 }
1405 }
1406
1407 sc->mue_link = 0;
1408}
1409
1410void
1411mue_tick(void *xsc)
1412{
1413 struct mue_softc *sc = xsc;
1414
1415 if (sc == NULL((void *)0))
1416 return;
1417
1418 if (usbd_is_dying(sc->mue_udev))
1419 return;
1420
1421 /* Perform periodic stuff in process context. */
1422 usb_add_task(sc->mue_udev, &sc->mue_tick_task);
1423}
1424
1425void
1426mue_tick_task(void *xsc)
1427{
1428 struct mue_softc *sc =xsc;
1429 struct mii_data *mii;
1430 int s;
1431
1432 if (sc == NULL((void *)0))
1433 return;
1434
1435 if (usbd_is_dying(sc->mue_udev))
1436 return;
1437
1438 mii = GET_MII(sc)(&(sc)->mue_mii);
1439
1440 s = splnet()splraise(0x7);
1441 mii_tick(mii);
1442 if (sc->mue_link == 0)
1443 mue_miibus_statchg(&sc->mue_dev);
1444 timeout_add_sec(&sc->mue_stat_ch, 1);
1445 splx(s)spllower(s);
1446}