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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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