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