1 /* $OpenBSD: if_uaq.c,v 1.1 2021/09/04 12:11:45 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 32768 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 if (ifp->if_flags & IFF_PROMISC || sc->sc_ac.ac_multirangecnt > 0) { 662 sc->sc_rxctl |= UAQ_SFR_RX_CTL_PRO; 663 } else if (ifp->if_flags & IFF_ALLMULTI || 664 sc->sc_ac.ac_multirangecnt > 0) { 665 sc->sc_rxctl |= UAQ_SFR_RX_CTL_AMALL; 666 } else if (sc->sc_ac.ac_multicnt > 0) { 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 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 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 return; 781 } 782 783 uaq_ifmedia_upd(ifp); 784 785 ifp->if_flags |= IFF_RUNNING; 786 ifq_clr_oactive(&ifp->if_snd); 787 788 splx(s); 789 } 790 791 int 792 uaq_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 793 { 794 struct uaq_softc *sc = ifp->if_softc; 795 struct ifreq *ifr = (struct ifreq *)data; 796 int s, error = 0; 797 798 s = splnet(); 799 800 switch (cmd) { 801 case SIOCSIFADDR: 802 ifp->if_flags |= IFF_UP; 803 if (!(ifp->if_flags & IFF_RUNNING)) 804 uaq_init(sc); 805 break; 806 807 case SIOCSIFFLAGS: 808 if (ifp->if_flags & IFF_UP) { 809 if (ifp->if_flags & IFF_RUNNING) 810 error = ENETRESET; 811 else 812 uaq_init(sc); 813 } else { 814 if (ifp->if_flags & IFF_RUNNING) 815 uaq_stop(sc); 816 } 817 break; 818 819 case SIOCGIFMEDIA: 820 case SIOCSIFMEDIA: 821 error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd); 822 break; 823 824 default: 825 error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); 826 } 827 828 if (error == ENETRESET) { 829 if (ifp->if_flags & IFF_RUNNING) 830 uaq_iff(sc); 831 error = 0; 832 } 833 834 splx(s); 835 836 return (error); 837 } 838 839 int 840 uaq_xfer_list_init(struct uaq_softc *sc, struct uaq_chain *ch, 841 uint32_t bufsize, int listlen) 842 { 843 struct uaq_chain *c; 844 int i; 845 846 for (i = 0; i < listlen; i++) { 847 c = &ch[i]; 848 c->uc_sc = sc; 849 c->uc_idx = i; 850 c->uc_buflen = 0; 851 c->uc_bufmax = bufsize; 852 c->uc_cnt = 0; 853 if (c->uc_xfer == NULL) { 854 c->uc_xfer = usbd_alloc_xfer(sc->sc_udev); 855 if (c->uc_xfer == NULL) 856 return (ENOBUFS); 857 858 c->uc_buf = usbd_alloc_buffer(c->uc_xfer, c->uc_bufmax); 859 if (c->uc_buf == NULL) { 860 usbd_free_xfer(c->uc_xfer); 861 c->uc_xfer = NULL; 862 return (ENOBUFS); 863 } 864 } 865 } 866 867 return (0); 868 } 869 870 void 871 uaq_xfer_list_free(struct uaq_softc *sc, struct uaq_chain *ch, int listlen) 872 { 873 int i; 874 875 for (i = 0; i < listlen; i++) { 876 if (ch[i].uc_buf != NULL) { 877 ch[i].uc_buf = NULL; 878 } 879 ch[i].uc_cnt = 0; 880 if (ch[i].uc_xfer != NULL) { 881 usbd_free_xfer(ch[i].uc_xfer); 882 ch[i].uc_xfer = NULL; 883 } 884 } 885 } 886 887 void 888 uaq_stop(struct uaq_softc *sc) 889 { 890 struct uaq_cdata *cd; 891 struct ifnet *ifp; 892 usbd_status err; 893 894 ifp = &sc->sc_ac.ac_if; 895 ifp->if_timer = 0; 896 ifp->if_flags &= ~IFF_RUNNING; 897 ifq_clr_oactive(&ifp->if_snd); 898 899 sc->sc_link_status = 0; 900 sc->sc_link_speed = 0; 901 902 if (sc->sc_ep[UAQ_ENDPT_RX] != NULL) { 903 err = usbd_close_pipe(sc->sc_ep[UAQ_ENDPT_RX]); 904 if (err) { 905 printf("%s: close rx pipe failed: %s\n", 906 sc->sc_dev.dv_xname, usbd_errstr(err)); 907 } 908 sc->sc_ep[UAQ_ENDPT_RX] = NULL; 909 } 910 911 if (sc->sc_ep[UAQ_ENDPT_TX] != NULL) { 912 err = usbd_close_pipe(sc->sc_ep[UAQ_ENDPT_TX]); 913 if (err) { 914 printf("%s: close tx pipe failed: %s\n", 915 sc->sc_dev.dv_xname, usbd_errstr(err)); 916 } 917 sc->sc_ep[UAQ_ENDPT_TX] = NULL; 918 } 919 920 if (sc->sc_ep[UAQ_ENDPT_INTR] != NULL) { 921 err = usbd_close_pipe(sc->sc_ep[UAQ_ENDPT_INTR]); 922 if (err) { 923 printf("%s: close intr pipe failed: %s\n", 924 sc->sc_dev.dv_xname, usbd_errstr(err)); 925 } 926 sc->sc_ep[UAQ_ENDPT_INTR] = NULL; 927 } 928 929 cd = &sc->sc_cdata; 930 uaq_xfer_list_free(sc, cd->uaq_rx_chain, UAQ_RX_LIST_CNT); 931 uaq_xfer_list_free(sc, cd->uaq_tx_chain, UAQ_TX_LIST_CNT); 932 } 933 934 void 935 uaq_link(struct uaq_softc *sc) 936 { 937 if (sc->sc_link_speed > 0) { 938 uint8_t resend[3] = { 0, 0xf8, 7 }; 939 uint8_t qctrl[5] = { 7, 0x00, 0x01, 0x1e, 0xff }; 940 uint8_t ipg = 0; 941 942 switch (sc->sc_link_speed) { 943 case UAQ_STATUS_SPEED_100M: 944 resend[1] = 0xfb; 945 resend[2] = 0x4; 946 break; 947 948 case UAQ_STATUS_SPEED_5G: 949 ipg = 5; 950 break; 951 } 952 953 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_IPG_0, 1, ipg); 954 955 uaq_write_mem(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_TX_PAUSE_RESEND_T, 956 3, resend, 3); 957 uaq_write_mem(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RX_BULKIN_QCTRL, 958 5, qctrl, 5); 959 uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_PAUSE_WATERLVL_LOW, 960 2, 0x0810); 961 962 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BMRX_DMA_CTRL, 1, 963 0); 964 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BMTX_DMA_CTRL, 1, 965 0); 966 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_ARC_CTRL, 1, 0); 967 968 sc->sc_rxctl = UAQ_SFR_RX_CTL_IPE | UAQ_SFR_RX_CTL_AB; 969 uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RX_CTL, 2, 970 sc->sc_rxctl); 971 972 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_ETH_MAC_PATH, 1, 973 UAQ_SFR_RX_PATH_READY); 974 975 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BULK_OUT_CTRL, 1, 976 UAQ_SFR_BULK_OUT_EFF_EN); 977 978 uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_MEDIUM_STATUS_MODE, 979 2, 0); 980 uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_MEDIUM_STATUS_MODE, 981 2, UAQ_SFR_MEDIUM_XGMIIMODE | UAQ_SFR_MEDIUM_FULL_DUPLEX | 982 UAQ_SFR_MEDIUM_RECEIVE_EN | UAQ_SFR_MEDIUM_RXFLOW_CTRLEN | 983 UAQ_SFR_MEDIUM_TXFLOW_CTRLEN); /* JUMBO_EN */ 984 985 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RXCOE_CTL, 1, 986 UAQ_SFR_RXCOE_IP | UAQ_SFR_RXCOE_TCP | UAQ_SFR_RXCOE_UDP | 987 UAQ_SFR_RXCOE_TCPV6 | UAQ_SFR_RXCOE_UDPV6); 988 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_TXCOE_CTL, 1, 989 UAQ_SFR_TXCOE_IP | UAQ_SFR_TXCOE_TCP | UAQ_SFR_TXCOE_UDP | 990 UAQ_SFR_TXCOE_TCPV6 | UAQ_SFR_TXCOE_UDPV6); 991 992 sc->sc_rxctl |= UAQ_SFR_RX_CTL_START; 993 uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RX_CTL, 2, 994 sc->sc_rxctl); 995 } else { 996 uint16_t mode; 997 998 mode = uaq_read_2(sc, UAQ_CMD_ACCESS_MAC, 999 UAQ_SFR_MEDIUM_STATUS_MODE, 2); 1000 mode &= ~UAQ_SFR_MEDIUM_RECEIVE_EN; 1001 uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_MEDIUM_STATUS_MODE, 1002 2, mode); 1003 1004 sc->sc_rxctl &= ~UAQ_SFR_RX_CTL_START; 1005 uaq_write_2(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_RX_CTL, 2, 1006 sc->sc_rxctl); 1007 1008 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BULK_OUT_CTRL, 1, 1009 UAQ_SFR_BULK_OUT_FLUSH_EN | UAQ_SFR_BULK_OUT_EFF_EN); 1010 1011 uaq_write_1(sc, UAQ_CMD_ACCESS_MAC, UAQ_SFR_BULK_OUT_CTRL, 1, 1012 UAQ_SFR_BULK_OUT_EFF_EN); 1013 } 1014 } 1015 1016 void 1017 uaq_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) 1018 { 1019 struct uaq_softc *sc = priv; 1020 struct ifnet *ifp = &sc->sc_ac.ac_if; 1021 uint64_t linkstatus; 1022 uint64_t baudrate; 1023 int link_state; 1024 1025 if (status == USBD_CANCELLED) 1026 return; 1027 1028 if (status != USBD_NORMAL_COMPLETION) { 1029 DPRINTFN(2, ("uaq_intr: status=%d\n", status)); 1030 if (status == USBD_STALLED) 1031 usbd_clear_endpoint_stall_async( 1032 sc->sc_ep[UAQ_ENDPT_INTR]); 1033 return; 1034 } 1035 1036 linkstatus = letoh64(sc->sc_link_status); 1037 DPRINTFN(1, ("uaq_intr: link status %llx\n", linkstatus)); 1038 1039 if (linkstatus & UAQ_STATUS_LINK) { 1040 link_state = LINK_STATE_FULL_DUPLEX; 1041 sc->sc_link_speed = (linkstatus & UAQ_STATUS_SPEED_MASK) 1042 >> UAQ_STATUS_SPEED_SHIFT; 1043 switch (sc->sc_link_speed) { 1044 case UAQ_STATUS_SPEED_5G: 1045 baudrate = IF_Gbps(5); 1046 break; 1047 case UAQ_STATUS_SPEED_2_5G: 1048 baudrate = IF_Mbps(2500); 1049 break; 1050 case UAQ_STATUS_SPEED_1G: 1051 baudrate = IF_Gbps(1); 1052 break; 1053 case UAQ_STATUS_SPEED_100M: 1054 baudrate = IF_Mbps(100); 1055 break; 1056 default: 1057 baudrate = 0; 1058 break; 1059 } 1060 1061 ifp->if_baudrate = baudrate; 1062 } else { 1063 link_state = LINK_STATE_DOWN; 1064 sc->sc_link_speed = 0; 1065 } 1066 1067 if (link_state != ifp->if_link_state) { 1068 ifp->if_link_state = link_state; 1069 if_link_state_change(ifp); 1070 usb_add_task(sc->sc_udev, &sc->sc_link_task); 1071 } 1072 } 1073 1074 void 1075 uaq_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1076 { 1077 struct uaq_chain *c = (struct uaq_chain *)priv; 1078 struct uaq_softc *sc = c->uc_sc; 1079 struct ifnet *ifp = &sc->sc_ac.ac_if; 1080 uint8_t *buf; 1081 uint64_t *pdesc; 1082 uint64_t desc; 1083 uint32_t total_len; 1084 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 1085 struct mbuf *m; 1086 int pktlen, s; 1087 int count, offset; 1088 1089 if (usbd_is_dying(sc->sc_udev)) 1090 return; 1091 1092 if (!(ifp->if_flags & IFF_RUNNING)) 1093 return; 1094 1095 if (status != USBD_NORMAL_COMPLETION) { 1096 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1097 return; 1098 if (usbd_ratecheck(&sc->sc_rx_notice)) { 1099 printf("%s: usb errors on rx: %s\n", 1100 sc->sc_dev.dv_xname, usbd_errstr(status)); 1101 } 1102 if (status == USBD_STALLED) 1103 usbd_clear_endpoint_stall_async( 1104 sc->sc_ep[UAQ_ENDPT_RX]); 1105 goto done; 1106 } 1107 1108 usbd_get_xfer_status(xfer, NULL, (void **)&buf, &total_len, NULL); 1109 DPRINTFN(3, ("received %d bytes\n", total_len)); 1110 if ((total_len & 7) != 0) { 1111 printf("%s: weird rx transfer length %d\n", 1112 sc->sc_dev.dv_xname, total_len); 1113 goto done; 1114 } 1115 1116 pdesc = (uint64_t *)(buf + (total_len - sizeof(desc))); 1117 desc = lemtoh64(pdesc); 1118 1119 count = desc & UAQ_RX_HDR_COUNT_MASK; 1120 if (count == 0) 1121 goto done; 1122 1123 /* get offset of packet headers */ 1124 offset = total_len - ((count + 1) * sizeof(desc)); 1125 if (offset != ((desc & UAQ_RX_HDR_OFFSET_MASK) >> 1126 UAQ_RX_HDR_OFFSET_SHIFT)) { 1127 printf("%s: offset mismatch, got %d expected %lld\n", 1128 sc->sc_dev.dv_xname, offset, 1129 desc >> UAQ_RX_HDR_OFFSET_SHIFT); 1130 goto done; 1131 } 1132 if (offset < 0 || offset > total_len) { 1133 printf("%s: offset %d outside buffer (%d)\n", 1134 sc->sc_dev.dv_xname, offset, total_len); 1135 goto done; 1136 } 1137 1138 pdesc = (uint64_t *)(buf + offset); 1139 total_len = offset; 1140 1141 while (count-- > 0) { 1142 desc = lemtoh64(pdesc); 1143 pdesc++; 1144 1145 pktlen = (desc & UAQ_RX_PKT_LEN_MASK) >> UAQ_RX_PKT_LEN_SHIFT; 1146 if (pktlen > total_len) { 1147 DPRINTFN(2, ("not enough bytes for this packet\n")); 1148 ifp->if_ierrors++; 1149 goto done; 1150 } 1151 1152 m = m_devget(buf + 2, pktlen - 2, ETHER_ALIGN); 1153 if (m == NULL) { 1154 DPRINTFN(2, ("m_devget failed for this packet\n")); 1155 ifp->if_ierrors++; 1156 goto done; 1157 } 1158 1159 if ((desc & UAQ_RX_PKT_L3_ERR) == 0) 1160 m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK; 1161 1162 if ((desc & UAQ_RX_PKT_L4_ERR) == 0) 1163 m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK | 1164 M_UDP_CSUM_IN_OK; 1165 1166 #if NVLAN > 0 1167 if (desc & UAQ_RX_PKT_VLAN) { 1168 m->m_pkthdr.ether_vtag = (desc >> UAQ_RX_PKT_VLAN_SHIFT) & 1169 0xfff; 1170 m->m_flags |= M_VLANTAG; 1171 } 1172 #endif 1173 ml_enqueue(&ml, m); 1174 1175 total_len -= roundup(pktlen, UAQ_RX_BUF_ALIGN); 1176 buf += roundup(pktlen, UAQ_RX_BUF_ALIGN); 1177 } 1178 1179 done: 1180 s = splnet(); 1181 if_input(ifp, &ml); 1182 splx(s); 1183 memset(c->uc_buf, 0, UAQ_RX_BUFSZ); 1184 1185 usbd_setup_xfer(xfer, sc->sc_ep[UAQ_ENDPT_RX], c, c->uc_buf, 1186 UAQ_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 1187 USBD_NO_TIMEOUT, uaq_rxeof); 1188 usbd_transfer(xfer); 1189 } 1190 1191 1192 void 1193 uaq_watchdog(struct ifnet *ifp) 1194 { 1195 struct uaq_softc *sc = ifp->if_softc; 1196 struct uaq_chain *c; 1197 usbd_status err; 1198 int i, s; 1199 1200 ifp->if_timer = 0; 1201 1202 if (usbd_is_dying(sc->sc_udev)) 1203 return; 1204 1205 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) 1206 return; 1207 1208 sc = ifp->if_softc; 1209 s = splnet(); 1210 1211 ifp->if_oerrors++; 1212 DPRINTF(("%s: watchdog timeout\n", sc->sc_dev.dv_xname)); 1213 1214 for (i = 0; i < UAQ_TX_LIST_CNT; i++) { 1215 c = &sc->sc_cdata.uaq_tx_chain[i]; 1216 if (c->uc_cnt > 0) { 1217 usbd_get_xfer_status(c->uc_xfer, NULL, NULL, NULL, 1218 &err); 1219 uaq_txeof(c->uc_xfer, c, err); 1220 } 1221 } 1222 1223 if (ifq_is_oactive(&ifp->if_snd)) 1224 ifq_restart(&ifp->if_snd); 1225 splx(s); 1226 } 1227 1228 void 1229 uaq_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1230 { 1231 struct uaq_softc *sc; 1232 struct uaq_chain *c; 1233 struct ifnet *ifp; 1234 int s; 1235 1236 c = priv; 1237 sc = c->uc_sc; 1238 ifp = &sc->sc_ac.ac_if; 1239 1240 if (usbd_is_dying(sc->sc_udev)) 1241 return; 1242 1243 if (status != USBD_NORMAL_COMPLETION) 1244 DPRINTF(("%s: %s uc_idx=%u : %s\n", sc->sc_dev.dv_xname, 1245 __func__, c->uc_idx, usbd_errstr(status))); 1246 else 1247 DPRINTF(("%s: txeof\n", sc->sc_dev.dv_xname)); 1248 1249 s = splnet(); 1250 1251 c->uc_cnt = 0; 1252 c->uc_buflen = 0; 1253 1254 SLIST_INSERT_HEAD(&sc->sc_cdata.uaq_tx_free, c, uc_list); 1255 1256 if (status != USBD_NORMAL_COMPLETION) { 1257 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 1258 splx(s); 1259 return; 1260 } 1261 1262 ifp->if_oerrors++; 1263 printf("%s: usb error on tx: %s\n", sc->sc_dev.dv_xname, 1264 usbd_errstr(status)); 1265 1266 if (status == USBD_STALLED) 1267 usbd_clear_endpoint_stall_async( 1268 sc->sc_ep[UAQ_ENDPT_TX]); 1269 splx(s); 1270 return; 1271 } 1272 1273 ifp->if_timer = 0; 1274 if (ifq_is_oactive(&ifp->if_snd)) 1275 ifq_restart(&ifp->if_snd); 1276 splx(s); 1277 } 1278 1279 void 1280 uaq_start(struct ifnet *ifp) 1281 { 1282 struct uaq_softc *sc = ifp->if_softc; 1283 struct uaq_cdata *cd = &sc->sc_cdata; 1284 struct uaq_chain *c; 1285 struct mbuf *m = NULL; 1286 int s, mlen; 1287 1288 if ((sc->sc_link_speed == 0) || 1289 (ifp->if_flags & (IFF_RUNNING|IFF_UP)) != 1290 (IFF_RUNNING|IFF_UP)) { 1291 return; 1292 } 1293 1294 s = splnet(); 1295 1296 c = SLIST_FIRST(&cd->uaq_tx_free); 1297 while (c != NULL) { 1298 m = ifq_deq_begin(&ifp->if_snd); 1299 if (m == NULL) 1300 break; 1301 1302 mlen = m->m_pkthdr.len; 1303 1304 /* Discard packet larger than buffer. */ 1305 if (mlen + sizeof(uint64_t) >= c->uc_bufmax) { 1306 ifq_deq_commit(&ifp->if_snd, m); 1307 m_freem(m); 1308 ifp->if_oerrors++; 1309 continue; 1310 } 1311 1312 /* Append packet to current buffer. */ 1313 mlen = uaq_encap_txpkt(sc, m, c->uc_buf + c->uc_buflen, 1314 c->uc_bufmax - c->uc_buflen); 1315 if (mlen <= 0) { 1316 ifq_deq_rollback(&ifp->if_snd, m); 1317 break; 1318 } 1319 1320 ifq_deq_commit(&ifp->if_snd, m); 1321 c->uc_cnt += 1; 1322 c->uc_buflen += mlen; 1323 1324 #if NBPFILTER > 0 1325 if (ifp->if_bpf) 1326 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 1327 #endif 1328 1329 m_freem(m); 1330 } 1331 1332 if (c != NULL) { 1333 /* Send current buffer unless empty */ 1334 if (c->uc_buflen > 0 && c->uc_cnt > 0) { 1335 SLIST_REMOVE_HEAD(&cd->uaq_tx_free, uc_list); 1336 if (uaq_encap_xfer(sc, c)) { 1337 SLIST_INSERT_HEAD(&cd->uaq_tx_free, c, 1338 uc_list); 1339 } 1340 c = SLIST_FIRST(&cd->uaq_tx_free); 1341 1342 ifp->if_timer = 5; 1343 if (c == NULL) 1344 ifq_set_oactive(&ifp->if_snd); 1345 } 1346 } 1347 1348 splx(s); 1349 } 1350 1351 int 1352 uaq_encap_txpkt(struct uaq_softc *sc, struct mbuf *m, char *buf, 1353 uint32_t maxlen) 1354 { 1355 uint64_t desc; 1356 int padded; 1357 1358 desc = m->m_pkthdr.len; 1359 padded = roundup(m->m_pkthdr.len, UAQ_TX_BUF_ALIGN); 1360 if (((padded + sizeof(desc)) % sc->sc_out_frame_size) == 0) { 1361 desc |= UAQ_TX_PKT_DROP_PADD; 1362 padded += 8; 1363 } 1364 1365 if (padded + sizeof(desc) > maxlen) 1366 return (-1); 1367 1368 #if NVLAN > 0 1369 if (m->m_flags & M_VLANTAG) 1370 desc |= (((uint64_t)m->m_pkthdr.ether_vtag) << 1371 UAQ_TX_PKT_VLAN_SHIFT) | UAQ_TX_PKT_VLAN; 1372 #endif 1373 1374 htolem64((uint64_t *)buf, desc); 1375 m_copydata(m, 0, m->m_pkthdr.len, buf + sizeof(desc)); 1376 return (padded + sizeof(desc)); 1377 } 1378 1379 int 1380 uaq_encap_xfer(struct uaq_softc *sc, struct uaq_chain *c) 1381 { 1382 usbd_status err; 1383 1384 usbd_setup_xfer(c->uc_xfer, sc->sc_ep[UAQ_ENDPT_TX], c, c->uc_buf, 1385 c->uc_buflen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 10000, 1386 uaq_txeof); 1387 1388 err = usbd_transfer(c->uc_xfer); 1389 if (err != USBD_IN_PROGRESS) { 1390 c->uc_cnt = 0; 1391 c->uc_buflen = 0; 1392 uaq_stop(sc); 1393 return (EIO); 1394 } 1395 1396 return (0); 1397 } 1398