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