xref: /openbsd-src/sys/dev/usb/if_uaq.c (revision 25c4e8bd056e974b28f4a0ffd39d76c190a56013)
1 /*	$OpenBSD: if_uaq.c,v 1.4 2022/06/26 15:25:03 jmatthew Exp $	*/
2 /*-
3  * Copyright (c) 2021 Jonathan Matthew <jonathan@d14n.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include "bpfilter.h"
29 #include "vlan.h"
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/sockio.h>
34 #include <sys/rwlock.h>
35 #include <sys/mbuf.h>
36 #include <sys/kernel.h>
37 #include <sys/socket.h>
38 #include <sys/device.h>
39 
40 #include <machine/bus.h>
41 
42 #include <net/if.h>
43 #include <net/if_media.h>
44 
45 #if NBPFILTER > 0
46 #include <net/bpf.h>
47 #endif
48 
49 #include <netinet/in.h>
50 #include <netinet/if_ether.h>
51 
52 #include <dev/usb/usb.h>
53 #include <dev/usb/usbdi.h>
54 #include <dev/usb/usbdi_util.h>
55 #include <dev/usb/usbdivar.h>
56 #include <dev/usb/usbdevs.h>
57 
58 #ifdef UAQ_DEBUG
59 #define DPRINTF(x)	do { if (uaqdebug) printf x; } while (0)
60 #define DPRINTFN(n,x)	do { if (uaqdebug >= (n)) printf x; } while (0)
61 int	uaqdebug = 0;
62 #else
63 #define DPRINTF(x)
64 #define DPRINTFN(n,x)
65 #endif
66 
67 #define UAQ_ENDPT_RX		0
68 #define UAQ_ENDPT_TX		1
69 #define UAQ_ENDPT_INTR		2
70 #define UAQ_ENDPT_MAX		3
71 
72 #define UAQ_TX_LIST_CNT		1
73 #define UAQ_RX_LIST_CNT		1
74 #define UAQ_TX_BUF_ALIGN	8
75 #define UAQ_RX_BUF_ALIGN	8
76 
77 #define UAQ_TX_BUFSZ		16384
78 #define UAQ_RX_BUFSZ		(62 * 1024)
79 
80 #define UAQ_CTL_READ		1
81 #define UAQ_CTL_WRITE		2
82 
83 #define UAQ_MCAST_FILTER_SIZE	8
84 
85 /* control commands */
86 #define UAQ_CMD_ACCESS_MAC	0x01
87 #define UAQ_CMD_FLASH_PARAM	0x20
88 #define UAQ_CMD_PHY_POWER	0x31
89 #define UAQ_CMD_WOL_CFG		0x60
90 #define UAQ_CMD_PHY_OPS		0x61
91 
92 /* SFR registers */
93 #define UAQ_SFR_GENERAL_STATUS	0x03
94 #define UAQ_SFR_CHIP_STATUS	0x05
95 #define UAQ_SFR_RX_CTL		0x0B
96 #define  UAQ_SFR_RX_CTL_STOP	0x0000
97 #define  UAQ_SFR_RX_CTL_PRO	0x0001
98 #define  UAQ_SFR_RX_CTL_AMALL	0x0002
99 #define  UAQ_SFR_RX_CTL_AB	0x0008
100 #define  UAQ_SFR_RX_CTL_AM	0x0010
101 #define  UAQ_SFR_RX_CTL_START	0x0080
102 #define  UAQ_SFR_RX_CTL_IPE	0x0200
103 #define UAQ_SFR_IPG_0		0x0D
104 #define UAQ_SFR_NODE_ID		0x10
105 #define UAQ_SFR_MCAST_FILTER	0x16
106 #define UAQ_SFR_MEDIUM_STATUS_MODE 0x22
107 #define  UAQ_SFR_MEDIUM_XGMIIMODE	0x0001
108 #define  UAQ_SFR_MEDIUM_FULL_DUPLEX	0x0002
109 #define  UAQ_SFR_MEDIUM_RXFLOW_CTRLEN	0x0010
110 #define  UAQ_SFR_MEDIUM_TXFLOW_CTRLEN	0x0020
111 #define  UAQ_SFR_MEDIUM_JUMBO_EN	0x0040
112 #define  UAQ_SFR_MEDIUM_RECEIVE_EN	0x0100
113 #define UAQ_SFR_MONITOR_MODE	0x24
114 #define  UAQ_SFR_MONITOR_MODE_EPHYRW	0x01
115 #define  UAQ_SFR_MONITOR_MODE_RWLC	0x02
116 #define  UAQ_SFR_MONITOR_MODE_RWMP	0x04
117 #define  UAQ_SFR_MONITOR_MODE_RWWF	0x08
118 #define  UAQ_SFR_MONITOR_MODE_RW_FLAG	0x10
119 #define  UAQ_SFR_MONITOR_MODE_PMEPOL	0x20
120 #define  UAQ_SFR_MONITOR_MODE_PMETYPE	0x40
121 #define UAQ_SFR_RX_BULKIN_QCTRL 0x2E
122 #define UAQ_SFR_RXCOE_CTL	0x34
123 #define  UAQ_SFR_RXCOE_IP		0x01
124 #define  UAQ_SFR_RXCOE_TCP		0x02
125 #define  UAQ_SFR_RXCOE_UDP		0x04
126 #define  UAQ_SFR_RXCOE_ICMP		0x08
127 #define  UAQ_SFR_RXCOE_IGMP		0x10
128 #define  UAQ_SFR_RXCOE_TCPV6		0x20
129 #define  UAQ_SFR_RXCOE_UDPV6		0x40
130 #define  UAQ_SFR_RXCOE_ICMV6		0x80
131 #define UAQ_SFR_TXCOE_CTL	0x35
132 #define  UAQ_SFR_TXCOE_IP		0x01
133 #define  UAQ_SFR_TXCOE_TCP		0x02
134 #define  UAQ_SFR_TXCOE_UDP		0x04
135 #define  UAQ_SFR_TXCOE_ICMP		0x08
136 #define  UAQ_SFR_TXCOE_IGMP		0x10
137 #define  UAQ_SFR_TXCOE_TCPV6		0x20
138 #define  UAQ_SFR_TXCOE_UDPV6		0x40
139 #define  UAQ_SFR_TXCOE_ICMV6		0x80
140 #define UAQ_SFR_BM_INT_MASK	0x41
141 #define UAQ_SFR_BMRX_DMA_CTRL	0x43
142 #define  UAQ_SFR_BMRX_DMA_EN	0x80
143 #define UAQ_SFR_BMTX_DMA_CTRL	0x46
144 #define UAQ_SFR_PAUSE_WATERLVL_LOW 0x54
145 #define UAQ_SFR_ARC_CTRL	0x9E
146 #define UAQ_SFR_SWP_CTRL	0xB1
147 #define UAQ_SFR_TX_PAUSE_RESEND_T 0xB2
148 #define UAQ_SFR_ETH_MAC_PATH	0xB7
149 #define  UAQ_SFR_RX_PATH_READY	0x01
150 #define UAQ_SFR_BULK_OUT_CTRL	0xB9
151 #define  UAQ_SFR_BULK_OUT_FLUSH_EN	0x01
152 #define  UAQ_SFR_BULK_OUT_EFF_EN	0x02
153 
154 #define UAQ_FW_VER_MAJOR	0xDA
155 #define UAQ_FW_VER_MINOR	0xDB
156 #define UAQ_FW_VER_REV		0xDC
157 
158 /* phy ops */
159 #define UAQ_PHY_ADV_100M	(1 << 0)
160 #define UAQ_PHY_ADV_1G		(1 << 1)
161 #define UAQ_PHY_ADV_2_5G	(1 << 2)
162 #define UAQ_PHY_ADV_5G		(1 << 3)
163 #define UAQ_PHY_ADV_MASK	0x0F
164 
165 #define UAQ_PHY_PAUSE		(1 << 16)
166 #define UAQ_PHY_ASYM_PAUSE	(1 << 17)
167 #define UAQ_PHY_LOW_POWER	(1 << 18)
168 #define UAQ_PHY_POWER_EN	(1 << 19)
169 #define UAQ_PHY_WOL		(1 << 20)
170 #define UAQ_PHY_DOWNSHIFT	(1 << 21)
171 
172 #define UAQ_PHY_DSH_RETRY_SHIFT	0x18
173 #define UAQ_PHY_DSH_RETRY_MASK	0xF000000
174 
175 /* status */
176 #define UAQ_STATUS_LINK		0x8000
177 #define UAQ_STATUS_SPEED_MASK	0x7F00
178 #define UAQ_STATUS_SPEED_SHIFT	8
179 #define UAQ_STATUS_SPEED_5G	0x000F
180 #define UAQ_STATUS_SPEED_2_5G	0x0010
181 #define UAQ_STATUS_SPEED_1G	0x0011
182 #define UAQ_STATUS_SPEED_100M	0x0013
183 
184 /* rx descriptor */
185 #define UAQ_RX_HDR_COUNT_MASK	0x1FFF
186 #define UAQ_RX_HDR_OFFSET_MASK	0xFFFFE000
187 #define UAQ_RX_HDR_OFFSET_SHIFT	13
188 
189 /* rx packet descriptor */
190 #define UAQ_RX_PKT_L4_ERR	0x01
191 #define UAQ_RX_PKT_L3_ERR	0x02
192 #define UAQ_RX_PKT_L4_MASK	0x1C
193 #define UAQ_RX_PKT_L4_UDP	0x04
194 #define UAQ_RX_PKT_L4_TCP	0x10
195 #define UAQ_RX_PKT_L3_MASK	0x60
196 #define UAQ_RX_PKT_L3_IP	0x20
197 #define UAQ_RX_PKT_L3_IP6	0x40
198 #define UAQ_RX_PKT_VLAN		0x400
199 #define UAQ_RX_PKT_RX_OK	0x800
200 #define UAQ_RX_PKT_DROP		0x80000000
201 #define UAQ_RX_PKT_LEN_MASK	0x7FFF0000
202 #define UAQ_RX_PKT_LEN_SHIFT	16
203 #define UAQ_RX_PKT_VLAN_SHIFT	32
204 
205 /* tx packet descriptor */
206 #define UAQ_TX_PKT_LEN_MASK	0x1FFFFF
207 #define UAQ_TX_PKT_DROP_PADD	(1 << 28)
208 #define UAQ_TX_PKT_VLAN		(1 << 29)
209 #define UAQ_TX_PKT_VLAN_MASK	0xFFFF
210 #define UAQ_TX_PKT_VLAN_SHIFT	0x30
211 
212 
213 struct uaq_chain {
214 	struct uaq_softc	*uc_sc;
215 	struct usbd_xfer	*uc_xfer;
216 	char			*uc_buf;
217 	uint32_t		 uc_cnt;
218 	uint32_t		 uc_buflen;
219 	uint32_t		 uc_bufmax;
220 	SLIST_ENTRY(uaq_chain)	 uc_list;
221 	uint8_t			 uc_idx;
222 };
223 
224 struct uaq_cdata {
225 	struct uaq_chain	 uaq_rx_chain[UAQ_RX_LIST_CNT];
226 	struct uaq_chain	 uaq_tx_chain[UAQ_TX_LIST_CNT];
227 	SLIST_HEAD(uaq_list_head, uaq_chain) uaq_tx_free;
228 };
229 
230 struct uaq_softc {
231 	struct device		 sc_dev;
232 	struct usbd_device	*sc_udev;
233 
234 	struct usbd_interface	*sc_iface;
235 	struct usb_task		 sc_link_task;
236 	struct timeval		 sc_rx_notice;
237 	int			 sc_ed[UAQ_ENDPT_MAX];
238 	struct usbd_pipe	*sc_ep[UAQ_ENDPT_MAX];
239 	int			 sc_out_frame_size;
240 
241 	struct arpcom		 sc_ac;
242 	struct ifmedia		 sc_ifmedia;
243 
244 	struct uaq_cdata	 sc_cdata;
245 	uint64_t		 sc_link_status;
246 	int			 sc_link_speed;
247 
248 	uint32_t		 sc_phy_cfg;
249 	uint16_t		 sc_rxctl;
250 };
251 
252 const struct usb_devno uaq_devs[] = {
253 	{ USB_VENDOR_AQUANTIA, USB_PRODUCT_AQUANTIA_AQC111 },
254 	{ USB_VENDOR_ASIX, USB_PRODUCT_ASIX_ASIX111 },
255 	{ USB_VENDOR_ASIX, USB_PRODUCT_ASIX_ASIX112 },
256 	{ USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_TUCET5G },
257 	{ USB_VENDOR_QNAP, USB_PRODUCT_QNAP_UC5G1T },
258 };
259 
260 int		uaq_match(struct device *, void *, void *);
261 void		uaq_attach(struct device *, struct device *, void *);
262 int		uaq_detach(struct device *, int);
263 
264 int		uaq_ctl(struct uaq_softc *, uint8_t, uint8_t, uint16_t,
265 		    uint16_t, void *, int);
266 int		uaq_read_mem(struct uaq_softc *, uint8_t, uint16_t, uint16_t,
267 		    void *, int);
268 int		uaq_write_mem(struct uaq_softc *, uint8_t, uint16_t, uint16_t,
269 		    void *, int);
270 uint8_t		uaq_read_1(struct uaq_softc *, uint8_t, uint16_t, uint16_t);
271 uint16_t	uaq_read_2(struct uaq_softc *, uint8_t, uint16_t, uint16_t);
272 uint32_t	uaq_read_4(struct uaq_softc *, uint8_t, uint16_t, uint16_t);
273 int		uaq_write_1(struct uaq_softc *, uint8_t, uint16_t, uint16_t,
274 		    uint32_t);
275 int		uaq_write_2(struct uaq_softc *, uint8_t, uint16_t, uint16_t,
276 		    uint32_t);
277 int		uaq_write_4(struct uaq_softc *, uint8_t, uint16_t, uint16_t,
278 		    uint32_t);
279 
280 int		uaq_ifmedia_upd(struct ifnet *);
281 void		uaq_ifmedia_sts(struct ifnet *, struct ifmediareq *);
282 void		uaq_add_media_types(struct uaq_softc *);
283 void		uaq_iff(struct uaq_softc *);
284 
285 void		uaq_init(void *);
286 int		uaq_ioctl(struct ifnet *, u_long, caddr_t);
287 int		uaq_xfer_list_init(struct uaq_softc *, struct uaq_chain *,
288 		    uint32_t, int);
289 void		uaq_xfer_list_free(struct uaq_softc *, struct uaq_chain *, int);
290 
291 void		uaq_stop(struct uaq_softc *);
292 void		uaq_link(struct uaq_softc *);
293 void		uaq_intr(struct usbd_xfer *, void *, usbd_status);
294 void		uaq_start(struct ifnet *);
295 void		uaq_rxeof(struct usbd_xfer *, void *, usbd_status);
296 void		uaq_txeof(struct usbd_xfer *, void *, usbd_status);
297 void		uaq_watchdog(struct ifnet *);
298 void		uaq_reset(struct uaq_softc *);
299 
300 int		uaq_encap_txpkt(struct uaq_softc *, struct mbuf *, char *,
301 		    uint32_t);
302 int		uaq_encap_xfer(struct uaq_softc *, struct uaq_chain *);
303 
304 struct cfdriver uaq_cd = {
305 	NULL, "uaq", DV_IFNET
306 };
307 
308 const struct cfattach uaq_ca = {
309 	sizeof(struct uaq_softc), uaq_match, uaq_attach, uaq_detach
310 };
311 
312 int
313 uaq_ctl(struct uaq_softc *sc, uint8_t rw, uint8_t cmd, uint16_t val,
314     uint16_t index, void *buf, int len)
315 {
316 	usb_device_request_t	req;
317 	usbd_status		err;
318 
319 	if (usbd_is_dying(sc->sc_udev))
320 		return 0;
321 
322 	if (rw == UAQ_CTL_WRITE)
323 		req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
324 	else
325 		req.bmRequestType = UT_READ_VENDOR_DEVICE;
326 	req.bRequest = cmd;
327 	USETW(req.wValue, val);
328 	USETW(req.wIndex, index);
329 	USETW(req.wLength, len);
330 
331 	DPRINTFN(5, ("uaq_ctl: rw %d, val 0x%04hx, index 0x%04hx, len %d\n",
332 	    rw, val, index, len));
333 	err = usbd_do_request(sc->sc_udev, &req, buf);
334 	if (err) {
335 		DPRINTF(("uaq_ctl: error %d\n", err));
336 		return -1;
337 	}
338 
339 	return 0;
340 }
341 
342 int
343 uaq_read_mem(struct uaq_softc *sc, uint8_t cmd, uint16_t addr, uint16_t index,
344     void *buf, int len)
345 {
346 	return (uaq_ctl(sc, UAQ_CTL_READ, cmd, addr, index, buf, len));
347 }
348 
349 int
350 uaq_write_mem(struct uaq_softc *sc, uint8_t cmd, uint16_t addr, uint16_t index,
351     void *buf, int len)
352 {
353 	return (uaq_ctl(sc, UAQ_CTL_WRITE, cmd, addr, index, buf, len));
354 }
355 
356 uint8_t
357 uaq_read_1(struct uaq_softc *sc, uint8_t cmd, uint16_t reg, uint16_t index)
358 {
359 	uint8_t		val;
360 
361 	uaq_read_mem(sc, cmd, reg, index, &val, 1);
362 	DPRINTFN(4, ("uaq_read_1: cmd %x reg %x index %x = %x\n", cmd, reg,
363 	    index, val));
364 	return (val);
365 }
366 
367 uint16_t
368 uaq_read_2(struct uaq_softc *sc, uint8_t cmd, uint16_t reg, uint16_t index)
369 {
370 	uint16_t	val;
371 
372 	uaq_read_mem(sc, cmd, reg, index, &val, 2);
373 	DPRINTFN(4, ("uaq_read_2: cmd %x reg %x index %x = %x\n", cmd, reg,
374 	    index, UGETW(&val)));
375 
376 	return (UGETW(&val));
377 }
378 
379 uint32_t
380 uaq_read_4(struct uaq_softc *sc, uint8_t cmd, uint16_t reg, uint16_t index)
381 {
382 	uint32_t	val;
383 
384 	uaq_read_mem(sc, cmd, reg, index, &val, 4);
385 	DPRINTFN(4, ("uaq_read_4: cmd %x reg %x index %x = %x\n", cmd, reg,
386 	    index, UGETDW(&val)));
387 	return (UGETDW(&val));
388 }
389 
390 int
391 uaq_write_1(struct uaq_softc *sc, uint8_t cmd, uint16_t reg, uint16_t index,
392     uint32_t val)
393 {
394 	uint8_t		temp;
395 
396 	DPRINTFN(4, ("uaq_write_1: cmd %x reg %x index %x: %x\n", cmd, reg,
397 	    index, val));
398 	temp = val & 0xff;
399 	return (uaq_write_mem(sc, cmd, reg, index, &temp, 1));
400 }
401 
402 int
403 uaq_write_2(struct uaq_softc *sc, uint8_t cmd, uint16_t reg, uint16_t index,
404     uint32_t val)
405 {
406 	uint16_t	temp;
407 
408 	DPRINTFN(4, ("uaq_write_2: cmd %x reg %x index %x: %x\n", cmd, reg,
409 	    index, val));
410 	USETW(&temp, val & 0xffff);
411 	return (uaq_write_mem(sc, cmd, reg, index, &temp, 2));
412 }
413 
414 int
415 uaq_write_4(struct uaq_softc *sc, uint8_t cmd, uint16_t reg, uint16_t index,
416     uint32_t val)
417 {
418 	uint8_t	temp[4];
419 
420 	DPRINTFN(4, ("uaq_write_4: cmd %x reg %x index %x: %x\n", cmd, reg,
421 	    index, val));
422 	USETDW(temp, val);
423 	return (uaq_write_mem(sc, cmd, reg, index, &temp, 4));
424 }
425 
426 int
427 uaq_match(struct device *parent, void *match, void *aux)
428 {
429 	struct usb_attach_arg	*uaa = aux;
430 
431 	if (uaa->iface == NULL || uaa->configno != 1)
432 		return (UMATCH_NONE);
433 
434 	return (usb_lookup(uaq_devs, uaa->vendor, uaa->product) != NULL ?
435 	    UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE);
436 }
437 
438 void
439 uaq_attach(struct device *parent, struct device *self, void *aux)
440 {
441 	struct uaq_softc		*sc = (struct uaq_softc *)self;
442 	struct usb_attach_arg		*uaa = aux;
443 	usb_interface_descriptor_t	*id;
444 	usb_endpoint_descriptor_t	*ed;
445 	struct ifnet			*ifp;
446 	int				i, s;
447 
448 	sc->sc_udev = uaa->device;
449 	sc->sc_iface = uaa->iface;
450 
451 	usb_init_task(&sc->sc_link_task, (void (*)(void *))uaq_link, sc,
452 	    USB_TASK_TYPE_GENERIC);
453 
454 	id = usbd_get_interface_descriptor(sc->sc_iface);
455 
456 	for (i = 0; i < id->bNumEndpoints; i++) {
457 		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
458 		if (!ed) {
459 			printf("%s: couldn't get ep %d\n",
460 			    sc->sc_dev.dv_xname, i);
461 			return;
462 		}
463 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
464 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
465 			sc->sc_ed[UAQ_ENDPT_RX] = ed->bEndpointAddress;
466 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
467 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
468 			sc->sc_ed[UAQ_ENDPT_TX] = ed->bEndpointAddress;
469 			sc->sc_out_frame_size = UGETW(ed->wMaxPacketSize);
470 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
471 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
472 			sc->sc_ed[UAQ_ENDPT_INTR] = ed->bEndpointAddress;
473 		}
474 	}
475 
476 	if ((sc->sc_ed[UAQ_ENDPT_RX] == 0) ||
477 	    (sc->sc_ed[UAQ_ENDPT_TX] == 0) ||
478 	    (sc->sc_ed[UAQ_ENDPT_INTR] == 0)) {
479 		printf("%s: missing one or more endpoints (%d, %d, %d)\n",
480 		    sc->sc_dev.dv_xname, sc->sc_ed[UAQ_ENDPT_RX],
481 		    sc->sc_ed[UAQ_ENDPT_TX], sc->sc_ed[UAQ_ENDPT_INTR]);
482 		return;
483 	}
484 
485 	s = splnet();
486 
487 	printf("%s: ver %u.%u.%u", sc->sc_dev.dv_xname,
488 	    uaq_read_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_FW_VER_MAJOR, 1) & 0x7f,
489 	    uaq_read_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_FW_VER_MINOR, 1),
490 	    uaq_read_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_FW_VER_REV, 1));
491 
492 	uaq_read_mem(sc, UAQ_CMD_FLASH_PARAM, 0, 0, &sc->sc_ac.ac_enaddr,
493 	    ETHER_ADDR_LEN);
494 	printf(", address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr));
495 
496 	ifp = &sc->sc_ac.ac_if;
497 	ifp->if_softc = sc;
498 	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
499 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
500 	ifp->if_ioctl = uaq_ioctl;
501 	ifp->if_start = uaq_start;
502 	ifp->if_watchdog = uaq_watchdog;
503 
504 	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_IPv4 |
505 	    IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
506 
507 #if NVLAN > 0
508 	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
509 #endif
510 
511 	ifmedia_init(&sc->sc_ifmedia, IFM_IMASK, uaq_ifmedia_upd,
512 	    uaq_ifmedia_sts);
513 	uaq_add_media_types(sc);
514 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
515 	ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | IFM_AUTO);
516 	sc->sc_ifmedia.ifm_media = sc->sc_ifmedia.ifm_cur->ifm_media;
517 
518 	if_attach(ifp);
519 	ether_ifattach(ifp);
520 
521 	splx(s);
522 }
523 
524 int
525 uaq_detach(struct device *self, int flags)
526 {
527 	struct uaq_softc	*sc = (struct uaq_softc *)self;
528 	struct ifnet		*ifp = &sc->sc_ac.ac_if;
529 	int			s;
530 
531 	if (sc->sc_ep[UAQ_ENDPT_TX] != NULL)
532 		usbd_abort_pipe(sc->sc_ep[UAQ_ENDPT_TX]);
533 	if (sc->sc_ep[UAQ_ENDPT_RX] != NULL)
534 		usbd_abort_pipe(sc->sc_ep[UAQ_ENDPT_RX]);
535 	if (sc->sc_ep[UAQ_ENDPT_INTR] != NULL)
536 		usbd_abort_pipe(sc->sc_ep[UAQ_ENDPT_INTR]);
537 
538 	s = splusb();
539 
540 	usb_rem_task(sc->sc_udev, &sc->sc_link_task);
541 
542 	usb_detach_wait(&sc->sc_dev);
543 
544 	if (ifp->if_flags & IFF_RUNNING)
545 		uaq_stop(sc);
546 
547 	if (ifp->if_softc != NULL) {
548 		ether_ifdetach(ifp);
549 		if_detach(ifp);
550 	}
551 
552 	splx(s);
553 
554 	return 0;
555 }
556 
557 int
558 uaq_ifmedia_upd(struct ifnet *ifp)
559 {
560 	struct uaq_softc	*sc = ifp->if_softc;
561 	struct ifmedia		*ifm = &sc->sc_ifmedia;
562 	int			 auto_adv;
563 
564 	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
565 		return (EINVAL);
566 
567 	auto_adv = UAQ_PHY_ADV_100M | UAQ_PHY_ADV_1G;
568 	if (sc->sc_udev->speed == USB_SPEED_SUPER)
569 		auto_adv |= UAQ_PHY_ADV_2_5G | UAQ_PHY_ADV_5G;
570 
571 	sc->sc_phy_cfg &= ~(UAQ_PHY_ADV_MASK);
572 	sc->sc_phy_cfg |= UAQ_PHY_PAUSE | UAQ_PHY_ASYM_PAUSE |
573 	    UAQ_PHY_DOWNSHIFT | (3 << UAQ_PHY_DSH_RETRY_SHIFT);
574 
575 	switch (IFM_SUBTYPE(ifm->ifm_media)) {
576 	case IFM_AUTO:
577 		sc->sc_phy_cfg |= auto_adv;
578 		break;
579 	case IFM_5000_T:
580 		sc->sc_phy_cfg |= UAQ_PHY_ADV_5G;
581 		break;
582 	case IFM_2500_T:
583 		sc->sc_phy_cfg |= UAQ_PHY_ADV_2_5G;
584 		break;
585 	case IFM_1000_T:
586 		sc->sc_phy_cfg |= UAQ_PHY_ADV_1G;
587 		break;
588 	case IFM_100_TX:
589 		sc->sc_phy_cfg |= UAQ_PHY_ADV_100M;
590 		break;
591 	default:
592 		printf("%s: unsupported media type\n", sc->sc_dev.dv_xname);
593 		return (EINVAL);
594 	}
595 
596 	DPRINTFN(1, ("%s: phy cfg %x\n", sc->sc_dev.dv_xname, sc->sc_phy_cfg));
597 	uaq_write_4(sc, UAQ_CMD_PHY_OPS, 0, 0, sc->sc_phy_cfg);
598 	return (0);
599 }
600 
601 void
602 uaq_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
603 {
604 	struct uaq_softc	*sc = ifp->if_softc;
605 
606 	ifmr->ifm_status = IFM_AVALID;
607 	if (sc->sc_link_speed > 0) {
608 		ifmr->ifm_status |= IFM_ACTIVE;
609 		ifmr->ifm_active = IFM_ETHER | IFM_FDX;
610 		switch (sc->sc_link_speed) {
611 		case UAQ_STATUS_SPEED_5G:
612 			ifmr->ifm_active |= IFM_5000_T;
613 			break;
614 		case UAQ_STATUS_SPEED_2_5G:
615 			ifmr->ifm_active |= IFM_2500_T;
616 			break;
617 		case UAQ_STATUS_SPEED_1G:
618 			ifmr->ifm_active |= IFM_1000_T;
619 			break;
620 		case UAQ_STATUS_SPEED_100M:
621 			ifmr->ifm_active |= IFM_100_TX;
622 			break;
623 		default:
624 			break;
625 		}
626 	}
627 }
628 
629 void
630 uaq_add_media_types(struct uaq_softc *sc)
631 {
632 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL);
633 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX, 0,
634 	    NULL);
635 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_1000_T, 0, NULL);
636 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_1000_T | IFM_FDX, 0,
637 	    NULL);
638 	/* only add 2.5G and 5G if at super speed */
639 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_2500_T, 0, NULL);
640 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_2500_T | IFM_FDX, 0,
641 	    NULL);
642 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_5000_T, 0, NULL);
643 	ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_5000_T | IFM_FDX, 0,
644 	    NULL);
645 }
646 
647 void
648 uaq_iff(struct uaq_softc *sc)
649 {
650 	struct ifnet		*ifp = &sc->sc_ac.ac_if;
651 	struct ether_multi	*enm;
652 	struct ether_multistep	step;
653 	uint8_t			filter[UAQ_MCAST_FILTER_SIZE];
654 	uint32_t		hash;
655 
656 	if (usbd_is_dying(sc->sc_udev))
657 		return;
658 
659 	sc->sc_rxctl &= ~(UAQ_SFR_RX_CTL_PRO | UAQ_SFR_RX_CTL_AMALL |
660 	    UAQ_SFR_RX_CTL_AM);
661 	ifp->if_flags &= ~IFF_ALLMULTI;
662 
663 	if (ifp->if_flags & IFF_PROMISC) {
664 		ifp->if_flags |= IFF_ALLMULTI;
665 		sc->sc_rxctl |= UAQ_SFR_RX_CTL_PRO;
666 	} else if (sc->sc_ac.ac_multirangecnt > 0) {
667 		ifp->if_flags |= IFF_ALLMULTI;
668 		sc->sc_rxctl |= UAQ_SFR_RX_CTL_AMALL;
669 	} else {
670 		sc->sc_rxctl |= UAQ_SFR_RX_CTL_AM;
671 
672 		bzero(filter, sizeof(filter));
673 		ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
674 		while (enm != NULL) {
675 			hash = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN)
676 			    >> 26;
677 			filter[hash >> 3] |= (1 << (hash & 7));
678 			ETHER_NEXT_MULTI(step, enm);
679 		}
680 
681 		uaq_write_mem(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_MCAST_FILTER,
682 		    UAQ_MCAST_FILTER_SIZE, filter, UAQ_MCAST_FILTER_SIZE);
683 	}
684 
685 	DPRINTFN(1, ("%s: rxctl = %x\n", sc->sc_dev.dv_xname, sc->sc_rxctl));
686 	uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RX_CTL, 2, sc->sc_rxctl);
687 }
688 
689 void
690 uaq_reset(struct uaq_softc *sc)
691 {
692 	uint8_t mode;
693 
694 	sc->sc_phy_cfg = UAQ_PHY_POWER_EN;
695 	uaq_write_4(sc, UAQ_CMD_PHY_OPS, 0, 0, sc->sc_phy_cfg);
696 
697 	uaq_write_mem(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_NODE_ID, 0,
698 	    sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
699 	uaq_write_mem(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_NODE_ID, ETHER_ADDR_LEN,
700 	    sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
701 
702 	uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BM_INT_MASK, 0, 0xff);
703 	uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_SWP_CTRL, 0, 0);
704 
705 	mode = uaq_read_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_MONITOR_MODE, 1);
706 	mode &= ~(UAQ_SFR_MONITOR_MODE_EPHYRW | UAQ_SFR_MONITOR_MODE_RWLC |
707 	    UAQ_SFR_MONITOR_MODE_RWMP | UAQ_SFR_MONITOR_MODE_RWWF |
708 	    UAQ_SFR_MONITOR_MODE_RW_FLAG);
709 	uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_MONITOR_MODE, 1, mode);
710 
711 	sc->sc_link_status = 0;
712 	sc->sc_link_speed = 0;
713 }
714 
715 void
716 uaq_init(void *xsc)
717 {
718 	struct uaq_softc	*sc = xsc;
719 	struct uaq_chain	*c;
720 	struct ifnet		*ifp = &sc->sc_ac.ac_if;
721 	usbd_status		err;
722 	int			s, i;
723 
724 	s = splnet();
725 
726 	uaq_stop(sc);
727 
728 	uaq_reset(sc);
729 
730 	if (uaq_xfer_list_init(sc, sc->sc_cdata.uaq_rx_chain,
731 		UAQ_RX_BUFSZ, UAQ_RX_LIST_CNT) == ENOBUFS) {
732 		printf("%s: rx list init failed\n", sc->sc_dev.dv_xname);
733 		splx(s);
734 		return;
735 	}
736 
737 	if (uaq_xfer_list_init(sc, sc->sc_cdata.uaq_tx_chain,
738 		UAQ_TX_BUFSZ, UAQ_TX_LIST_CNT) == ENOBUFS) {
739 		printf("%s: tx list init failed\n", sc->sc_dev.dv_xname);
740 		splx(s);
741 		return;
742 	}
743 
744 	SLIST_INIT(&sc->sc_cdata.uaq_tx_free);
745 	for (i = 0; i < UAQ_TX_LIST_CNT; i++)
746 		SLIST_INSERT_HEAD(&sc->sc_cdata.uaq_tx_free,
747 		    &sc->sc_cdata.uaq_tx_chain[i], uc_list);
748 
749 	err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UAQ_ENDPT_RX],
750 	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UAQ_ENDPT_RX]);
751 	if (err) {
752 		printf("%s: open rx pipe failed: %s\n",
753 		    sc->sc_dev.dv_xname, usbd_errstr(err));
754 		splx(s);
755 		return;
756 	}
757 
758 	err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UAQ_ENDPT_TX],
759 	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UAQ_ENDPT_TX]);
760 	if (err) {
761 		printf("%s: open tx pipe failed: %s\n",
762 		    sc->sc_dev.dv_xname, usbd_errstr(err));
763 		splx(s);
764 		return;
765 	}
766 
767 	for (i = 0; i < UAQ_RX_LIST_CNT; i++) {
768 		c = &sc->sc_cdata.uaq_rx_chain[i];
769 		usbd_setup_xfer(c->uc_xfer, sc->sc_ep[UAQ_ENDPT_RX],
770 		    c, c->uc_buf, c->uc_bufmax,
771 		    USBD_SHORT_XFER_OK | USBD_NO_COPY,
772 		    USBD_NO_TIMEOUT, uaq_rxeof);
773 		usbd_transfer(c->uc_xfer);
774 	}
775 
776 	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UAQ_ENDPT_INTR],
777 	    0, &sc->sc_ep[UAQ_ENDPT_INTR], sc,
778 	    &sc->sc_link_status, sizeof(sc->sc_link_status), uaq_intr,
779 	    USBD_DEFAULT_INTERVAL);
780 	if (err) {
781 		printf("%s: couldn't open interrupt pipe\n",
782 		    sc->sc_dev.dv_xname);
783 		splx(s);
784 		return;
785 	}
786 
787 	uaq_iff(sc);
788 
789 	uaq_ifmedia_upd(ifp);
790 
791 	ifp->if_flags |= IFF_RUNNING;
792 	ifq_clr_oactive(&ifp->if_snd);
793 
794 	splx(s);
795 }
796 
797 int
798 uaq_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
799 {
800 	struct uaq_softc	*sc = ifp->if_softc;
801 	struct ifreq		*ifr = (struct ifreq *)data;
802 	int			s, error = 0;
803 
804 	s = splnet();
805 
806 	switch (cmd) {
807 	case SIOCSIFADDR:
808 		ifp->if_flags |= IFF_UP;
809 		if (!(ifp->if_flags & IFF_RUNNING))
810 			uaq_init(sc);
811 		break;
812 
813 	case SIOCSIFFLAGS:
814 		if (ifp->if_flags & IFF_UP) {
815 			if (ifp->if_flags & IFF_RUNNING)
816 				error = ENETRESET;
817 			else
818 				uaq_init(sc);
819 		} else {
820 			if (ifp->if_flags & IFF_RUNNING)
821 				uaq_stop(sc);
822 		}
823 		break;
824 
825 	case SIOCGIFMEDIA:
826 	case SIOCSIFMEDIA:
827 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
828 		break;
829 
830 	default:
831 		error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
832 	}
833 
834 	if (error == ENETRESET) {
835 		if (ifp->if_flags & IFF_RUNNING)
836 			uaq_iff(sc);
837 		error = 0;
838 	}
839 
840 	splx(s);
841 
842 	return (error);
843 }
844 
845 int
846 uaq_xfer_list_init(struct uaq_softc *sc, struct uaq_chain *ch,
847     uint32_t bufsize, int listlen)
848 {
849 	struct uaq_chain	*c;
850 	int			i;
851 
852 	for (i = 0; i < listlen; i++) {
853 		c = &ch[i];
854 		c->uc_sc = sc;
855 		c->uc_idx = i;
856 		c->uc_buflen = 0;
857 		c->uc_bufmax = bufsize;
858 		c->uc_cnt = 0;
859 		if (c->uc_xfer == NULL) {
860 			c->uc_xfer = usbd_alloc_xfer(sc->sc_udev);
861 			if (c->uc_xfer == NULL)
862 				return (ENOBUFS);
863 
864 			c->uc_buf = usbd_alloc_buffer(c->uc_xfer, c->uc_bufmax);
865 			if (c->uc_buf == NULL) {
866 				usbd_free_xfer(c->uc_xfer);
867 				c->uc_xfer = NULL;
868 				return (ENOBUFS);
869 			}
870 		}
871 	}
872 
873 	return (0);
874 }
875 
876 void
877 uaq_xfer_list_free(struct uaq_softc *sc, struct uaq_chain *ch, int listlen)
878 {
879 	int	i;
880 
881 	for (i = 0; i < listlen; i++) {
882 		if (ch[i].uc_buf != NULL) {
883 			ch[i].uc_buf = NULL;
884 		}
885 		ch[i].uc_cnt = 0;
886 		if (ch[i].uc_xfer != NULL) {
887 			usbd_free_xfer(ch[i].uc_xfer);
888 			ch[i].uc_xfer = NULL;
889 		}
890 	}
891 }
892 
893 void
894 uaq_stop(struct uaq_softc *sc)
895 {
896 	struct uaq_cdata	*cd;
897 	struct ifnet		*ifp;
898 	usbd_status		err;
899 
900 	ifp = &sc->sc_ac.ac_if;
901 	ifp->if_timer = 0;
902 	ifp->if_flags &= ~IFF_RUNNING;
903 	ifq_clr_oactive(&ifp->if_snd);
904 
905 	sc->sc_link_status = 0;
906 	sc->sc_link_speed = 0;
907 
908 	if (sc->sc_ep[UAQ_ENDPT_RX] != NULL) {
909 		err = usbd_close_pipe(sc->sc_ep[UAQ_ENDPT_RX]);
910 		if (err) {
911 			printf("%s: close rx pipe failed: %s\n",
912 			    sc->sc_dev.dv_xname, usbd_errstr(err));
913 		}
914 		sc->sc_ep[UAQ_ENDPT_RX] = NULL;
915 	}
916 
917 	if (sc->sc_ep[UAQ_ENDPT_TX] != NULL) {
918 		err = usbd_close_pipe(sc->sc_ep[UAQ_ENDPT_TX]);
919 		if (err) {
920 			printf("%s: close tx pipe failed: %s\n",
921 			    sc->sc_dev.dv_xname, usbd_errstr(err));
922 		}
923 		sc->sc_ep[UAQ_ENDPT_TX] = NULL;
924 	}
925 
926 	if (sc->sc_ep[UAQ_ENDPT_INTR] != NULL) {
927 		err = usbd_close_pipe(sc->sc_ep[UAQ_ENDPT_INTR]);
928 		if (err) {
929 			printf("%s: close intr pipe failed: %s\n",
930 			    sc->sc_dev.dv_xname, usbd_errstr(err));
931 		}
932 		sc->sc_ep[UAQ_ENDPT_INTR] = NULL;
933 	}
934 
935 	cd = &sc->sc_cdata;
936 	uaq_xfer_list_free(sc, cd->uaq_rx_chain, UAQ_RX_LIST_CNT);
937 	uaq_xfer_list_free(sc, cd->uaq_tx_chain, UAQ_TX_LIST_CNT);
938 }
939 
940 void
941 uaq_link(struct uaq_softc *sc)
942 {
943 	if (sc->sc_link_speed > 0) {
944 		uint8_t resend[3] = { 0, 0xf8, 7 };
945 		uint8_t qctrl[5] = { 7, 0x00, 0x01, 0x1e, 0xff };
946 		uint8_t ipg = 0;
947 
948 		switch (sc->sc_link_speed) {
949 		case UAQ_STATUS_SPEED_100M:
950 			resend[1] = 0xfb;
951 			resend[2] = 0x4;
952 			break;
953 
954 		case UAQ_STATUS_SPEED_5G:
955 			ipg = 5;
956 			break;
957 		}
958 
959 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_IPG_0, 1, ipg);
960 
961 		uaq_write_mem(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_TX_PAUSE_RESEND_T,
962 		    3, resend, 3);
963 		uaq_write_mem(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RX_BULKIN_QCTRL,
964 		    5, qctrl, 5);
965 		uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_PAUSE_WATERLVL_LOW,
966 		    2, 0x0810);
967 
968 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BMRX_DMA_CTRL, 1,
969 		    0);
970 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BMTX_DMA_CTRL, 1,
971 		    0);
972 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_ARC_CTRL, 1, 0);
973 
974 		sc->sc_rxctl = UAQ_SFR_RX_CTL_IPE | UAQ_SFR_RX_CTL_AB;
975 		uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RX_CTL, 2,
976 		    sc->sc_rxctl);
977 
978 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_ETH_MAC_PATH, 1,
979 		    UAQ_SFR_RX_PATH_READY);
980 
981 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BULK_OUT_CTRL, 1,
982 		    UAQ_SFR_BULK_OUT_EFF_EN);
983 
984 		uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_MEDIUM_STATUS_MODE,
985 		    2, 0);
986 		uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_MEDIUM_STATUS_MODE,
987 		    2, UAQ_SFR_MEDIUM_XGMIIMODE | UAQ_SFR_MEDIUM_FULL_DUPLEX |
988 		    UAQ_SFR_MEDIUM_RECEIVE_EN | UAQ_SFR_MEDIUM_RXFLOW_CTRLEN |
989 		    UAQ_SFR_MEDIUM_TXFLOW_CTRLEN);	/* JUMBO_EN */
990 
991 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RXCOE_CTL, 1,
992 		    UAQ_SFR_RXCOE_IP | UAQ_SFR_RXCOE_TCP | UAQ_SFR_RXCOE_UDP |
993 		    UAQ_SFR_RXCOE_TCPV6 | UAQ_SFR_RXCOE_UDPV6);
994 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_TXCOE_CTL, 1,
995 		    UAQ_SFR_TXCOE_IP | UAQ_SFR_TXCOE_TCP | UAQ_SFR_TXCOE_UDP |
996 		    UAQ_SFR_TXCOE_TCPV6 | UAQ_SFR_TXCOE_UDPV6);
997 
998 		sc->sc_rxctl |= UAQ_SFR_RX_CTL_START;
999 		uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RX_CTL, 2,
1000 		    sc->sc_rxctl);
1001 	} else {
1002 		uint16_t mode;
1003 
1004 		mode = uaq_read_2(sc, UAQ_CMD_ACCESS_MAC,
1005 		    UAQ_SFR_MEDIUM_STATUS_MODE, 2);
1006 		mode &= ~UAQ_SFR_MEDIUM_RECEIVE_EN;
1007 		uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_MEDIUM_STATUS_MODE,
1008 		    2, mode);
1009 
1010 		sc->sc_rxctl &= ~UAQ_SFR_RX_CTL_START;
1011 		uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RX_CTL, 2,
1012 		    sc->sc_rxctl);
1013 
1014 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BULK_OUT_CTRL, 1,
1015 		    UAQ_SFR_BULK_OUT_FLUSH_EN | UAQ_SFR_BULK_OUT_EFF_EN);
1016 
1017 		uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BULK_OUT_CTRL, 1,
1018 		    UAQ_SFR_BULK_OUT_EFF_EN);
1019 	}
1020 }
1021 
1022 void
1023 uaq_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
1024 {
1025 	struct uaq_softc	*sc = priv;
1026 	struct ifnet		*ifp = &sc->sc_ac.ac_if;
1027 	uint64_t		linkstatus;
1028 	uint64_t		baudrate;
1029 	int			link_state;
1030 
1031 	if (status == USBD_CANCELLED)
1032 		return;
1033 
1034 	if (status != USBD_NORMAL_COMPLETION) {
1035 		DPRINTFN(2, ("uaq_intr: status=%d\n", status));
1036 		if (status == USBD_STALLED)
1037 			usbd_clear_endpoint_stall_async(
1038 			    sc->sc_ep[UAQ_ENDPT_INTR]);
1039 		return;
1040 	}
1041 
1042 	linkstatus = letoh64(sc->sc_link_status);
1043 	DPRINTFN(1, ("uaq_intr: link status %llx\n", linkstatus));
1044 
1045 	if (linkstatus & UAQ_STATUS_LINK) {
1046 		link_state = LINK_STATE_FULL_DUPLEX;
1047 		sc->sc_link_speed = (linkstatus & UAQ_STATUS_SPEED_MASK)
1048 		    >> UAQ_STATUS_SPEED_SHIFT;
1049 		switch (sc->sc_link_speed) {
1050 		case UAQ_STATUS_SPEED_5G:
1051 			baudrate = IF_Gbps(5);
1052 			break;
1053 		case UAQ_STATUS_SPEED_2_5G:
1054 			baudrate = IF_Mbps(2500);
1055 			break;
1056 		case UAQ_STATUS_SPEED_1G:
1057 			baudrate = IF_Gbps(1);
1058 			break;
1059 		case UAQ_STATUS_SPEED_100M:
1060 			baudrate = IF_Mbps(100);
1061 			break;
1062 		default:
1063 			baudrate = 0;
1064 			break;
1065 		}
1066 
1067 		ifp->if_baudrate = baudrate;
1068 	} else {
1069 		link_state = LINK_STATE_DOWN;
1070 		sc->sc_link_speed = 0;
1071 	}
1072 
1073 	if (link_state != ifp->if_link_state) {
1074 		ifp->if_link_state = link_state;
1075 		if_link_state_change(ifp);
1076 		usb_add_task(sc->sc_udev, &sc->sc_link_task);
1077 	}
1078 }
1079 
1080 void
1081 uaq_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1082 {
1083 	struct uaq_chain	*c = (struct uaq_chain *)priv;
1084 	struct uaq_softc	*sc = c->uc_sc;
1085 	struct ifnet		*ifp = &sc->sc_ac.ac_if;
1086 	uint8_t			*buf;
1087 	uint64_t		*pdesc;
1088 	uint64_t		desc;
1089 	uint32_t		total_len;
1090 	struct mbuf_list	ml = MBUF_LIST_INITIALIZER();
1091 	struct mbuf		*m;
1092 	int			pktlen, s;
1093 	int			count, offset;
1094 
1095 	if (usbd_is_dying(sc->sc_udev))
1096 		return;
1097 
1098 	if (!(ifp->if_flags & IFF_RUNNING))
1099 		return;
1100 
1101 	if (status != USBD_NORMAL_COMPLETION) {
1102 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1103 			return;
1104 		if (usbd_ratecheck(&sc->sc_rx_notice)) {
1105 			printf("%s: usb errors on rx: %s\n",
1106 				sc->sc_dev.dv_xname, usbd_errstr(status));
1107 		}
1108 		if (status == USBD_STALLED)
1109 			usbd_clear_endpoint_stall_async(
1110 			    sc->sc_ep[UAQ_ENDPT_RX]);
1111 		goto done;
1112 	}
1113 
1114 	usbd_get_xfer_status(xfer, NULL, (void **)&buf, &total_len, NULL);
1115 	DPRINTFN(3, ("received %d bytes\n", total_len));
1116 	if ((total_len & 7) != 0) {
1117 		printf("%s: weird rx transfer length %d\n",
1118 		    sc->sc_dev.dv_xname, total_len);
1119 		goto done;
1120 	}
1121 
1122 	pdesc = (uint64_t *)(buf + (total_len - sizeof(desc)));
1123 	desc = lemtoh64(pdesc);
1124 
1125 	count = desc & UAQ_RX_HDR_COUNT_MASK;
1126 	if (count == 0)
1127 		goto done;
1128 
1129 	/* get offset of packet headers */
1130 	offset = total_len - ((count + 1) * sizeof(desc));
1131 	if (offset != ((desc & UAQ_RX_HDR_OFFSET_MASK) >>
1132 	    UAQ_RX_HDR_OFFSET_SHIFT)) {
1133 		printf("%s: offset mismatch, got %d expected %lld\n",
1134 		    sc->sc_dev.dv_xname, offset,
1135 		    desc >> UAQ_RX_HDR_OFFSET_SHIFT);
1136 		goto done;
1137 	}
1138 	if (offset < 0 || offset > total_len) {
1139 		printf("%s: offset %d outside buffer (%d)\n",
1140 		    sc->sc_dev.dv_xname, offset, total_len);
1141 		goto done;
1142 	}
1143 
1144 	pdesc = (uint64_t *)(buf + offset);
1145 	total_len = offset;
1146 
1147 	while (count-- > 0) {
1148 		desc = lemtoh64(pdesc);
1149 		pdesc++;
1150 
1151 		pktlen = (desc & UAQ_RX_PKT_LEN_MASK) >> UAQ_RX_PKT_LEN_SHIFT;
1152 		if (pktlen > total_len) {
1153 			DPRINTFN(2, ("not enough bytes for this packet\n"));
1154 			ifp->if_ierrors++;
1155 			goto done;
1156 		}
1157 
1158 		m = m_devget(buf + 2, pktlen - 2, ETHER_ALIGN);
1159 		if (m == NULL) {
1160 			DPRINTFN(2, ("m_devget failed for this packet\n"));
1161 			ifp->if_ierrors++;
1162 			goto done;
1163 		}
1164 
1165 		if ((desc & UAQ_RX_PKT_L3_ERR) == 0)
1166 			m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
1167 
1168 		if ((desc & UAQ_RX_PKT_L4_ERR) == 0)
1169 			m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
1170 			    M_UDP_CSUM_IN_OK;
1171 
1172 #if NVLAN > 0
1173 		if (desc & UAQ_RX_PKT_VLAN) {
1174 			m->m_pkthdr.ether_vtag = (desc >> UAQ_RX_PKT_VLAN_SHIFT) &
1175 			    0xfff;
1176 			m->m_flags |= M_VLANTAG;
1177 		}
1178 #endif
1179 		ml_enqueue(&ml, m);
1180 
1181 		total_len -= roundup(pktlen, UAQ_RX_BUF_ALIGN);
1182 		buf += roundup(pktlen, UAQ_RX_BUF_ALIGN);
1183 	}
1184 
1185 done:
1186 	s = splnet();
1187 	if_input(ifp, &ml);
1188 	splx(s);
1189 	memset(c->uc_buf, 0, UAQ_RX_BUFSZ);
1190 
1191 	usbd_setup_xfer(xfer, sc->sc_ep[UAQ_ENDPT_RX], c, c->uc_buf,
1192 	    UAQ_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
1193 	    USBD_NO_TIMEOUT, uaq_rxeof);
1194 	usbd_transfer(xfer);
1195 }
1196 
1197 
1198 void
1199 uaq_watchdog(struct ifnet *ifp)
1200 {
1201 	struct uaq_softc	*sc = ifp->if_softc;
1202 	struct uaq_chain	*c;
1203 	usbd_status		err;
1204 	int			i, s;
1205 
1206 	ifp->if_timer = 0;
1207 
1208 	if (usbd_is_dying(sc->sc_udev))
1209 		return;
1210 
1211 	if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
1212 		return;
1213 
1214 	sc = ifp->if_softc;
1215 	s = splnet();
1216 
1217 	ifp->if_oerrors++;
1218 	DPRINTF(("%s: watchdog timeout\n", sc->sc_dev.dv_xname));
1219 
1220 	for (i = 0; i < UAQ_TX_LIST_CNT; i++) {
1221 		c = &sc->sc_cdata.uaq_tx_chain[i];
1222 		if (c->uc_cnt > 0) {
1223 			usbd_get_xfer_status(c->uc_xfer, NULL, NULL, NULL,
1224 			    &err);
1225 			uaq_txeof(c->uc_xfer, c, err);
1226 		}
1227 	}
1228 
1229 	if (ifq_is_oactive(&ifp->if_snd))
1230 		ifq_restart(&ifp->if_snd);
1231 	splx(s);
1232 }
1233 
1234 void
1235 uaq_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1236 {
1237 	struct uaq_softc	*sc;
1238 	struct uaq_chain	*c;
1239 	struct ifnet		*ifp;
1240 	int			s;
1241 
1242 	c = priv;
1243 	sc = c->uc_sc;
1244 	ifp = &sc->sc_ac.ac_if;
1245 
1246 	if (usbd_is_dying(sc->sc_udev))
1247 		return;
1248 
1249 	if (status != USBD_NORMAL_COMPLETION)
1250 		DPRINTF(("%s: %s uc_idx=%u : %s\n", sc->sc_dev.dv_xname,
1251 			__func__, c->uc_idx, usbd_errstr(status)));
1252 	else
1253 		DPRINTF(("%s: txeof\n", sc->sc_dev.dv_xname));
1254 
1255 	s = splnet();
1256 
1257 	c->uc_cnt = 0;
1258 	c->uc_buflen = 0;
1259 
1260 	SLIST_INSERT_HEAD(&sc->sc_cdata.uaq_tx_free, c, uc_list);
1261 
1262 	if (status != USBD_NORMAL_COMPLETION) {
1263 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1264 			splx(s);
1265 			return;
1266 		}
1267 
1268 		ifp->if_oerrors++;
1269 		printf("%s: usb error on tx: %s\n", sc->sc_dev.dv_xname,
1270 		    usbd_errstr(status));
1271 
1272 		if (status == USBD_STALLED)
1273 			usbd_clear_endpoint_stall_async(
1274 			    sc->sc_ep[UAQ_ENDPT_TX]);
1275 		splx(s);
1276 		return;
1277 	}
1278 
1279 	ifp->if_timer = 0;
1280 	if (ifq_is_oactive(&ifp->if_snd))
1281 		ifq_restart(&ifp->if_snd);
1282 	splx(s);
1283 }
1284 
1285 void
1286 uaq_start(struct ifnet *ifp)
1287 {
1288 	struct uaq_softc	*sc = ifp->if_softc;
1289 	struct uaq_cdata	*cd = &sc->sc_cdata;
1290 	struct uaq_chain	*c;
1291 	struct mbuf		*m = NULL;
1292 	int			s, mlen;
1293 
1294 	if ((sc->sc_link_speed == 0) ||
1295 		(ifp->if_flags & (IFF_RUNNING|IFF_UP)) !=
1296 		    (IFF_RUNNING|IFF_UP)) {
1297 		return;
1298 	}
1299 
1300 	s = splnet();
1301 
1302 	c = SLIST_FIRST(&cd->uaq_tx_free);
1303 	while (c != NULL) {
1304 		m = ifq_deq_begin(&ifp->if_snd);
1305 		if (m == NULL)
1306 			break;
1307 
1308 		mlen = m->m_pkthdr.len;
1309 
1310 		/* Discard packet larger than buffer. */
1311 		if (mlen + sizeof(uint64_t) >= c->uc_bufmax) {
1312 			ifq_deq_commit(&ifp->if_snd, m);
1313 			m_freem(m);
1314 			ifp->if_oerrors++;
1315 			continue;
1316 		}
1317 
1318 		/* Append packet to current buffer. */
1319 		mlen = uaq_encap_txpkt(sc, m, c->uc_buf + c->uc_buflen,
1320 		    c->uc_bufmax - c->uc_buflen);
1321 		if (mlen <= 0) {
1322 			ifq_deq_rollback(&ifp->if_snd, m);
1323 			break;
1324 		}
1325 
1326 		ifq_deq_commit(&ifp->if_snd, m);
1327 		c->uc_cnt += 1;
1328 		c->uc_buflen += mlen;
1329 
1330 #if NBPFILTER > 0
1331 		if (ifp->if_bpf)
1332 			bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
1333 #endif
1334 
1335 		m_freem(m);
1336 	}
1337 
1338 	if (c != NULL) {
1339 		/* Send current buffer unless empty */
1340 		if (c->uc_buflen > 0 && c->uc_cnt > 0) {
1341 			SLIST_REMOVE_HEAD(&cd->uaq_tx_free, uc_list);
1342 			if (uaq_encap_xfer(sc, c)) {
1343 				SLIST_INSERT_HEAD(&cd->uaq_tx_free, c,
1344 				    uc_list);
1345 			}
1346 			c = SLIST_FIRST(&cd->uaq_tx_free);
1347 
1348 			ifp->if_timer = 5;
1349 			if (c == NULL)
1350 				ifq_set_oactive(&ifp->if_snd);
1351 		}
1352 	}
1353 
1354 	splx(s);
1355 }
1356 
1357 int
1358 uaq_encap_txpkt(struct uaq_softc *sc, struct mbuf *m, char *buf,
1359     uint32_t maxlen)
1360 {
1361 	uint64_t		desc;
1362 	int			padded;
1363 
1364 	desc = m->m_pkthdr.len;
1365 	padded = roundup(m->m_pkthdr.len, UAQ_TX_BUF_ALIGN);
1366 	if (((padded + sizeof(desc)) % sc->sc_out_frame_size) == 0) {
1367 		desc |= UAQ_TX_PKT_DROP_PADD;
1368 		padded += 8;
1369 	}
1370 
1371 	if (padded + sizeof(desc) > maxlen)
1372 		return (-1);
1373 
1374 #if NVLAN > 0
1375 	if (m->m_flags & M_VLANTAG)
1376 		desc |= (((uint64_t)m->m_pkthdr.ether_vtag) <<
1377 		    UAQ_TX_PKT_VLAN_SHIFT) | UAQ_TX_PKT_VLAN;
1378 #endif
1379 
1380 	htolem64((uint64_t *)buf, desc);
1381 	m_copydata(m, 0, m->m_pkthdr.len, buf + sizeof(desc));
1382 	return (padded + sizeof(desc));
1383 }
1384 
1385 int
1386 uaq_encap_xfer(struct uaq_softc *sc, struct uaq_chain *c)
1387 {
1388 	usbd_status	err;
1389 
1390 	usbd_setup_xfer(c->uc_xfer, sc->sc_ep[UAQ_ENDPT_TX], c, c->uc_buf,
1391 	    c->uc_buflen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 10000,
1392 	    uaq_txeof);
1393 
1394 	err = usbd_transfer(c->uc_xfer);
1395 	if (err != USBD_IN_PROGRESS) {
1396 		c->uc_cnt = 0;
1397 		c->uc_buflen = 0;
1398 		uaq_stop(sc);
1399 		return (EIO);
1400 	}
1401 
1402 	return (0);
1403 }
1404