Annotation of src/sys/dev/usb/if_mue.c, Revision 1.18
1.18 ! rin 1: /* $NetBSD: if_mue.c,v 1.17 2018/09/16 01:56:29 rin Exp $ */
1.1 rin 2: /* $OpenBSD: if_mue.c,v 1.3 2018/08/04 16:42:46 jsg Exp $ */
3:
4: /*
5: * Copyright (c) 2018 Kevin Lo <kevlo@openbsd.org>
6: *
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
9: * copyright notice and this permission notice appear in all copies.
10: *
11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
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
17: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18: */
19:
20: /* Driver for Microchip LAN7500/LAN7800 chipsets. */
21:
22: #include <sys/cdefs.h>
1.18 ! rin 23: __KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.17 2018/09/16 01:56:29 rin Exp $");
1.1 rin 24:
25: #ifdef _KERNEL_OPT
26: #include "opt_usb.h"
27: #include "opt_inet.h"
28: #endif
29:
30: #include <sys/param.h>
31: #include <sys/cprng.h>
32: #include <sys/bus.h>
33: #include <sys/systm.h>
34: #include <sys/sockio.h>
35: #include <sys/mbuf.h>
36: #include <sys/mutex.h>
37: #include <sys/kernel.h>
38: #include <sys/proc.h>
39: #include <sys/socket.h>
40:
41: #include <sys/device.h>
42:
43: #include <sys/rndsource.h>
44:
45: #include <net/if.h>
46: #include <net/if_dl.h>
47: #include <net/if_media.h>
48: #include <net/if_ether.h>
49:
50: #include <net/bpf.h>
51:
1.3 rin 52: #include <netinet/if_inarp.h>
1.1 rin 53: #include <netinet/in.h>
1.3 rin 54: #include <netinet/ip.h> /* XXX for struct ip */
55: #include <netinet/ip6.h> /* XXX for struct ip6_hdr */
1.1 rin 56:
57: #include <dev/mii/mii.h>
58: #include <dev/mii/miivar.h>
59:
60: #include <dev/usb/usb.h>
61: #include <dev/usb/usbdi.h>
62: #include <dev/usb/usbdi_util.h>
63: #include <dev/usb/usbdivar.h>
64: #include <dev/usb/usbdevs.h>
65:
66: #include <dev/usb/if_muereg.h>
67: #include <dev/usb/if_muevar.h>
68:
69: #define MUE_PRINTF(sc, fmt, args...) \
70: device_printf((sc)->mue_dev, "%s: " fmt, __func__, ##args);
71:
72: #ifdef USB_DEBUG
73: int muedebug = 0;
74: #define DPRINTF(sc, fmt, args...) \
75: do { \
76: if (muedebug) \
77: MUE_PRINTF(sc, fmt, ##args); \
78: } while (0 /* CONSTCOND */)
79: #else
80: #define DPRINTF(sc, fmt, args...) /* nothing */
81: #endif
82:
83: /*
84: * Various supported device vendors/products.
85: */
86: struct mue_type {
87: struct usb_devno mue_dev;
88: uint16_t mue_flags;
89: #define LAN7500 0x0001 /* LAN7500 */
90: };
91:
92: const struct mue_type mue_devs[] = {
93: { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7500 }, LAN7500 },
94: { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7505 }, LAN7500 },
95: { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7800 }, 0 },
96: { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7801 }, 0 },
97: { { USB_VENDOR_SMSC, USB_PRODUCT_SMSC_LAN7850 }, 0 }
98: };
99:
100: #define MUE_LOOKUP(uaa) ((const struct mue_type *)usb_lookup(mue_devs, \
101: uaa->uaa_vendor, uaa->uaa_product))
102:
103: #define MUE_ENADDR_LO(enaddr) \
104: ((enaddr[3] << 24) | (enaddr[2] << 16) | (enaddr[1] << 8) | enaddr[0])
105: #define MUE_ENADDR_HI(enaddr) \
106: ((enaddr[5] << 8) | enaddr[4])
107:
108: static int mue_match(device_t, cfdata_t, void *);
109: static void mue_attach(device_t, device_t, void *);
110: static int mue_detach(device_t, int);
111: static int mue_activate(device_t, enum devact);
112:
113: static uint32_t mue_csr_read(struct mue_softc *, uint32_t);
114: static int mue_csr_write(struct mue_softc *, uint32_t, uint32_t);
115: static int mue_wait_for_bits(struct mue_softc *sc, uint32_t, uint32_t,
116: uint32_t, uint32_t);
117:
118: static void mue_lock_mii(struct mue_softc *);
119: static void mue_unlock_mii(struct mue_softc *);
120:
121: static int mue_miibus_readreg(device_t, int, int);
122: static void mue_miibus_writereg(device_t, int, int, int);
123: static void mue_miibus_statchg(struct ifnet *);
124: static int mue_ifmedia_upd(struct ifnet *);
125: static void mue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
126:
127: static uint8_t mue_eeprom_getbyte(struct mue_softc *, int, uint8_t *);
128: static int mue_read_eeprom(struct mue_softc *, uint8_t *, int, int);
129: static bool mue_eeprom_present(struct mue_softc *sc);
130:
131: static int mue_read_otp_raw(struct mue_softc *, uint8_t *, int, int);
132: static int mue_read_otp(struct mue_softc *, uint8_t *, int, int);
133:
134: static void mue_dataport_write(struct mue_softc *, uint32_t, uint32_t,
135: uint32_t, uint32_t *);
136:
137: static void mue_init_ltm(struct mue_softc *);
138:
139: static int mue_chip_init(struct mue_softc *);
140:
141: static void mue_set_macaddr(struct mue_softc *);
142: static int mue_get_macaddr(struct mue_softc *, prop_dictionary_t);
143:
144: static int mue_rx_list_init(struct mue_softc *);
145: static int mue_tx_list_init(struct mue_softc *);
146: static int mue_open_pipes(struct mue_softc *);
1.18 ! rin 147: static void mue_startup_rx_pipes(struct mue_softc *);
1.1 rin 148:
149: static int mue_encap(struct mue_softc *, struct mbuf *, int);
1.3 rin 150: static void mue_tx_offload(struct mue_softc *, struct mbuf *);
1.1 rin 151:
152: static void mue_setmulti(struct mue_softc *);
153: static void mue_sethwcsum(struct mue_softc *);
154:
155: static void mue_rxeof(struct usbd_xfer *, void *, usbd_status);
156: static void mue_txeof(struct usbd_xfer *, void *, usbd_status);
157:
158: static int mue_init(struct ifnet *);
159: static int mue_ioctl(struct ifnet *, u_long, void *);
160: static void mue_watchdog(struct ifnet *);
161: static void mue_reset(struct mue_softc *);
162: static void mue_start(struct ifnet *);
163: static void mue_stop(struct ifnet *, int);
164: static void mue_tick(void *);
165: static void mue_tick_task(void *);
166:
167: static struct mbuf *mue_newbuf(void);
168:
169: #define MUE_SETBIT(sc, reg, x) \
170: mue_csr_write(sc, reg, mue_csr_read(sc, reg) | (x))
171:
172: #define MUE_CLRBIT(sc, reg, x) \
173: mue_csr_write(sc, reg, mue_csr_read(sc, reg) & ~(x))
174:
175: #define MUE_WAIT_SET(sc, reg, set, fail) \
176: mue_wait_for_bits(sc, reg, set, ~0, fail)
177:
178: #define MUE_WAIT_CLR(sc, reg, clear, fail) \
179: mue_wait_for_bits(sc, reg, 0, clear, fail)
180:
181: #define ETHER_IS_VALID(addr) \
182: (!ETHER_IS_MULTICAST(addr) && !ETHER_IS_ZERO(addr))
183:
184: #define ETHER_IS_ZERO(addr) \
185: (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]))
186:
187: #define ETHER_ALIGN 2
188:
189: CFATTACH_DECL_NEW(mue, sizeof(struct mue_softc), mue_match, mue_attach,
190: mue_detach, mue_activate);
191:
192: static uint32_t
193: mue_csr_read(struct mue_softc *sc, uint32_t reg)
194: {
195: usb_device_request_t req;
196: usbd_status err;
197: uDWord val;
198:
199: if (sc->mue_dying)
200: return 0;
201:
202: USETDW(val, 0);
203: req.bmRequestType = UT_READ_VENDOR_DEVICE;
204: req.bRequest = MUE_UR_READREG;
205: USETW(req.wValue, 0);
206: USETW(req.wIndex, reg);
207: USETW(req.wLength, 4);
208:
209: err = usbd_do_request(sc->mue_udev, &req, &val);
210: if (err) {
211: MUE_PRINTF(sc, "reg = 0x%x: %s\n", reg, usbd_errstr(err));
212: return 0;
213: }
214:
215: return UGETDW(val);
216: }
217:
218: static int
219: mue_csr_write(struct mue_softc *sc, uint32_t reg, uint32_t aval)
220: {
221: usb_device_request_t req;
222: usbd_status err;
223: uDWord val;
224:
225: if (sc->mue_dying)
226: return 0;
227:
228: USETDW(val, aval);
229: req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
230: req.bRequest = MUE_UR_WRITEREG;
231: USETW(req.wValue, 0);
232: USETW(req.wIndex, reg);
233: USETW(req.wLength, 4);
234:
235: err = usbd_do_request(sc->mue_udev, &req, &val);
236: if (err) {
237: MUE_PRINTF(sc, "reg = 0x%x: %s\n", reg, usbd_errstr(err));
238: return -1;
239: }
240:
241: return 0;
242: }
243:
244: static int
245: mue_wait_for_bits(struct mue_softc *sc, uint32_t reg,
246: uint32_t set, uint32_t clear, uint32_t fail)
247: {
248: uint32_t val;
249: int ntries;
250:
251: for (ntries = 0; ntries < 1000; ntries++) {
252: val = mue_csr_read(sc, reg);
253: if ((val & set) || !(val & clear))
254: return 0;
255: if (val & fail)
256: return 1;
257: usbd_delay_ms(sc->mue_udev, 1);
258: }
259:
260: return 1;
261: }
262:
263: /*
264: * Get exclusive access to the MII registers.
265: */
266: static void
267: mue_lock_mii(struct mue_softc *sc)
268: {
269: sc->mue_refcnt++;
270: mutex_enter(&sc->mue_mii_lock);
271: }
272:
273: static void
274: mue_unlock_mii(struct mue_softc *sc)
275: {
276: mutex_exit(&sc->mue_mii_lock);
277: if (--sc->mue_refcnt < 0)
278: usb_detach_wakeupold(sc->mue_dev);
279: }
280:
281: static int
282: mue_miibus_readreg(device_t dev, int phy, int reg)
283: {
284: struct mue_softc *sc = device_private(dev);
285: uint32_t val;
286:
287: if (sc->mue_dying) {
288: DPRINTF(sc, "dying\n");
289: return 0;
290: }
291:
292: if (sc->mue_phyno != phy)
293: return 0;
294:
295: mue_lock_mii(sc);
296: if (MUE_WAIT_CLR(sc, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) {
297: mue_unlock_mii(sc);
298: MUE_PRINTF(sc, "not ready\n");
299: return -1;
300: }
301:
302: mue_csr_write(sc, MUE_MII_ACCESS, MUE_MII_ACCESS_READ |
303: MUE_MII_ACCESS_BUSY | MUE_MII_ACCESS_REGADDR(reg) |
304: MUE_MII_ACCESS_PHYADDR(phy));
305:
306: if (MUE_WAIT_CLR(sc, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) {
307: mue_unlock_mii(sc);
308: MUE_PRINTF(sc, "timed out\n");
309: return -1;
310: }
311:
312: val = mue_csr_read(sc, MUE_MII_DATA);
313: mue_unlock_mii(sc);
314: return val & 0xffff;
315: }
316:
317: static void
318: mue_miibus_writereg(device_t dev, int phy, int reg, int data)
319: {
320: struct mue_softc *sc = device_private(dev);
321:
322: if (sc->mue_dying) {
323: DPRINTF(sc, "dying\n");
324: return;
325: }
326:
327: if (sc->mue_phyno != phy) {
328: DPRINTF(sc, "sc->mue_phyno (%d) != phy (%d)\n",
329: sc->mue_phyno, phy);
330: return;
331: }
332:
333: mue_lock_mii(sc);
334: if (MUE_WAIT_CLR(sc, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0)) {
335: mue_unlock_mii(sc);
336: MUE_PRINTF(sc, "not ready\n");
337: return;
338: }
339:
340: mue_csr_write(sc, MUE_MII_DATA, data);
341: mue_csr_write(sc, MUE_MII_ACCESS, MUE_MII_ACCESS_WRITE |
342: MUE_MII_ACCESS_BUSY | MUE_MII_ACCESS_REGADDR(reg) |
343: MUE_MII_ACCESS_PHYADDR(phy));
344:
345: if (MUE_WAIT_CLR(sc, MUE_MII_ACCESS, MUE_MII_ACCESS_BUSY, 0))
346: MUE_PRINTF(sc, "timed out\n");
347:
348: mue_unlock_mii(sc);
349: }
350:
351: static void
352: mue_miibus_statchg(struct ifnet *ifp)
353: {
354: struct mue_softc *sc = ifp->if_softc;
355: struct mii_data *mii = GET_MII(sc);
356: uint32_t flow, threshold;
357:
358: if (mii == NULL || ifp == NULL || (ifp->if_flags & IFF_RUNNING) == 0) {
359: DPRINTF(sc, "not ready\n");
360: return;
361: }
362:
363: sc->mue_link = 0;
364: if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
365: (IFM_ACTIVE | IFM_AVALID)) {
366: switch (IFM_SUBTYPE(mii->mii_media_active)) {
367: case IFM_10_T:
368: case IFM_100_TX:
369: case IFM_1000_T:
370: sc->mue_link++;
371: break;
372: default:
373: break;
374: }
375: }
376:
377: /* Lost link, do nothing. */
378: if (sc->mue_link == 0) {
379: DPRINTF(sc, "mii_media_status = 0x%x\n", mii->mii_media_status);
380: return;
381: }
382:
383: if (!(sc->mue_flags & LAN7500)) {
384: if (sc->mue_udev->ud_speed == USB_SPEED_SUPER) {
385: if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
386: /* Disable U2 and enable U1. */
387: MUE_CLRBIT(sc, MUE_USB_CFG1,
388: MUE_USB_CFG1_DEV_U2_INIT_EN);
389: MUE_SETBIT(sc, MUE_USB_CFG1,
390: MUE_USB_CFG1_DEV_U1_INIT_EN);
391: } else {
392: /* Enable U1 and U2. */
393: MUE_SETBIT(sc, MUE_USB_CFG1,
394: MUE_USB_CFG1_DEV_U1_INIT_EN |
395: MUE_USB_CFG1_DEV_U2_INIT_EN);
396: }
397: }
398: }
399:
400: flow = 0;
401: /* XXX Linux does not check IFM_FDX flag for 7800. */
402: if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) {
403: if (IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE)
404: flow |= MUE_FLOW_TX_FCEN | MUE_FLOW_PAUSE_TIME;
405: if (IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE)
406: flow |= MUE_FLOW_RX_FCEN;
407: }
408:
409: /* XXX Magic numbers taken from Linux driver. */
410: if (sc->mue_flags & LAN7500)
411: threshold = 0x820;
412: else
413: switch (sc->mue_udev->ud_speed) {
414: case USB_SPEED_SUPER:
415: threshold = 0x817;
416: break;
417: case USB_SPEED_HIGH:
418: threshold = 0x211;
419: break;
420: default:
421: threshold = 0;
422: break;
423: }
424:
425: /* Threshold value should be set before enabling flow. */
426: mue_csr_write(sc, (sc->mue_flags & LAN7500) ?
427: MUE_7500_FCT_FLOW : MUE_7800_FCT_FLOW, threshold);
428: mue_csr_write(sc, MUE_FLOW, flow);
429:
430: DPRINTF(sc, "done\n");
431: }
432:
433: /*
434: * Set media options.
435: */
436: static int
437: mue_ifmedia_upd(struct ifnet *ifp)
438: {
439: struct mue_softc *sc = ifp->if_softc;
440: struct mii_data *mii = GET_MII(sc);
441:
442: sc->mue_link = 0; /* XXX */
443:
444: if (mii->mii_instance) {
445: struct mii_softc *miisc;
446: LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
447: mii_phy_reset(miisc);
448: }
449: return mii_mediachg(mii);
450: }
451:
452: /*
453: * Report current media status.
454: */
455: static void
456: mue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
457: {
458: struct mue_softc *sc = ifp->if_softc;
459: struct mii_data *mii = GET_MII(sc);
460:
461: mii_pollstat(mii);
462: ifmr->ifm_active = mii->mii_media_active;
463: ifmr->ifm_status = mii->mii_media_status;
464: }
465:
466: static uint8_t
467: mue_eeprom_getbyte(struct mue_softc *sc, int off, uint8_t *dest)
468: {
469: uint32_t val;
470:
471: if (MUE_WAIT_CLR(sc, MUE_E2P_CMD, MUE_E2P_CMD_BUSY, 0)) {
472: MUE_PRINTF(sc, "not ready\n");
473: return ETIMEDOUT;
474: }
475:
1.17 rin 476: KASSERT((off & ~MUE_E2P_CMD_ADDR_MASK) == 0);
1.1 rin 477: mue_csr_write(sc, MUE_E2P_CMD, MUE_E2P_CMD_READ | MUE_E2P_CMD_BUSY |
1.17 rin 478: off);
1.1 rin 479:
480: if (MUE_WAIT_CLR(sc, MUE_E2P_CMD, MUE_E2P_CMD_BUSY,
481: MUE_E2P_CMD_TIMEOUT)) {
482: MUE_PRINTF(sc, "timed out\n");
483: return ETIMEDOUT;
484: }
485:
486: val = mue_csr_read(sc, MUE_E2P_DATA);
487: *dest = val & 0xff;
488:
489: return 0;
490: }
491:
492: static int
493: mue_read_eeprom(struct mue_softc *sc, uint8_t *dest, int off, int cnt)
494: {
495: uint32_t val = 0; /* XXX gcc */
496: uint8_t byte;
497: int i, err;
498:
499: /*
500: * EEPROM pins are muxed with the LED function on LAN7800 device.
501: */
502: if (sc->mue_product == USB_PRODUCT_SMSC_LAN7800) {
503: val = mue_csr_read(sc, MUE_HW_CFG);
504: mue_csr_write(sc, MUE_HW_CFG,
505: val & ~(MUE_HW_CFG_LED0_EN | MUE_HW_CFG_LED1_EN));
506: }
507:
508: for (i = 0; i < cnt; i++) {
509: err = mue_eeprom_getbyte(sc, off + i, &byte);
510: if (err)
511: break;
512: *(dest + i) = byte;
513: }
514:
515: if (sc->mue_product == USB_PRODUCT_SMSC_LAN7800)
516: mue_csr_write(sc, MUE_HW_CFG, val);
517:
518: return err ? 1 : 0;
519: }
520:
521: static bool
522: mue_eeprom_present(struct mue_softc *sc)
523: {
524: uint32_t val;
525: uint8_t sig;
526: int ret;
527:
528: if (sc->mue_flags & LAN7500) {
529: val = mue_csr_read(sc, MUE_E2P_CMD);
530: return val & MUE_E2P_CMD_LOADED;
531: } else {
532: ret = mue_read_eeprom(sc, &sig, MUE_E2P_IND_OFFSET, 1);
533: return (ret == 0) && (sig == MUE_E2P_IND);
534: }
535: }
536:
537: static int
538: mue_read_otp_raw(struct mue_softc *sc, uint8_t *dest, int off, int cnt)
539: {
540: uint32_t val;
541: int i, err;
542:
543: val = mue_csr_read(sc, MUE_OTP_PWR_DN);
544:
545: /* Checking if bit is set. */
546: if (val & MUE_OTP_PWR_DN_PWRDN_N) {
547: /* Clear it, then wait for it to be cleared. */
548: mue_csr_write(sc, MUE_OTP_PWR_DN, 0);
549: err = MUE_WAIT_CLR(sc, MUE_OTP_PWR_DN, MUE_OTP_PWR_DN_PWRDN_N,
550: 0);
551: if (err) {
552: MUE_PRINTF(sc, "not ready\n");
553: return 1;
554: }
555: }
556:
557: /* Start reading the bytes, one at a time. */
558: for (i = 0; i < cnt; i++) {
559: mue_csr_write(sc, MUE_OTP_ADDR1,
560: ((off + i) >> 8) & MUE_OTP_ADDR1_MASK);
561: mue_csr_write(sc, MUE_OTP_ADDR2,
562: ((off + i) & MUE_OTP_ADDR2_MASK));
563: mue_csr_write(sc, MUE_OTP_FUNC_CMD, MUE_OTP_FUNC_CMD_READ);
564: mue_csr_write(sc, MUE_OTP_CMD_GO, MUE_OTP_CMD_GO_GO);
565:
566: err = MUE_WAIT_CLR(sc, MUE_OTP_STATUS, MUE_OTP_STATUS_BUSY, 0);
567: if (err) {
568: MUE_PRINTF(sc, "timed out\n");
569: return 1;
570: }
571: val = mue_csr_read(sc, MUE_OTP_RD_DATA);
572: *(dest + i) = (uint8_t)(val & 0xff);
573: }
574:
575: return 0;
576: }
577:
578: static int
579: mue_read_otp(struct mue_softc *sc, uint8_t *dest, int off, int cnt)
580: {
581: uint8_t sig;
582: int err;
583:
584: if (sc->mue_flags & LAN7500)
585: return 1;
586:
587: err = mue_read_otp_raw(sc, &sig, MUE_OTP_IND_OFFSET, 1);
588: if (err)
589: return 1;
590: switch (sig) {
591: case MUE_OTP_IND_1:
592: break;
593: case MUE_OTP_IND_2:
594: off += 0x100;
595: break;
596: default:
597: DPRINTF(sc, "OTP not found\n");
598: return 1;
599: }
600: err = mue_read_otp_raw(sc, dest, off, cnt);
601: return err;
602: }
603:
604: static void
605: mue_dataport_write(struct mue_softc *sc, uint32_t sel, uint32_t addr,
606: uint32_t cnt, uint32_t *data)
607: {
608: uint32_t i;
609:
610: if (MUE_WAIT_SET(sc, MUE_DP_SEL, MUE_DP_SEL_DPRDY, 0)) {
611: MUE_PRINTF(sc, "not ready\n");
612: return;
613: }
614:
615: mue_csr_write(sc, MUE_DP_SEL,
616: (mue_csr_read(sc, MUE_DP_SEL) & ~MUE_DP_SEL_RSEL_MASK) | sel);
617:
618: for (i = 0; i < cnt; i++) {
619: mue_csr_write(sc, MUE_DP_ADDR, addr + i);
620: mue_csr_write(sc, MUE_DP_DATA, data[i]);
621: mue_csr_write(sc, MUE_DP_CMD, MUE_DP_CMD_WRITE);
622: if (MUE_WAIT_SET(sc, MUE_DP_SEL, MUE_DP_SEL_DPRDY, 0)) {
623: MUE_PRINTF(sc, "timed out\n");
624: return;
625: }
626: }
627: }
628:
629: static void
630: mue_init_ltm(struct mue_softc *sc)
631: {
632: uint32_t idx[MUE_NUM_LTM_INDEX] = { 0, 0, 0, 0, 0, 0 };
633: uint8_t temp[2];
634: size_t i;
635:
636: if (mue_csr_read(sc, MUE_USB_CFG1) & MUE_USB_CFG1_LTM_ENABLE) {
637: if (mue_eeprom_present(sc) &&
638: (mue_read_eeprom(sc, temp, MUE_E2P_LTM_OFFSET, 2) == 0)) {
639: if (temp[0] != sizeof(idx)) {
640: DPRINTF(sc, "EEPROM: unexpected size\n");
641: goto done;
642: }
643: if (mue_read_eeprom(sc, (uint8_t *)idx, temp[1] << 1,
644: sizeof(idx))) {
1.9 rin 645: DPRINTF(sc, "EEPROM: failed to read\n");
1.1 rin 646: goto done;
647: }
648: DPRINTF(sc, "success\n");
649: } else if (mue_read_otp(sc, temp, MUE_E2P_LTM_OFFSET, 2) == 0) {
650: if (temp[0] != sizeof(idx)) {
651: DPRINTF(sc, "OTP: unexpected size\n");
652: goto done;
653: }
654: if (mue_read_otp(sc, (uint8_t *)idx, temp[1] << 1,
655: sizeof(idx))) {
1.9 rin 656: DPRINTF(sc, "OTP: failed to read\n");
1.1 rin 657: goto done;
658: }
659: DPRINTF(sc, "success\n");
660: } else {
661: DPRINTF(sc, "nothing to do\n");
662: }
663: } else {
664: DPRINTF(sc, "nothing to do\n");
665: }
666: done:
667: for (i = 0; i < __arraycount(idx); i++)
668: mue_csr_write(sc, MUE_LTM_INDEX(i), idx[i]);
669: }
670:
671: static int
672: mue_chip_init(struct mue_softc *sc)
673: {
674: uint32_t val;
675:
676: if ((sc->mue_flags & LAN7500) &&
677: MUE_WAIT_SET(sc, MUE_PMT_CTL, MUE_PMT_CTL_READY, 0)) {
678: MUE_PRINTF(sc, "not ready\n");
679: return ETIMEDOUT;
680: }
681:
682: MUE_SETBIT(sc, MUE_HW_CFG, MUE_HW_CFG_LRST);
683: if (MUE_WAIT_CLR(sc, MUE_HW_CFG, MUE_HW_CFG_LRST, 0)) {
684: MUE_PRINTF(sc, "timed out\n");
685: return ETIMEDOUT;
686: }
687:
688: /* Respond to the IN token with a NAK. */
689: if (sc->mue_flags & LAN7500)
690: MUE_SETBIT(sc, MUE_HW_CFG, MUE_HW_CFG_BIR);
691: else
692: MUE_SETBIT(sc, MUE_USB_CFG0, MUE_USB_CFG0_BIR);
693:
694: if (sc->mue_flags & LAN7500) {
695: if (sc->mue_udev->ud_speed == USB_SPEED_HIGH)
1.3 rin 696: val = MUE_7500_HS_RX_BUFSIZE /
1.1 rin 697: MUE_HS_USB_PKT_SIZE;
698: else
1.3 rin 699: val = MUE_7500_FS_RX_BUFSIZE /
1.1 rin 700: MUE_FS_USB_PKT_SIZE;
701: mue_csr_write(sc, MUE_7500_BURST_CAP, val);
702: mue_csr_write(sc, MUE_7500_BULKIN_DELAY,
703: MUE_7500_DEFAULT_BULKIN_DELAY);
704:
705: MUE_SETBIT(sc, MUE_HW_CFG, MUE_HW_CFG_BCE | MUE_HW_CFG_MEF);
706:
707: /* Set FIFO sizes. */
708: val = (MUE_7500_MAX_RX_FIFO_SIZE - 512) / 512;
709: mue_csr_write(sc, MUE_7500_FCT_RX_FIFO_END, val);
710: val = (MUE_7500_MAX_TX_FIFO_SIZE - 512) / 512;
711: mue_csr_write(sc, MUE_7500_FCT_TX_FIFO_END, val);
712: } else {
713: /* Init LTM. */
714: mue_init_ltm(sc);
715:
1.3 rin 716: val = MUE_7800_RX_BUFSIZE;
1.1 rin 717: switch (sc->mue_udev->ud_speed) {
718: case USB_SPEED_SUPER:
719: val /= MUE_SS_USB_PKT_SIZE;
720: break;
721: case USB_SPEED_HIGH:
722: val /= MUE_HS_USB_PKT_SIZE;
723: break;
724: default:
725: val /= MUE_FS_USB_PKT_SIZE;
726: break;
727: }
728: mue_csr_write(sc, MUE_7800_BURST_CAP, val);
729: mue_csr_write(sc, MUE_7800_BULKIN_DELAY,
730: MUE_7800_DEFAULT_BULKIN_DELAY);
731:
732: MUE_SETBIT(sc, MUE_HW_CFG, MUE_HW_CFG_MEF);
733: MUE_SETBIT(sc, MUE_USB_CFG0, MUE_USB_CFG0_BCE);
734:
735: /*
736: * Set FCL's RX and TX FIFO sizes: according to data sheet this
737: * is already the default value. But we initialize it to the
738: * same value anyways, as that's what the Linux driver does.
739: */
740: val = (MUE_7800_MAX_RX_FIFO_SIZE - 512) / 512;
741: mue_csr_write(sc, MUE_7800_FCT_RX_FIFO_END, val);
742: val = (MUE_7800_MAX_TX_FIFO_SIZE - 512) / 512;
743: mue_csr_write(sc, MUE_7800_FCT_TX_FIFO_END, val);
744: }
745:
746: /* Enabling interrupts. */
747: mue_csr_write(sc, MUE_INT_STATUS, ~0);
748:
749: mue_csr_write(sc, (sc->mue_flags & LAN7500) ?
750: MUE_7500_FCT_FLOW : MUE_7800_FCT_FLOW, 0);
751: mue_csr_write(sc, MUE_FLOW, 0);
752:
753: /* Reset PHY. */
754: MUE_SETBIT(sc, MUE_PMT_CTL, MUE_PMT_CTL_PHY_RST);
755: if (MUE_WAIT_CLR(sc, MUE_PMT_CTL, MUE_PMT_CTL_PHY_RST, 0)) {
756: MUE_PRINTF(sc, "PHY not ready\n");
757: return ETIMEDOUT;
758: }
759:
760: /* LAN7801 only has RGMII mode. */
761: if (sc->mue_product == USB_PRODUCT_SMSC_LAN7801)
762: MUE_CLRBIT(sc, MUE_MAC_CR, MUE_MAC_CR_GMII_EN);
763:
764: if ((sc->mue_flags & LAN7500) ||
765: (sc->mue_product == USB_PRODUCT_SMSC_LAN7800 &&
766: !mue_eeprom_present(sc))) {
767: /* Allow MAC to detect speed and duplex from PHY. */
768: MUE_SETBIT(sc, MUE_MAC_CR, MUE_MAC_CR_AUTO_SPEED |
769: MUE_MAC_CR_AUTO_DUPLEX);
770: }
771:
772: MUE_SETBIT(sc, MUE_MAC_TX, MUE_MAC_TX_TXEN);
773: MUE_SETBIT(sc, (sc->mue_flags & LAN7500) ?
774: MUE_7500_FCT_TX_CTL : MUE_7800_FCT_TX_CTL, MUE_FCT_TX_CTL_EN);
775:
776: /* Set the maximum frame size. */
777: MUE_CLRBIT(sc, MUE_MAC_RX, MUE_MAC_RX_RXEN);
778: val = mue_csr_read(sc, MUE_MAC_RX);
779: val &= ~MUE_MAC_RX_MAX_SIZE_MASK;
1.11 rin 780: val |= MUE_MAC_RX_MAX_LEN(ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN);
1.1 rin 781: mue_csr_write(sc, MUE_MAC_RX, val);
782: MUE_SETBIT(sc, MUE_MAC_RX, MUE_MAC_RX_RXEN);
783:
784: MUE_SETBIT(sc, (sc->mue_flags & LAN7500) ?
785: MUE_7500_FCT_RX_CTL : MUE_7800_FCT_RX_CTL, MUE_FCT_RX_CTL_EN);
786:
787: /* Set default GPIO/LED settings only if no EEPROM is detected. */
788: if ((sc->mue_flags & LAN7500) && !mue_eeprom_present(sc)) {
789: MUE_CLRBIT(sc, MUE_LED_CFG, MUE_LED_CFG_LED10_FUN_SEL);
790: MUE_SETBIT(sc, MUE_LED_CFG,
791: MUE_LED_CFG_LEDGPIO_EN | MUE_LED_CFG_LED2_FUN_SEL);
792: }
793:
794: /* XXX We assume two LEDs at least when EEPROM is missing. */
795: if (sc->mue_product == USB_PRODUCT_SMSC_LAN7800 &&
796: !mue_eeprom_present(sc))
797: MUE_SETBIT(sc, MUE_HW_CFG,
798: MUE_HW_CFG_LED0_EN | MUE_HW_CFG_LED1_EN);
799:
800: return 0;
801: }
802:
803: static void
804: mue_set_macaddr(struct mue_softc *sc)
805: {
806: struct ifnet *ifp = GET_IFP(sc);
807: const uint8_t *enaddr = CLLADDR(ifp->if_sadl);
808: uint32_t lo, hi;
809:
810: lo = MUE_ENADDR_LO(enaddr);
811: hi = MUE_ENADDR_HI(enaddr);
812:
813: mue_csr_write(sc, MUE_RX_ADDRL, lo);
814: mue_csr_write(sc, MUE_RX_ADDRH, hi);
815: }
816:
817: static int
818: mue_get_macaddr(struct mue_softc *sc, prop_dictionary_t dict)
819: {
820: prop_data_t eaprop;
821: uint32_t low, high;
822:
823: if (!(sc->mue_flags & LAN7500)) {
824: low = mue_csr_read(sc, MUE_RX_ADDRL);
825: high = mue_csr_read(sc, MUE_RX_ADDRH);
826: sc->mue_enaddr[5] = (uint8_t)((high >> 8) & 0xff);
827: sc->mue_enaddr[4] = (uint8_t)((high) & 0xff);
828: sc->mue_enaddr[3] = (uint8_t)((low >> 24) & 0xff);
829: sc->mue_enaddr[2] = (uint8_t)((low >> 16) & 0xff);
830: sc->mue_enaddr[1] = (uint8_t)((low >> 8) & 0xff);
831: sc->mue_enaddr[0] = (uint8_t)((low) & 0xff);
832: if (ETHER_IS_VALID(sc->mue_enaddr))
833: return 0;
834: else {
835: DPRINTF(sc, "registers: %s\n",
836: ether_sprintf(sc->mue_enaddr));
837: }
838: }
839:
840: if (mue_eeprom_present(sc) && !mue_read_eeprom(sc, sc->mue_enaddr,
841: MUE_E2P_MAC_OFFSET, ETHER_ADDR_LEN)) {
842: if (ETHER_IS_VALID(sc->mue_enaddr))
843: return 0;
844: else {
845: DPRINTF(sc, "EEPROM: %s\n",
846: ether_sprintf(sc->mue_enaddr));
847: }
848: }
849:
850: if (mue_read_otp(sc, sc->mue_enaddr, MUE_OTP_MAC_OFFSET,
851: ETHER_ADDR_LEN) == 0) {
852: if (ETHER_IS_VALID(sc->mue_enaddr))
853: return 0;
854: else {
855: DPRINTF(sc, "OTP: %s\n",
856: ether_sprintf(sc->mue_enaddr));
857: }
858: }
859:
860: /*
861: * Other MD methods. This should be tried only if other methods fail.
862: * Otherwise, MAC address for internal device can be assinged to
863: * external devices on Raspberry Pi, for example.
864: */
865: eaprop = prop_dictionary_get(dict, "mac-address");
866: if (eaprop != NULL) {
867: KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA);
868: KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN);
869: memcpy(sc->mue_enaddr, prop_data_data_nocopy(eaprop),
870: ETHER_ADDR_LEN);
871: if (ETHER_IS_VALID(sc->mue_enaddr))
872: return 0;
873: else {
874: DPRINTF(sc, "prop_dictionary_get: %s\n",
875: ether_sprintf(sc->mue_enaddr));
876: }
877: }
878:
879: return 1;
880: }
881:
882:
883: /*
884: * Probe for a Microchip chip. */
885: static int
886: mue_match(device_t parent, cfdata_t match, void *aux)
887: {
888: struct usb_attach_arg *uaa = aux;
889:
890: return (MUE_LOOKUP(uaa) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
891: }
892:
893: static void
894: mue_attach(device_t parent, device_t self, void *aux)
895: {
896: struct mue_softc *sc = device_private(self);
897: prop_dictionary_t dict = device_properties(self);
898: struct usb_attach_arg *uaa = aux;
899: struct usbd_device *dev = uaa->uaa_device;
900: usb_interface_descriptor_t *id;
901: usb_endpoint_descriptor_t *ed;
902: char *devinfop;
903: struct mii_data *mii;
904: struct ifnet *ifp;
905: usbd_status err;
1.8 rin 906: uint8_t i;
907: int s;
1.1 rin 908:
909: aprint_naive("\n");
910: aprint_normal("\n");
911:
912: sc->mue_dev = self;
913: sc->mue_udev = dev;
914:
915: devinfop = usbd_devinfo_alloc(sc->mue_udev, 0);
916: aprint_normal_dev(self, "%s\n", devinfop);
917: usbd_devinfo_free(devinfop);
918:
919: #define MUE_CONFIG_NO 1
920: err = usbd_set_config_no(dev, MUE_CONFIG_NO, 1);
921: if (err) {
922: aprint_error_dev(self, "failed to set configuration: %s\n",
923: usbd_errstr(err));
924: return;
925: }
926:
927: mutex_init(&sc->mue_mii_lock, MUTEX_DEFAULT, IPL_NONE);
928: usb_init_task(&sc->mue_tick_task, mue_tick_task, sc, 0);
929: usb_init_task(&sc->mue_stop_task, (void (*)(void *))mue_stop, sc, 0);
930:
931: #define MUE_IFACE_IDX 0
932: err = usbd_device2interface_handle(dev, MUE_IFACE_IDX, &sc->mue_iface);
933: if (err) {
934: aprint_error_dev(self, "failed to get interface handle: %s\n",
935: usbd_errstr(err));
936: return;
937: }
938:
939: sc->mue_product = uaa->uaa_product;
940: sc->mue_flags = MUE_LOOKUP(uaa)->mue_flags;
941:
942: /* Decide on what our bufsize will be. */
943: if (sc->mue_flags & LAN7500)
1.3 rin 944: sc->mue_rxbufsz = (sc->mue_udev->ud_speed == USB_SPEED_HIGH) ?
945: MUE_7500_HS_RX_BUFSIZE : MUE_7500_FS_RX_BUFSIZE;
1.1 rin 946: else
1.3 rin 947: sc->mue_rxbufsz = MUE_7800_RX_BUFSIZE;
948: sc->mue_txbufsz = MUE_TX_BUFSIZE;
1.1 rin 949:
950: /* Find endpoints. */
951: id = usbd_get_interface_descriptor(sc->mue_iface);
952: for (i = 0; i < id->bNumEndpoints; i++) {
953: ed = usbd_interface2endpoint_descriptor(sc->mue_iface, i);
954: if (ed == NULL) {
1.8 rin 955: aprint_error_dev(self, "failed to get ep %hhd\n", i);
1.1 rin 956: return;
957: }
958: if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
959: UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
960: sc->mue_ed[MUE_ENDPT_RX] = ed->bEndpointAddress;
961: } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
962: UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
963: sc->mue_ed[MUE_ENDPT_TX] = ed->bEndpointAddress;
964: } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
965: UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
966: sc->mue_ed[MUE_ENDPT_INTR] = ed->bEndpointAddress;
967: }
968: }
969: KASSERT(sc->mue_ed[MUE_ENDPT_RX] != 0);
970: KASSERT(sc->mue_ed[MUE_ENDPT_TX] != 0);
971: KASSERT(sc->mue_ed[MUE_ENDPT_INTR] != 0);
972:
973: s = splnet();
974:
975: sc->mue_phyno = 1;
976:
977: if (mue_chip_init(sc)) {
1.9 rin 978: aprint_error_dev(self, "failed to initialize chip\n");
1.1 rin 979: splx(s);
980: return;
981: }
982:
983: /* A Microchip chip was detected. Inform the world. */
984: if (sc->mue_flags & LAN7500)
985: aprint_normal_dev(self, "LAN7500\n");
986: else
987: aprint_normal_dev(self, "LAN7800\n");
988:
989: if (mue_get_macaddr(sc, dict)) {
990: aprint_error_dev(self, "Ethernet address assigned randomly\n");
991: cprng_fast(sc->mue_enaddr, ETHER_ADDR_LEN);
992: sc->mue_enaddr[0] &= ~0x01; /* unicast */
993: sc->mue_enaddr[0] |= 0x02; /* locally administered */
994: }
995:
996: aprint_normal_dev(self, "Ethernet address %s\n",
997: ether_sprintf(sc->mue_enaddr));
998:
999: /* Initialize interface info.*/
1000: ifp = GET_IFP(sc);
1001: ifp->if_softc = sc;
1002: strlcpy(ifp->if_xname, device_xname(sc->mue_dev), IFNAMSIZ);
1003: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1004: ifp->if_init = mue_init;
1005: ifp->if_ioctl = mue_ioctl;
1006: ifp->if_start = mue_start;
1007: ifp->if_stop = mue_stop;
1008: ifp->if_watchdog = mue_watchdog;
1009:
1010: IFQ_SET_READY(&ifp->if_snd);
1011:
1.3 rin 1012: ifp->if_capabilities = IFCAP_TSOv4 | IFCAP_TSOv6;
1013:
1.1 rin 1014: sc->mue_ec.ec_capabilities = ETHERCAP_VLAN_MTU;
1015:
1016: /* Initialize MII/media info. */
1017: mii = GET_MII(sc);
1018: mii->mii_ifp = ifp;
1019: mii->mii_readreg = mue_miibus_readreg;
1020: mii->mii_writereg = mue_miibus_writereg;
1021: mii->mii_statchg = mue_miibus_statchg;
1022: mii->mii_flags = MIIF_AUTOTSLEEP;
1023:
1024: sc->mue_ec.ec_mii = mii;
1025: ifmedia_init(&mii->mii_media, 0, mue_ifmedia_upd, mue_ifmedia_sts);
1026: mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
1027:
1028: if (LIST_FIRST(&mii->mii_phys) == NULL) {
1029: ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
1030: ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
1031: } else
1032: ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
1033:
1034: /* Attach the interface. */
1035: if_attach(ifp);
1036: ether_ifattach(ifp, sc->mue_enaddr);
1037:
1038: rnd_attach_source(&sc->mue_rnd_source, device_xname(sc->mue_dev),
1039: RND_TYPE_NET, RND_FLAG_DEFAULT);
1040:
1041: callout_init(&sc->mue_stat_ch, 0);
1042:
1043: splx(s);
1044:
1045: usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->mue_udev, sc->mue_dev);
1046: }
1047:
1048: static int
1049: mue_detach(device_t self, int flags)
1050: {
1051: struct mue_softc *sc = device_private(self);
1052: struct ifnet *ifp = GET_IFP(sc);
1053: size_t i;
1054: int s;
1055:
1056: sc->mue_dying = true;
1057:
1058: callout_halt(&sc->mue_stat_ch, NULL);
1059:
1060: for (i = 0; i < __arraycount(sc->mue_ep); i++)
1061: if (sc->mue_ep[i] != NULL)
1062: usbd_abort_pipe(sc->mue_ep[i]);
1063:
1064: /*
1.7 rin 1065: * Remove any pending tasks. They cannot be executing because they run
1.1 rin 1066: * in the same thread as detach.
1067: */
1068: usb_rem_task_wait(sc->mue_udev, &sc->mue_tick_task, USB_TASKQ_DRIVER,
1069: NULL);
1070: usb_rem_task_wait(sc->mue_udev, &sc->mue_stop_task, USB_TASKQ_DRIVER,
1071: NULL);
1072:
1073: s = splusb();
1074:
1075: if (ifp->if_flags & IFF_RUNNING)
1076: mue_stop(ifp, 1);
1077:
1078: rnd_detach_source(&sc->mue_rnd_source);
1079: mii_detach(&sc->mue_mii, MII_PHY_ANY, MII_OFFSET_ANY);
1080: ifmedia_delete_instance(&sc->mue_mii.mii_media, IFM_INST_ANY);
1081: if (ifp->if_softc != NULL) {
1082: ether_ifdetach(ifp);
1083: if_detach(ifp);
1084: }
1085:
1086: if (--sc->mue_refcnt >= 0) {
1087: /* Wait for processes to go away. */
1088: usb_detach_waitold(sc->mue_dev);
1089: }
1090: splx(s);
1091:
1092: usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->mue_udev, sc->mue_dev);
1093:
1094: mutex_destroy(&sc->mue_mii_lock);
1095:
1096: return 0;
1097: }
1098:
1099: static int
1100: mue_activate(device_t self, enum devact act)
1101: {
1102: struct mue_softc *sc = device_private(self);
1103: struct ifnet *ifp = GET_IFP(sc);
1104:
1105: switch (act) {
1106: case DVACT_DEACTIVATE:
1107: if_deactivate(ifp);
1108: sc->mue_dying = true;
1109: return 0;
1110: default:
1111: return EOPNOTSUPP;
1112: }
1113: return 0;
1114: }
1115:
1116: static int
1117: mue_rx_list_init(struct mue_softc *sc)
1118: {
1119: struct mue_cdata *cd;
1120: struct mue_chain *c;
1121: size_t i;
1122: int err;
1123:
1124: cd = &sc->mue_cdata;
1125: for (i = 0; i < __arraycount(cd->mue_rx_chain); i++) {
1126: c = &cd->mue_rx_chain[i];
1127: c->mue_sc = sc;
1128: c->mue_idx = i;
1129: if (c->mue_xfer == NULL) {
1130: err = usbd_create_xfer(sc->mue_ep[MUE_ENDPT_RX],
1.3 rin 1131: sc->mue_rxbufsz, 0, 0, &c->mue_xfer);
1.1 rin 1132: if (err)
1133: return err;
1134: c->mue_buf = usbd_get_buffer(c->mue_xfer);
1135: }
1136: }
1137:
1138: return 0;
1139: }
1140:
1141: static int
1142: mue_tx_list_init(struct mue_softc *sc)
1143: {
1144: struct mue_cdata *cd;
1145: struct mue_chain *c;
1146: size_t i;
1147: int err;
1148:
1149: cd = &sc->mue_cdata;
1150: for (i = 0; i < __arraycount(cd->mue_tx_chain); i++) {
1151: c = &cd->mue_tx_chain[i];
1152: c->mue_sc = sc;
1153: c->mue_idx = i;
1154: if (c->mue_xfer == NULL) {
1155: err = usbd_create_xfer(sc->mue_ep[MUE_ENDPT_TX],
1.3 rin 1156: sc->mue_txbufsz, USBD_FORCE_SHORT_XFER, 0,
1.1 rin 1157: &c->mue_xfer);
1158: if (err)
1159: return err;
1160: c->mue_buf = usbd_get_buffer(c->mue_xfer);
1161: }
1162: }
1163:
1164: return 0;
1165: }
1166:
1167: static int
1168: mue_open_pipes(struct mue_softc *sc)
1169: {
1170: usbd_status err;
1171:
1172: /* Open RX and TX pipes. */
1173: err = usbd_open_pipe(sc->mue_iface, sc->mue_ed[MUE_ENDPT_RX],
1174: USBD_EXCLUSIVE_USE, &sc->mue_ep[MUE_ENDPT_RX]);
1175: if (err) {
1176: MUE_PRINTF(sc, "rx pipe: %s\n", usbd_errstr(err));
1177: return EIO;
1178: }
1179: err = usbd_open_pipe(sc->mue_iface, sc->mue_ed[MUE_ENDPT_TX],
1180: USBD_EXCLUSIVE_USE, &sc->mue_ep[MUE_ENDPT_TX]);
1181: if (err) {
1182: MUE_PRINTF(sc, "tx pipe: %s\n", usbd_errstr(err));
1183: return EIO;
1184: }
1185: return 0;
1186: }
1187:
1188: static void
1.18 ! rin 1189: mue_startup_rx_pipes(struct mue_softc *sc)
1.1 rin 1190: {
1191: struct mue_chain *c;
1192: size_t i;
1193:
1194: /* Start up the receive pipe. */
1195: for (i = 0; i < __arraycount(sc->mue_cdata.mue_rx_chain); i++) {
1196: c = &sc->mue_cdata.mue_rx_chain[i];
1.3 rin 1197: usbd_setup_xfer(c->mue_xfer, c, c->mue_buf, sc->mue_rxbufsz,
1.1 rin 1198: USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, mue_rxeof);
1199: usbd_transfer(c->mue_xfer);
1200: }
1201: }
1202:
1203: static int
1204: mue_encap(struct mue_softc *sc, struct mbuf *m, int idx)
1205: {
1206: struct ifnet *ifp = GET_IFP(sc);
1207: struct mue_chain *c;
1208: usbd_status err;
1209: struct mue_txbuf_hdr hdr;
1.12 rin 1210: uint32_t tx_cmd_a, tx_cmd_b;
1.1 rin 1211: int len;
1.12 rin 1212: bool tso;
1213:
1214: tso = m->m_pkthdr.csum_flags & (M_CSUM_TSOv4 | M_CSUM_TSOv6);
1215:
1216: len = m->m_pkthdr.len;
1217: if (__predict_false((!tso && len > MUE_MAX_TX_LEN) ||
1218: ( tso && len > MUE_MAX_TSO_LEN))) {
1219: MUE_PRINTF(sc, "packet length %d\n too long", len);
1220: return EINVAL;
1221: }
1.1 rin 1222:
1223: c = &sc->mue_cdata.mue_tx_chain[idx];
1224:
1.12 rin 1225: KASSERT((len & ~MUE_TX_CMD_A_LEN_MASK) == 0);
1226: tx_cmd_a = len | MUE_TX_CMD_A_FCS;
1.3 rin 1227:
1.12 rin 1228: if (tso) {
1229: tx_cmd_a |= MUE_TX_CMD_A_LSO;
1.3 rin 1230: if (__predict_true(m->m_pkthdr.segsz > MUE_TX_MSS_MIN))
1.12 rin 1231: tx_cmd_b = m->m_pkthdr.segsz;
1.3 rin 1232: else
1.12 rin 1233: tx_cmd_b = MUE_TX_MSS_MIN;
1234: tx_cmd_b <<= MUE_TX_CMD_B_MSS_SHIFT;
1235: KASSERT((tx_cmd_b & ~MUE_TX_CMD_B_MSS_MASK) == 0);
1.3 rin 1236: mue_tx_offload(sc, m);
1237: } else
1.12 rin 1238: tx_cmd_b = 0;
1239:
1240: hdr.tx_cmd_a = htole32(tx_cmd_a);
1241: hdr.tx_cmd_b = htole32(tx_cmd_b);
1.3 rin 1242:
1.1 rin 1243: memcpy(c->mue_buf, &hdr, sizeof(hdr));
1.12 rin 1244: m_copydata(m, 0, len, c->mue_buf + sizeof(hdr));
1.1 rin 1245:
1.12 rin 1246: usbd_setup_xfer(c->mue_xfer, c, c->mue_buf, len + sizeof(hdr),
1.1 rin 1247: USBD_FORCE_SHORT_XFER, 10000, mue_txeof);
1248:
1249: /* Transmit */
1250: err = usbd_transfer(c->mue_xfer);
1251: if (__predict_false(err != USBD_IN_PROGRESS)) {
1.12 rin 1252: MUE_PRINTF(sc, "%s\n", usbd_errstr(err));
1.1 rin 1253: mue_stop(ifp, 0);
1254: return EIO;
1255: }
1256:
1257: sc->mue_cdata.mue_tx_cnt++;
1258:
1259: return 0;
1260: }
1261:
1262: static void
1.3 rin 1263: mue_tx_offload(struct mue_softc *sc, struct mbuf *m)
1264: {
1265: struct ether_header *eh;
1266: struct ip *ip;
1267: struct ip6_hdr *ip6;
1.18 ! rin 1268: int off;
1.3 rin 1269:
1270: eh = mtod(m, struct ether_header *);
1271: switch (htons(eh->ether_type)) {
1272: case ETHERTYPE_IP:
1273: case ETHERTYPE_IPV6:
1.18 ! rin 1274: off = ETHER_HDR_LEN;
1.3 rin 1275: break;
1276: case ETHERTYPE_VLAN:
1277: /* XXX not yet supported */
1.18 ! rin 1278: off = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
1.3 rin 1279: break;
1280: default:
1281: /* XXX */
1282: panic("%s: unsupported ethertype\n", __func__);
1283: /* NOTREACHED */
1284: }
1285:
1286: /* Packet length should be cleared. */
1.13 rin 1287: if (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) {
1.18 ! rin 1288: ip = (void *)(mtod(m, char *) + off);
1.3 rin 1289: ip->ip_len = 0;
1290: } else {
1.18 ! rin 1291: ip6 = (void *)(mtod(m, char *) + off);
1.3 rin 1292: ip6->ip6_plen = 0;
1293: }
1294: }
1295:
1296: static void
1.1 rin 1297: mue_setmulti(struct mue_softc *sc)
1298: {
1299: struct ifnet *ifp = GET_IFP(sc);
1300: const uint8_t *enaddr = CLLADDR(ifp->if_sadl);
1301: struct ether_multi *enm;
1302: struct ether_multistep step;
1303: uint32_t pfiltbl[MUE_NUM_ADDR_FILTX][2];
1304: uint32_t hashtbl[MUE_DP_SEL_VHF_HASH_LEN];
1305: uint32_t reg, rxfilt, h, hireg, loreg;
1.8 rin 1306: size_t i;
1.1 rin 1307:
1308: if (sc->mue_dying)
1309: return;
1310:
1311: /* Clear perfect filter and hash tables. */
1312: memset(pfiltbl, 0, sizeof(pfiltbl));
1313: memset(hashtbl, 0, sizeof(hashtbl));
1314:
1315: reg = (sc->mue_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL;
1316: rxfilt = mue_csr_read(sc, reg);
1317: rxfilt &= ~(MUE_RFE_CTL_PERFECT | MUE_RFE_CTL_MULTICAST_HASH |
1318: MUE_RFE_CTL_UNICAST | MUE_RFE_CTL_MULTICAST);
1319:
1320: /* Always accept broadcast frames. */
1321: rxfilt |= MUE_RFE_CTL_BROADCAST;
1322:
1323: if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
1324: allmulti: rxfilt |= MUE_RFE_CTL_MULTICAST;
1325: if (ifp->if_flags & IFF_PROMISC) {
1326: rxfilt |= MUE_RFE_CTL_UNICAST;
1327: DPRINTF(sc, "promisc\n");
1328: } else {
1329: DPRINTF(sc, "allmulti\n");
1330: }
1331: } else {
1332: /* Now program new ones. */
1333: pfiltbl[0][0] = MUE_ENADDR_HI(enaddr) | MUE_ADDR_FILTX_VALID;
1334: pfiltbl[0][1] = MUE_ENADDR_LO(enaddr);
1335: i = 1;
1336: ETHER_FIRST_MULTI(step, &sc->mue_ec, enm);
1337: while (enm != NULL) {
1338: if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1339: ETHER_ADDR_LEN)) {
1340: memset(pfiltbl, 0, sizeof(pfiltbl));
1341: memset(hashtbl, 0, sizeof(hashtbl));
1342: rxfilt &= ~MUE_RFE_CTL_MULTICAST_HASH;
1343: goto allmulti;
1344: }
1345: if (i < MUE_NUM_ADDR_FILTX) {
1346: /* Use perfect address table if possible. */
1347: pfiltbl[i][0] = MUE_ENADDR_HI(enm->enm_addrlo) |
1348: MUE_ADDR_FILTX_VALID;
1349: pfiltbl[i][1] = MUE_ENADDR_LO(enm->enm_addrlo);
1350: } else {
1351: /* Otherwise, use hash table. */
1352: rxfilt |= MUE_RFE_CTL_MULTICAST_HASH;
1353: h = (ether_crc32_be(enm->enm_addrlo,
1354: ETHER_ADDR_LEN) >> 23) & 0x1ff;
1355: hashtbl[h / 32] |= 1 << (h % 32);
1356: }
1357: i++;
1358: ETHER_NEXT_MULTI(step, enm);
1359: }
1360: rxfilt |= MUE_RFE_CTL_PERFECT;
1361: if (rxfilt & MUE_RFE_CTL_MULTICAST_HASH) {
1362: DPRINTF(sc, "perfect filter and hash tables\n");
1363: } else {
1364: DPRINTF(sc, "perfect filter\n");
1365: }
1366: }
1367:
1368: for (i = 0; i < MUE_NUM_ADDR_FILTX; i++) {
1369: hireg = (sc->mue_flags & LAN7500) ?
1370: MUE_7500_ADDR_FILTX(i) : MUE_7800_ADDR_FILTX(i);
1371: loreg = hireg + 4;
1372: mue_csr_write(sc, hireg, 0);
1373: mue_csr_write(sc, loreg, pfiltbl[i][1]);
1374: mue_csr_write(sc, hireg, pfiltbl[i][0]);
1375: }
1376:
1377: mue_dataport_write(sc, MUE_DP_SEL_VHF, MUE_DP_SEL_VHF_VLAN_LEN,
1378: MUE_DP_SEL_VHF_HASH_LEN, hashtbl);
1379:
1380: mue_csr_write(sc, reg, rxfilt);
1381: }
1382:
1383: static void
1384: mue_sethwcsum(struct mue_softc *sc)
1385: {
1386: struct ifnet *ifp = GET_IFP(sc);
1387: uint32_t reg, val;
1388:
1389: reg = (sc->mue_flags & LAN7500) ? MUE_7500_RFE_CTL : MUE_7800_RFE_CTL;
1390: val = mue_csr_read(sc, reg);
1391:
1.2 rin 1392: if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx|IFCAP_CSUM_UDPv4_Rx)) {
1.1 rin 1393: DPRINTF(sc, "enabled\n");;
1394: val |= MUE_RFE_CTL_IGMP_COE | MUE_RFE_CTL_ICMP_COE;
1395: val |= MUE_RFE_CTL_TCPUDP_COE | MUE_RFE_CTL_IP_COE;
1396: } else {
1397: DPRINTF(sc, "disabled\n");;
1398: val &=
1399: ~(MUE_RFE_CTL_IGMP_COE | MUE_RFE_CTL_ICMP_COE);
1400: val &=
1401: ~(MUE_RFE_CTL_TCPUDP_COE | MUE_RFE_CTL_IP_COE);
1402: }
1403:
1404: val &= ~MUE_RFE_CTL_VLAN_FILTER;
1405:
1406: mue_csr_write(sc, reg, val);
1407: }
1408:
1409:
1410: static void
1411: mue_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1412: {
1413: struct mue_chain *c = (struct mue_chain *)priv;
1414: struct mue_softc *sc = c->mue_sc;
1415: struct ifnet *ifp = GET_IFP(sc);
1416: struct mbuf *m;
1417: struct mue_rxbuf_hdr *hdrp;
1.15 rin 1418: uint32_t rx_cmd_a, totlen;
1.1 rin 1419: uint16_t pktlen;
1420: int s;
1421: char *buf = c->mue_buf;
1422:
1423: if (__predict_false(sc->mue_dying)) {
1424: DPRINTF(sc, "dying\n");
1425: return;
1426: }
1427:
1428: if (__predict_false(!(ifp->if_flags & IFF_RUNNING))) {
1429: DPRINTF(sc, "not running\n");
1430: return;
1431: }
1432:
1433: if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
1434: DPRINTF(sc, "%s\n", usbd_errstr(status));
1435: if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1436: return;
1437: if (usbd_ratecheck(&sc->mue_rx_notice))
1438: MUE_PRINTF(sc, "%s\n", usbd_errstr(status));
1439: if (status == USBD_STALLED)
1440: usbd_clear_endpoint_stall_async(
1441: sc->mue_ep[MUE_ENDPT_RX]);
1442: goto done;
1443: }
1444:
1.15 rin 1445: usbd_get_xfer_status(xfer, NULL, NULL, &totlen, NULL);
1.1 rin 1446:
1.16 rin 1447: KASSERTMSG(totlen <= sc->mue_rxbufsz, "%u vs %u",
1.15 rin 1448: totlen, sc->mue_rxbufsz);
1.1 rin 1449:
1450: do {
1.15 rin 1451: if (__predict_false(totlen < sizeof(*hdrp))) {
1452: MUE_PRINTF(sc, "packet length %u too short\n", totlen);
1.1 rin 1453: ifp->if_ierrors++;
1454: goto done;
1455: }
1456:
1457: hdrp = (struct mue_rxbuf_hdr *)buf;
1458: rx_cmd_a = le32toh(hdrp->rx_cmd_a);
1459:
1460: if (__predict_false(rx_cmd_a & MUE_RX_CMD_A_RED)) {
1.9 rin 1461: MUE_PRINTF(sc, "rx_cmd_a: 0x%x\n", rx_cmd_a);
1.1 rin 1462: ifp->if_ierrors++;
1463: goto done;
1464: }
1465:
1466: /* XXX not yet */
1467: KASSERT((rx_cmd_a & MUE_RX_CMD_A_ICSM) == 0);
1468:
1469: pktlen = (uint16_t)(rx_cmd_a & MUE_RX_CMD_A_LEN_MASK);
1470: if (sc->mue_flags & LAN7500)
1471: pktlen -= 2;
1472:
1.10 rin 1473: if (__predict_false(pktlen < ETHER_HDR_LEN + ETHER_CRC_LEN ||
1.1 rin 1474: pktlen > MCLBYTES - ETHER_ALIGN ||
1.15 rin 1475: pktlen + sizeof(*hdrp) > totlen)) {
1.9 rin 1476: MUE_PRINTF(sc, "invalid packet length %d\n", pktlen);
1.1 rin 1477: ifp->if_ierrors++;
1478: goto done;
1479: }
1480:
1481: m = mue_newbuf();
1482: if (__predict_false(m == NULL)) {
1.9 rin 1483: MUE_PRINTF(sc, "failed to allocate mbuf\n");
1.1 rin 1484: ifp->if_ierrors++;
1485: goto done;
1486: }
1487:
1488: m_set_rcvif(m, ifp);
1489: m->m_pkthdr.len = m->m_len = pktlen;
1490: m->m_flags |= M_HASFCS;
1491: memcpy(mtod(m, char *), buf + sizeof(*hdrp), pktlen);
1492:
1493: /* Attention: sizeof(hdr) = 10 */
1494: pktlen = roundup(pktlen + sizeof(*hdrp), 4);
1.15 rin 1495: if (pktlen > totlen)
1496: pktlen = totlen;
1497: totlen -= pktlen;
1.1 rin 1498: buf += pktlen;
1499:
1500: s = splnet();
1501: if_percpuq_enqueue(ifp->if_percpuq, m);
1502: splx(s);
1.15 rin 1503: } while (totlen > 0);
1.1 rin 1504:
1505: done:
1506: /* Setup new transfer. */
1.3 rin 1507: usbd_setup_xfer(xfer, c, c->mue_buf, sc->mue_rxbufsz,
1.1 rin 1508: USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, mue_rxeof);
1509: usbd_transfer(xfer);
1510: }
1511:
1512: static void
1513: mue_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1514: {
1515: struct mue_chain *c = priv;
1516: struct mue_softc *sc = c->mue_sc;
1517: struct ifnet *ifp = GET_IFP(sc);
1518: int s;
1519:
1520: if (__predict_false(sc->mue_dying))
1521: return;
1522:
1523: s = splnet();
1524:
1525: if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
1526: if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1527: splx(s);
1528: return;
1529: }
1530: ifp->if_oerrors++;
1531: MUE_PRINTF(sc, "%s\n", usbd_errstr(status));
1532: if (status == USBD_STALLED)
1533: usbd_clear_endpoint_stall_async(
1534: sc->mue_ep[MUE_ENDPT_TX]);
1535: splx(s);
1536: return;
1537: }
1538:
1539: ifp->if_timer = 0;
1540: ifp->if_flags &= ~IFF_OACTIVE;
1541:
1542: if (!IFQ_IS_EMPTY(&ifp->if_snd))
1543: mue_start(ifp);
1544:
1545: ifp->if_opackets++;
1546: splx(s);
1547: }
1548:
1549: static int
1550: mue_init(struct ifnet *ifp)
1551: {
1552: struct mue_softc *sc = ifp->if_softc;
1553: int s;
1554:
1555: if (sc->mue_dying) {
1556: DPRINTF(sc, "dying\n");
1557: return EIO;
1558: }
1559:
1560: s = splnet();
1561:
1562: /* Cancel pending I/O and free all TX/RX buffers. */
1563: if (ifp->if_flags & IFF_RUNNING)
1564: mue_stop(ifp, 1);
1565:
1566: mue_reset(sc);
1567:
1568: /* Set MAC address. */
1569: mue_set_macaddr(sc);
1570:
1571: /* Load the multicast filter. */
1572: mue_setmulti(sc);
1573:
1574: /* TCP/UDP checksum offload engines. */
1575: mue_sethwcsum(sc);
1576:
1577: if (mue_open_pipes(sc)) {
1578: splx(s);
1579: return EIO;
1580: }
1581:
1582: /* Init RX ring. */
1583: if (mue_rx_list_init(sc)) {
1.9 rin 1584: MUE_PRINTF(sc, "failed to init rx list\n");
1.1 rin 1585: splx(s);
1586: return ENOBUFS;
1587: }
1588:
1589: /* Init TX ring. */
1590: if (mue_tx_list_init(sc)) {
1.9 rin 1591: MUE_PRINTF(sc, "failed to init tx list\n");
1.1 rin 1592: splx(s);
1593: return ENOBUFS;
1594: }
1595:
1.18 ! rin 1596: mue_startup_rx_pipes(sc);
1.1 rin 1597:
1598: ifp->if_flags |= IFF_RUNNING;
1599: ifp->if_flags &= ~IFF_OACTIVE;
1600:
1601: splx(s);
1602:
1603: callout_reset(&sc->mue_stat_ch, hz, mue_tick, sc);
1604:
1605: return 0;
1606: }
1607:
1608: static int
1609: mue_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1610: {
1611: struct mue_softc *sc = ifp->if_softc;
1612: struct ifreq /*const*/ *ifr = data;
1613: int s, error = 0;
1614:
1615: s = splnet();
1616:
1617: switch(cmd) {
1618: case SIOCSIFFLAGS:
1619: if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1620: break;
1621:
1622: switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
1623: case IFF_RUNNING:
1624: mue_stop(ifp, 1);
1625: break;
1626: case IFF_UP:
1627: mue_init(ifp);
1628: break;
1629: case IFF_UP | IFF_RUNNING:
1630: if ((ifp->if_flags ^ sc->mue_if_flags) == IFF_PROMISC)
1631: mue_setmulti(sc);
1632: else
1633: mue_init(ifp);
1634: break;
1635: }
1636: sc->mue_if_flags = ifp->if_flags;
1637: break;
1638: case SIOCGIFMEDIA:
1639: case SIOCSIFMEDIA:
1640: error = ifmedia_ioctl(ifp, ifr, &sc->mue_mii.mii_media, cmd);
1641: break;
1642: default:
1643: if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET)
1644: break;
1645: error = 0;
1646: if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI)
1647: mue_setmulti(sc);
1648: break;
1649: }
1650: splx(s);
1651:
1652: return error;
1653: }
1654:
1655: static void
1656: mue_watchdog(struct ifnet *ifp)
1657: {
1658: struct mue_softc *sc = ifp->if_softc;
1659: struct mue_chain *c;
1660: usbd_status stat;
1661: int s;
1662:
1663: ifp->if_oerrors++;
1664: MUE_PRINTF(sc, "timed out\n");
1665:
1666: s = splusb();
1667: c = &sc->mue_cdata.mue_tx_chain[0];
1668: usbd_get_xfer_status(c->mue_xfer, NULL, NULL, NULL, &stat);
1669: mue_txeof(c->mue_xfer, c, stat);
1670:
1671: if (!IFQ_IS_EMPTY(&ifp->if_snd))
1672: mue_start(ifp);
1673: splx(s);
1674: }
1675:
1676: static void
1677: mue_reset(struct mue_softc *sc)
1678: {
1679: if (sc->mue_dying)
1680: return;
1681:
1682: /* Wait a little while for the chip to get its brains in order. */
1683: usbd_delay_ms(sc->mue_udev, 1);
1684:
1685: // mue_chip_init(sc); /* XXX */
1686: }
1687:
1688: static void
1689: mue_start(struct ifnet *ifp)
1690: {
1691: struct mue_softc *sc = ifp->if_softc;
1692: struct mbuf *m;
1693:
1694: if (__predict_false(!sc->mue_link)) {
1695: DPRINTF(sc, "no link\n");
1696: return;
1697: }
1698:
1699: if (__predict_false((ifp->if_flags & (IFF_OACTIVE|IFF_RUNNING))
1700: != IFF_RUNNING)) {
1701: DPRINTF(sc, "not ready\n");
1702: return;
1703: }
1704:
1705: IFQ_POLL(&ifp->if_snd, m);
1706: if (m == NULL)
1707: return;
1708:
1709: if (__predict_false(mue_encap(sc, m, 0))) {
1.14 rin 1710: ifp->if_oerrors++;
1.1 rin 1711: return;
1712: }
1713: IFQ_DEQUEUE(&ifp->if_snd, m);
1714:
1715: bpf_mtap(ifp, m, BPF_D_OUT);
1716: m_freem(m);
1717:
1718: ifp->if_flags |= IFF_OACTIVE;
1719:
1720: /* Set a timeout in case the chip goes out to lunch. */
1721: ifp->if_timer = 5;
1722: }
1723:
1724: static void
1725: mue_stop(struct ifnet *ifp, int disable __unused)
1726: {
1727: struct mue_softc *sc = ifp->if_softc;
1728: usbd_status err;
1729: size_t i;
1730:
1731: mue_reset(sc);
1732:
1733: ifp->if_timer = 0;
1734: ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1735:
1736: callout_stop(&sc->mue_stat_ch);
1737:
1738: /* Stop transfers. */
1739: for (i = 0; i < __arraycount(sc->mue_ep); i++)
1740: if (sc->mue_ep[i] != NULL) {
1741: err = usbd_abort_pipe(sc->mue_ep[i]);
1742: if (err)
1743: MUE_PRINTF(sc, "abort pipe %zu: %s\n",
1744: i, usbd_errstr(err));
1745: }
1746:
1747: /* Free RX resources. */
1748: for (i = 0; i < __arraycount(sc->mue_cdata.mue_rx_chain); i++)
1749: if (sc->mue_cdata.mue_rx_chain[i].mue_xfer != NULL) {
1750: usbd_destroy_xfer(
1751: sc->mue_cdata.mue_rx_chain[i].mue_xfer);
1752: sc->mue_cdata.mue_rx_chain[i].mue_xfer = NULL;
1753: }
1754:
1755: /* Free TX resources. */
1756: for (i = 0; i < __arraycount(sc->mue_cdata.mue_tx_chain); i++)
1757: if (sc->mue_cdata.mue_tx_chain[i].mue_xfer != NULL) {
1758: usbd_destroy_xfer(
1759: sc->mue_cdata.mue_tx_chain[i].mue_xfer);
1760: sc->mue_cdata.mue_tx_chain[i].mue_xfer = NULL;
1761: }
1762:
1763: /* Close pipes */
1764: for (i = 0; i < __arraycount(sc->mue_ep); i++)
1765: if (sc->mue_ep[i] != NULL) {
1766: err = usbd_close_pipe(sc->mue_ep[i]);
1767: if (err)
1768: MUE_PRINTF(sc, "close pipe %zu: %s\n",
1769: i, usbd_errstr(err));
1770: sc->mue_ep[i] = NULL;
1771: }
1772:
1773: sc->mue_link = 0; /* XXX */
1774:
1775: DPRINTF(sc, "done\n");
1776: }
1777:
1778: static void
1779: mue_tick(void *xsc)
1780: {
1781: struct mue_softc *sc = xsc;
1782:
1783: if (sc == NULL)
1784: return;
1785:
1786: if (sc->mue_dying)
1787: return;
1788:
1789: /* Perform periodic stuff in process context. */
1790: usb_add_task(sc->mue_udev, &sc->mue_tick_task, USB_TASKQ_DRIVER);
1791: }
1792:
1793: static void
1794: mue_tick_task(void *xsc)
1795: {
1796: struct mue_softc *sc = xsc;
1797: struct ifnet *ifp = GET_IFP(sc);
1798: struct mii_data *mii = GET_MII(sc);
1799: int s;
1800:
1801: if (sc == NULL)
1802: return;
1803:
1804: if (sc->mue_dying)
1805: return;
1806:
1807: s = splnet();
1808: mii_tick(mii);
1809: if (sc->mue_link == 0)
1810: mue_miibus_statchg(ifp);
1811: callout_reset(&sc->mue_stat_ch, hz, mue_tick, sc);
1812: splx(s);
1813: }
1814:
1815: static struct mbuf *
1816: mue_newbuf(void)
1817: {
1818: struct mbuf *m;
1819:
1820: MGETHDR(m, M_DONTWAIT, MT_DATA);
1821: if (__predict_false(m == NULL))
1822: return NULL;
1823:
1824: MCLGET(m, M_DONTWAIT);
1825: if (__predict_false(!(m->m_flags & M_EXT))) {
1826: m_freem(m);
1827: return NULL;
1828: }
1829:
1830: m_adj(m, ETHER_ALIGN);
1831:
1832: return m;
1833: }
CVSweb <webmaster@jp.NetBSD.org>