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