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