1 /* $NetBSD: if_aue.c,v 1.191 2022/08/20 14:08:59 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 1997, 1998, 1999, 2000 5 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Bill Paul. 18 * 4. Neither the name of the author nor the names of any co-contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 * THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.11 2000/01/14 01:36:14 wpaul Exp $ 35 */ 36 37 /* 38 * ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver. 39 * Datasheet is available from http://www.admtek.com.tw. 40 * 41 * Written by Bill Paul <wpaul@ee.columbia.edu> 42 * Electrical Engineering Department 43 * Columbia University, New York City 44 */ 45 46 /* 47 * The Pegasus chip uses four USB "endpoints" to provide 10/100 ethernet 48 * support: the control endpoint for reading/writing registers, burst 49 * read endpoint for packet reception, burst write for packet transmission 50 * and one for "interrupts." The chip uses the same RX filter scheme 51 * as the other ADMtek ethernet parts: one perfect filter entry for the 52 * the station address and a 64-bit multicast hash table. The chip supports 53 * both MII and HomePNA attachments. 54 * 55 * Since the maximum data transfer speed of USB is supposed to be 12Mbps, 56 * you're never really going to get 100Mbps speeds from this device. I 57 * think the idea is to allow the device to connect to 10 or 100Mbps 58 * networks, not necessarily to provide 100Mbps performance. Also, since 59 * the controller uses an external PHY chip, it's possible that board 60 * designers might simply choose a 10Mbps PHY. 61 * 62 * Registers are accessed using usbd_do_request(). Packet transfers are 63 * done using usbd_transfer() and friends. 64 */ 65 66 /* 67 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. 68 */ 69 70 /* 71 * TODO: 72 * better error messages from rxstat 73 * more error checks 74 * investigate short rx problem 75 * proper cleanup on errors 76 */ 77 78 #include <sys/cdefs.h> 79 __KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.191 2022/08/20 14:08:59 riastradh Exp $"); 80 81 #ifdef _KERNEL_OPT 82 #include "opt_usb.h" 83 #include "opt_inet.h" 84 #endif 85 86 #include <sys/param.h> 87 88 #include <dev/usb/usbnet.h> 89 #include <dev/usb/usbhist.h> 90 #include <dev/usb/if_auereg.h> 91 92 #ifdef INET 93 #include <netinet/in.h> 94 #include <netinet/if_inarp.h> 95 #endif 96 97 #ifdef USB_DEBUG 98 #ifndef AUE_DEBUG 99 #define auedebug 0 100 #else 101 static int auedebug = 10; 102 103 SYSCTL_SETUP(sysctl_hw_aue_setup, "sysctl hw.aue setup") 104 { 105 int err; 106 const struct sysctlnode *rnode; 107 const struct sysctlnode *cnode; 108 109 err = sysctl_createv(clog, 0, NULL, &rnode, 110 CTLFLAG_PERMANENT, CTLTYPE_NODE, "aue", 111 SYSCTL_DESCR("aue global controls"), 112 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 113 114 if (err) 115 goto fail; 116 117 /* control debugging printfs */ 118 err = sysctl_createv(clog, 0, &rnode, &cnode, 119 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 120 "debug", SYSCTL_DESCR("Enable debugging output"), 121 NULL, 0, &auedebug, sizeof(auedebug), CTL_CREATE, CTL_EOL); 122 if (err) 123 goto fail; 124 125 return; 126 fail: 127 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 128 } 129 130 #endif /* AUE_DEBUG */ 131 #endif /* USB_DEBUG */ 132 133 #define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(auedebug,1,FMT,A,B,C,D) 134 #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(auedebug,N,FMT,A,B,C,D) 135 #define AUEHIST_FUNC() USBHIST_FUNC() 136 #define AUEHIST_CALLED(name) USBHIST_CALLED(auedebug) 137 #define AUEHIST_CALLARGS(FMT,A,B,C,D) \ 138 USBHIST_CALLARGS(auedebug,FMT,A,B,C,D) 139 #define AUEHIST_CALLARGSN(N,FMT,A,B,C,D) \ 140 USBHIST_CALLARGSN(auedebug,N,FMT,A,B,C,D) 141 142 #define AUE_TX_LIST_CNT 1 143 #define AUE_RX_LIST_CNT 1 144 145 struct aue_softc { 146 struct usbnet aue_un; 147 struct usbnet_intr aue_intr; 148 struct aue_intrpkt aue_ibuf; 149 }; 150 151 #define AUE_TIMEOUT 1000 152 #define AUE_BUFSZ 1536 153 #define AUE_MIN_FRAMELEN 60 154 #define AUE_TX_TIMEOUT 10000 /* ms */ 155 #define AUE_INTR_INTERVAL 100 /* ms */ 156 157 /* 158 * Various supported device vendors/products. 159 */ 160 struct aue_type { 161 struct usb_devno aue_dev; 162 uint16_t aue_flags; 163 #define LSYS 0x0001 /* use Linksys reset */ 164 #define PNA 0x0002 /* has Home PNA */ 165 #define PII 0x0004 /* Pegasus II chip */ 166 }; 167 168 static const struct aue_type aue_devs[] = { 169 {{ USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B}, PII }, 170 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1}, PNA | PII }, 171 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2}, PII }, 172 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000}, LSYS }, 173 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4}, PNA }, 174 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5}, PNA }, 175 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6}, PII }, 176 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7}, PII }, 177 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8}, PII }, 178 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9}, PNA }, 179 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10}, 0 }, 180 {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA}, 0 }, 181 {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC}, 0 }, 182 {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001}, PII }, 183 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS}, PNA }, 184 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII}, PII }, 185 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2}, PII }, 186 {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3}, PII }, 187 {{ USB_VENDOR_AEI, USB_PRODUCT_AEI_USBTOLAN}, PII }, 188 {{ USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2LAN}, PII }, 189 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100}, 0 }, 190 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100}, PNA }, 191 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBEL100}, 0 }, 192 {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBE100}, PII }, 193 {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_HNE200}, PII }, 194 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX}, 0 }, 195 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXS},PII }, 196 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4}, LSYS | PII }, 197 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX1}, LSYS }, 198 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX}, LSYS }, 199 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA}, PNA }, 200 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3}, LSYS | PII }, 201 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2}, LSYS | PII }, 202 {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650}, 0 }, 203 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0}, 0 }, 204 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1}, LSYS }, 205 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2}, 0 }, 206 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3}, LSYS }, 207 {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX}, PII }, 208 {{ USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET}, 0 }, 209 {{ USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100}, PII }, 210 {{ USB_VENDOR_HP, USB_PRODUCT_HP_HN210E}, PII }, 211 {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX}, 0 }, 212 {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTXS}, PII }, 213 {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETXUS2}, PII }, 214 {{ USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_KNU101TX}, 0 }, 215 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX1}, LSYS | PII }, 216 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T}, LSYS }, 217 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX}, LSYS }, 218 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1}, LSYS | PNA }, 219 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA}, LSYS }, 220 {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2}, LSYS | PII }, 221 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1}, 0 }, 222 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5}, 0 }, 223 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5}, PII }, 224 {{ USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110}, PII }, 225 {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101}, PII }, 226 {{ USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM}, PII }, 227 {{ USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC},PII }, 228 {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB}, 0 }, 229 {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB}, PII }, 230 {{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100}, 0 }, 231 }; 232 #define aue_lookup(v, p) ((const struct aue_type *)usb_lookup(aue_devs, v, p)) 233 234 static int aue_match(device_t, cfdata_t, void *); 235 static void aue_attach(device_t, device_t, void *); 236 237 CFATTACH_DECL_NEW(aue, sizeof(struct aue_softc), aue_match, aue_attach, 238 usbnet_detach, usbnet_activate); 239 240 static void aue_reset_pegasus_II(struct aue_softc *); 241 242 static void aue_uno_stop(struct ifnet *, int); 243 static void aue_uno_mcast(struct ifnet *); 244 static int aue_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 245 static int aue_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 246 static void aue_uno_mii_statchg(struct ifnet *); 247 static unsigned aue_uno_tx_prepare(struct usbnet *, struct mbuf *, 248 struct usbnet_chain *); 249 static void aue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 250 static int aue_uno_init(struct ifnet *); 251 static void aue_uno_intr(struct usbnet *, usbd_status); 252 253 static const struct usbnet_ops aue_ops = { 254 .uno_stop = aue_uno_stop, 255 .uno_mcast = aue_uno_mcast, 256 .uno_read_reg = aue_uno_mii_read_reg, 257 .uno_write_reg = aue_uno_mii_write_reg, 258 .uno_statchg = aue_uno_mii_statchg, 259 .uno_tx_prepare = aue_uno_tx_prepare, 260 .uno_rx_loop = aue_uno_rx_loop, 261 .uno_init = aue_uno_init, 262 .uno_intr = aue_uno_intr, 263 }; 264 265 static uint32_t aue_crc(void *); 266 static void aue_reset(struct aue_softc *); 267 268 static int aue_csr_read_1(struct aue_softc *, int); 269 static int aue_csr_write_1(struct aue_softc *, int, int); 270 static int aue_csr_read_2(struct aue_softc *, int); 271 static int aue_csr_write_2(struct aue_softc *, int, int); 272 273 #define AUE_SETBIT(sc, reg, x) \ 274 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x)) 275 276 #define AUE_CLRBIT(sc, reg, x) \ 277 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x)) 278 279 static int 280 aue_csr_read_1(struct aue_softc *sc, int reg) 281 { 282 struct usbnet * const un = &sc->aue_un; 283 usb_device_request_t req; 284 usbd_status err; 285 uByte val = 0; 286 287 if (usbnet_isdying(un)) 288 return 0; 289 290 req.bmRequestType = UT_READ_VENDOR_DEVICE; 291 req.bRequest = AUE_UR_READREG; 292 USETW(req.wValue, 0); 293 USETW(req.wIndex, reg); 294 USETW(req.wLength, 1); 295 296 err = usbd_do_request(un->un_udev, &req, &val); 297 298 if (err) { 299 AUEHIST_FUNC(); 300 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 301 device_unit(un->un_dev), reg, err, 0); 302 return 0; 303 } 304 305 return val; 306 } 307 308 static int 309 aue_csr_read_2(struct aue_softc *sc, int reg) 310 { 311 struct usbnet * const un = &sc->aue_un; 312 usb_device_request_t req; 313 usbd_status err; 314 uWord val; 315 316 if (usbnet_isdying(un)) 317 return 0; 318 319 req.bmRequestType = UT_READ_VENDOR_DEVICE; 320 req.bRequest = AUE_UR_READREG; 321 USETW(req.wValue, 0); 322 USETW(req.wIndex, reg); 323 USETW(req.wLength, 2); 324 325 err = usbd_do_request(un->un_udev, &req, &val); 326 327 if (err) { 328 AUEHIST_FUNC(); 329 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 330 device_unit(un->un_dev), reg, err, 0); 331 return 0; 332 } 333 334 return UGETW(val); 335 } 336 337 static int 338 aue_csr_write_1(struct aue_softc *sc, int reg, int aval) 339 { 340 struct usbnet * const un = &sc->aue_un; 341 usb_device_request_t req; 342 usbd_status err; 343 uByte val; 344 345 if (usbnet_isdying(un)) 346 return 0; 347 348 val = aval; 349 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 350 req.bRequest = AUE_UR_WRITEREG; 351 USETW(req.wValue, val); 352 USETW(req.wIndex, reg); 353 USETW(req.wLength, 1); 354 355 err = usbd_do_request(un->un_udev, &req, &val); 356 357 if (err) { 358 AUEHIST_FUNC(); 359 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 360 device_unit(un->un_dev), reg, err, 0); 361 return -1; 362 } 363 364 return 0; 365 } 366 367 static int 368 aue_csr_write_2(struct aue_softc *sc, int reg, int aval) 369 { 370 struct usbnet * const un = &sc->aue_un; 371 usb_device_request_t req; 372 usbd_status err; 373 uWord val; 374 375 if (usbnet_isdying(un)) 376 return 0; 377 378 USETW(val, aval); 379 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 380 req.bRequest = AUE_UR_WRITEREG; 381 USETW(req.wValue, aval); 382 USETW(req.wIndex, reg); 383 USETW(req.wLength, 2); 384 385 err = usbd_do_request(un->un_udev, &req, &val); 386 387 if (err) { 388 AUEHIST_FUNC(); 389 AUEHIST_CALLARGS("aue%jd: reg=%#jx err=%jd", 390 device_unit(un->un_dev), reg, err, 0); 391 return -1; 392 } 393 394 return 0; 395 } 396 397 /* 398 * Read a word of data stored in the EEPROM at address 'addr.' 399 */ 400 static int 401 aue_eeprom_getword(struct aue_softc *sc, int addr) 402 { 403 struct usbnet * const un = &sc->aue_un; 404 int i; 405 406 AUEHIST_FUNC(); AUEHIST_CALLED(); 407 408 aue_csr_write_1(sc, AUE_EE_REG, addr); 409 aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ); 410 411 for (i = 0; i < AUE_TIMEOUT; i++) { 412 if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE) 413 break; 414 } 415 416 if (i == AUE_TIMEOUT) { 417 printf("%s: EEPROM read timed out\n", 418 device_xname(un->un_dev)); 419 } 420 421 return aue_csr_read_2(sc, AUE_EE_DATA); 422 } 423 424 /* 425 * Read the MAC from the EEPROM. It's at offset 0. 426 */ 427 static void 428 aue_read_mac(struct usbnet *un) 429 { 430 struct aue_softc *sc = usbnet_softc(un); 431 int i; 432 int off = 0; 433 int word; 434 435 AUEHIST_FUNC(); 436 AUEHIST_CALLARGS("aue%jd: enter", 437 device_unit(un->un_dev), 0, 0, 0); 438 439 for (i = 0; i < 3; i++) { 440 word = aue_eeprom_getword(sc, off + i); 441 un->un_eaddr[2 * i] = (u_char)word; 442 un->un_eaddr[2 * i + 1] = (u_char)(word >> 8); 443 } 444 } 445 446 static int 447 aue_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 448 { 449 struct aue_softc *sc = usbnet_softc(un); 450 int i; 451 452 AUEHIST_FUNC(); 453 454 #if 0 455 /* 456 * The Am79C901 HomePNA PHY actually contains 457 * two transceivers: a 1Mbps HomePNA PHY and a 458 * 10Mbps full/half duplex ethernet PHY with 459 * NWAY autoneg. However in the ADMtek adapter, 460 * only the 1Mbps PHY is actually connected to 461 * anything, so we ignore the 10Mbps one. It 462 * happens to be configured for MII address 3, 463 * so we filter that out. 464 */ 465 if (sc->aue_vendor == USB_VENDOR_ADMTEK && 466 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { 467 if (phy == 3) { 468 *val = 0; 469 return EINVAL; 470 } 471 } 472 #endif 473 474 aue_csr_write_1(sc, AUE_PHY_ADDR, phy); 475 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ); 476 477 for (i = 0; i < AUE_TIMEOUT; i++) { 478 if (usbnet_isdying(un)) { 479 *val = 0; 480 return ENXIO; 481 } 482 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) 483 break; 484 } 485 486 if (i == AUE_TIMEOUT) { 487 AUEHIST_CALLARGS("aue%jd: phy=%#jx reg=%#jx read timed out", 488 device_unit(un->un_dev), phy, reg, 0); 489 *val = 0; 490 return ETIMEDOUT; 491 } 492 493 *val = aue_csr_read_2(sc, AUE_PHY_DATA); 494 495 AUEHIST_CALLARGSN(11, "aue%jd: phy=%#jx reg=%#jx => 0x%04jx", 496 device_unit(un->un_dev), phy, reg, *val); 497 498 return 0; 499 } 500 501 static int 502 aue_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 503 { 504 struct aue_softc *sc = usbnet_softc(un); 505 int i; 506 507 AUEHIST_FUNC(); 508 AUEHIST_CALLARGSN(11, "aue%jd: phy=%jd reg=%jd data=0x%04jx", 509 device_unit(un->un_dev), phy, reg, val); 510 511 #if 0 512 if (sc->aue_vendor == USB_VENDOR_ADMTEK && 513 sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { 514 if (phy == 3) 515 return EINVAL; 516 } 517 #endif 518 519 aue_csr_write_2(sc, AUE_PHY_DATA, val); 520 aue_csr_write_1(sc, AUE_PHY_ADDR, phy); 521 aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE); 522 523 for (i = 0; i < AUE_TIMEOUT; i++) { 524 if (usbnet_isdying(un)) 525 return ENXIO; 526 if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) 527 break; 528 } 529 530 if (i == AUE_TIMEOUT) { 531 DPRINTF("aue%jd: phy=%#jx reg=%#jx val=%#jx write timed out", 532 device_unit(un->un_dev), phy, reg, val); 533 return ETIMEDOUT; 534 } 535 536 return 0; 537 } 538 539 static void 540 aue_uno_mii_statchg(struct ifnet *ifp) 541 { 542 struct usbnet *un = ifp->if_softc; 543 struct aue_softc *sc = usbnet_softc(un); 544 struct mii_data *mii = usbnet_mii(un); 545 const bool hadlink __diagused = usbnet_havelink(un); 546 547 AUEHIST_FUNC(); AUEHIST_CALLED(); 548 AUEHIST_CALLARGSN(5, "aue%jd: ifp=%#jx link=%jd", 549 device_unit(un->un_dev), (uintptr_t)ifp, hadlink, 0); 550 551 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); 552 553 if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) { 554 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); 555 } else { 556 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); 557 } 558 559 if ((mii->mii_media_active & IFM_FDX) != 0) 560 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); 561 else 562 AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); 563 564 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); 565 566 if (mii->mii_media_status & IFM_ACTIVE && 567 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 568 usbnet_set_link(un, true); 569 } 570 571 /* 572 * Set the LED modes on the LinkSys adapter. 573 * This turns on the 'dual link LED' bin in the auxmode 574 * register of the Broadcom PHY. 575 */ 576 if (!usbnet_isdying(un) && (un->un_flags & LSYS)) { 577 uint16_t auxmode; 578 aue_uno_mii_read_reg(un, 0, 0x1b, &auxmode); 579 aue_uno_mii_write_reg(un, 0, 0x1b, auxmode | 0x04); 580 } 581 582 if (usbnet_havelink(un) != hadlink) { 583 DPRINTFN(5, "aue%jd: exit link %jd", 584 device_unit(un->un_dev), usbnet_havelink(un), 0, 0); 585 } 586 } 587 588 #define AUE_POLY 0xEDB88320 589 #define AUE_BITS 6 590 591 static uint32_t 592 aue_crc(void *addrv) 593 { 594 uint32_t idx, bit, data, crc; 595 char *addr = addrv; 596 597 /* Compute CRC for the address value. */ 598 crc = 0xFFFFFFFF; /* initial value */ 599 600 for (idx = 0; idx < 6; idx++) { 601 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) 602 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? AUE_POLY : 0); 603 } 604 605 return crc & ((1 << AUE_BITS) - 1); 606 } 607 608 static void 609 aue_uno_mcast(struct ifnet *ifp) 610 { 611 struct usbnet * const un = ifp->if_softc; 612 struct aue_softc * const sc = usbnet_softc(un); 613 struct ethercom * ec = usbnet_ec(un); 614 struct ether_multi *enm; 615 struct ether_multistep step; 616 uint32_t h = 0, i; 617 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 618 619 AUEHIST_FUNC(); 620 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); 621 622 if (usbnet_ispromisc(un)) { 623 ETHER_LOCK(ec); 624 allmulti: 625 ec->ec_flags |= ETHER_F_ALLMULTI; 626 ETHER_UNLOCK(ec); 627 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); 628 return; 629 } 630 631 /* now program new ones */ 632 ETHER_LOCK(ec); 633 ETHER_FIRST_MULTI(step, ec, enm); 634 while (enm != NULL) { 635 if (memcmp(enm->enm_addrlo, 636 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) { 637 goto allmulti; 638 } 639 640 h = aue_crc(enm->enm_addrlo); 641 hashtbl[h >> 3] |= 1 << (h & 0x7); 642 ETHER_NEXT_MULTI(step, enm); 643 } 644 ec->ec_flags &= ~ETHER_F_ALLMULTI; 645 ETHER_UNLOCK(ec); 646 647 AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); 648 649 /* write the hashtable */ 650 for (i = 0; i < 8; i++) 651 aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]); 652 } 653 654 static void 655 aue_reset_pegasus_II(struct aue_softc *sc) 656 { 657 /* Magic constants taken from Linux driver. */ 658 aue_csr_write_1(sc, AUE_REG_1D, 0); 659 aue_csr_write_1(sc, AUE_REG_7B, 2); 660 #if 0 661 if ((un->un_flags & PNA) && mii_mode) 662 aue_csr_write_1(sc, AUE_REG_81, 6); 663 else 664 #endif 665 aue_csr_write_1(sc, AUE_REG_81, 2); 666 } 667 668 static void 669 aue_reset(struct aue_softc *sc) 670 { 671 struct usbnet * const un = &sc->aue_un; 672 int i; 673 674 AUEHIST_FUNC(); 675 AUEHIST_CALLARGSN(2, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); 676 677 AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC); 678 679 for (i = 0; i < AUE_TIMEOUT; i++) { 680 if (usbnet_isdying(un)) 681 return; 682 if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC)) 683 break; 684 } 685 686 if (i == AUE_TIMEOUT) 687 printf("%s: reset failed\n", device_xname(un->un_dev)); 688 689 #if 0 690 /* XXX what is mii_mode supposed to be */ 691 if (sc->sc_mii_mode && (un->un_flags & PNA)) 692 aue_csr_write_1(sc, AUE_GPIO1, 0x34); 693 else 694 aue_csr_write_1(sc, AUE_GPIO1, 0x26); 695 #endif 696 697 /* 698 * The PHY(s) attached to the Pegasus chip may be held 699 * in reset until we flip on the GPIO outputs. Make sure 700 * to set the GPIO pins high so that the PHY(s) will 701 * be enabled. 702 * 703 * Note: We force all of the GPIO pins low first, *then* 704 * enable the ones we want. 705 */ 706 if (un->un_flags & LSYS) { 707 /* Grrr. LinkSys has to be different from everyone else. */ 708 aue_csr_write_1(sc, AUE_GPIO0, 709 AUE_GPIO_SEL0 | AUE_GPIO_SEL1); 710 } else { 711 aue_csr_write_1(sc, AUE_GPIO0, 712 AUE_GPIO_OUT0 | AUE_GPIO_SEL0); 713 } 714 aue_csr_write_1(sc, AUE_GPIO0, 715 AUE_GPIO_OUT0 | AUE_GPIO_SEL0 | AUE_GPIO_SEL1); 716 717 if (un->un_flags & PII) 718 aue_reset_pegasus_II(sc); 719 720 /* Wait a little while for the chip to get its brains in order. */ 721 delay(10000); /* XXX */ 722 //usbd_delay_ms(un->un_udev, 10); /* XXX */ 723 724 DPRINTFN(2, "aue%jd: exit", device_unit(un->un_dev), 0, 0, 0); 725 } 726 727 /* 728 * Probe for a Pegasus chip. 729 */ 730 static int 731 aue_match(device_t parent, cfdata_t match, void *aux) 732 { 733 struct usb_attach_arg *uaa = aux; 734 735 /* 736 * Some manufacturers use the same vendor and product id for 737 * different devices. We need to sanity check the DeviceClass 738 * in this case 739 * Currently known guilty products: 740 * 0x050d/0x0121 Belkin Bluetooth and USB2LAN 741 * 742 * If this turns out to be more common, we could use a quirk 743 * table. 744 */ 745 if (uaa->uaa_vendor == USB_VENDOR_BELKIN && 746 uaa->uaa_product == USB_PRODUCT_BELKIN_USB2LAN) { 747 usb_device_descriptor_t *dd; 748 749 dd = usbd_get_device_descriptor(uaa->uaa_device); 750 if (dd != NULL && 751 dd->bDeviceClass != UDCLASS_IN_INTERFACE) 752 return UMATCH_NONE; 753 } 754 755 return aue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 756 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 757 } 758 759 /* 760 * Attach the interface. Allocate softc structures, do ifmedia 761 * setup and ethernet/BPF attach. 762 */ 763 static void 764 aue_attach(device_t parent, device_t self, void *aux) 765 { 766 USBNET_MII_DECL_DEFAULT(unm); 767 struct aue_softc * const sc = device_private(self); 768 struct usbnet * const un = &sc->aue_un; 769 struct usb_attach_arg *uaa = aux; 770 char *devinfop; 771 struct usbd_device *dev = uaa->uaa_device; 772 usbd_status err; 773 usb_interface_descriptor_t *id; 774 usb_endpoint_descriptor_t *ed; 775 int i; 776 777 AUEHIST_FUNC(); 778 AUEHIST_CALLARGSN(2, "aue%jd: enter sc=%#jx", 779 device_unit(self), (uintptr_t)sc, 0, 0); 780 781 KASSERT((void *)sc == un); 782 783 aprint_naive("\n"); 784 aprint_normal("\n"); 785 devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0); 786 aprint_normal_dev(self, "%s\n", devinfop); 787 usbd_devinfo_free(devinfop); 788 789 un->un_dev = self; 790 un->un_udev = dev; 791 un->un_sc = sc; 792 un->un_ops = &aue_ops; 793 un->un_intr = &sc->aue_intr; 794 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 795 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 796 un->un_rx_list_cnt = AUE_RX_LIST_CNT; 797 un->un_tx_list_cnt = AUE_RX_LIST_CNT; 798 un->un_rx_bufsz = AUE_BUFSZ; 799 un->un_tx_bufsz = AUE_BUFSZ; 800 801 sc->aue_intr.uni_buf = &sc->aue_ibuf; 802 sc->aue_intr.uni_bufsz = sizeof(sc->aue_ibuf); 803 sc->aue_intr.uni_interval = AUE_INTR_INTERVAL; 804 805 err = usbd_set_config_no(dev, AUE_CONFIG_NO, 1); 806 if (err) { 807 aprint_error_dev(self, "failed to set configuration" 808 ", err=%s\n", usbd_errstr(err)); 809 return; 810 } 811 812 err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &un->un_iface); 813 if (err) { 814 aprint_error_dev(self, "getting interface handle failed\n"); 815 return; 816 } 817 818 un->un_flags = aue_lookup(uaa->uaa_vendor, uaa->uaa_product)->aue_flags; 819 820 id = usbd_get_interface_descriptor(un->un_iface); 821 822 /* Find endpoints. */ 823 for (i = 0; i < id->bNumEndpoints; i++) { 824 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 825 if (ed == NULL) { 826 aprint_error_dev(self, 827 "couldn't get endpoint descriptor %d\n", i); 828 return; 829 } 830 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 831 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 832 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 833 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 834 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 835 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 836 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 837 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 838 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 839 } 840 } 841 842 if (un->un_ed[USBNET_ENDPT_RX] == 0 || 843 un->un_ed[USBNET_ENDPT_TX] == 0 || 844 un->un_ed[USBNET_ENDPT_INTR] == 0) { 845 aprint_error_dev(self, "missing endpoint\n"); 846 return; 847 } 848 849 /* First level attach. */ 850 usbnet_attach(un); 851 852 /* Reset the adapter and get station address from the EEPROM. */ 853 aue_reset(sc); 854 aue_read_mac(un); 855 856 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 857 0, &unm); 858 } 859 860 static void 861 aue_uno_intr(struct usbnet *un, usbd_status status) 862 { 863 struct ifnet *ifp = usbnet_ifp(un); 864 struct aue_softc *sc = usbnet_softc(un); 865 struct aue_intrpkt *p = &sc->aue_ibuf; 866 867 AUEHIST_FUNC(); 868 AUEHIST_CALLARGSN(20, "aue%jd: enter txstat0 %#jx\n", 869 device_unit(un->un_dev), p->aue_txstat0, 0, 0); 870 871 if (p->aue_txstat0) 872 if_statinc(ifp, if_oerrors); 873 874 if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL | AUE_TXSTAT0_EXCESSCOLL)) 875 if_statinc(ifp, if_collisions); 876 } 877 878 static void 879 aue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 880 { 881 struct ifnet *ifp = usbnet_ifp(un); 882 uint8_t *buf = c->unc_buf; 883 struct aue_rxpkt r; 884 uint32_t pktlen; 885 886 AUEHIST_FUNC(); 887 AUEHIST_CALLARGSN(10, "aue%jd: enter len %ju", 888 device_unit(un->un_dev), total_len, 0, 0); 889 890 if (total_len <= 4 + ETHER_CRC_LEN) { 891 if_statinc(ifp, if_ierrors); 892 return; 893 } 894 895 memcpy(&r, buf + total_len - 4, sizeof(r)); 896 897 /* Turn off all the non-error bits in the rx status word. */ 898 r.aue_rxstat &= AUE_RXSTAT_MASK; 899 if (r.aue_rxstat) { 900 if_statinc(ifp, if_ierrors); 901 return; 902 } 903 904 /* No errors; receive the packet. */ 905 pktlen = total_len - ETHER_CRC_LEN - 4; 906 907 usbnet_enqueue(un, buf, pktlen, 0, 0, 0); 908 } 909 910 static unsigned 911 aue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 912 { 913 uint8_t *buf = c->unc_buf; 914 int total_len; 915 916 AUEHIST_FUNC(); 917 AUEHIST_CALLARGSN(10, "aue%jd: enter pktlen=%jd", 918 device_unit(un->un_dev), m->m_pkthdr.len, 0, 0); 919 920 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2) 921 return 0; 922 923 /* 924 * Copy the mbuf data into a contiguous buffer, leaving two 925 * bytes at the beginning to hold the frame length. 926 */ 927 m_copydata(m, 0, m->m_pkthdr.len, buf + 2); 928 929 /* 930 * The ADMtek documentation says that the packet length is 931 * supposed to be specified in the first two bytes of the 932 * transfer, however it actually seems to ignore this info 933 * and base the frame size on the bulk transfer length. 934 */ 935 buf[0] = (uint8_t)m->m_pkthdr.len; 936 buf[1] = (uint8_t)(m->m_pkthdr.len >> 8); 937 total_len = m->m_pkthdr.len + 2; 938 939 DPRINTFN(5, "aue%jd: send %jd bytes", 940 device_unit(un->un_dev), total_len, 0, 0); 941 942 return total_len; 943 } 944 945 static int 946 aue_uno_init(struct ifnet *ifp) 947 { 948 struct usbnet * const un = ifp->if_softc; 949 struct aue_softc *sc = usbnet_softc(un); 950 int i; 951 const u_char *eaddr; 952 953 AUEHIST_FUNC(); 954 AUEHIST_CALLARGSN(5, "aue%jd: enter link=%jd", 955 device_unit(un->un_dev), usbnet_havelink(un), 0, 0); 956 957 /* Reset the interface. */ 958 aue_reset(sc); 959 960 eaddr = CLLADDR(ifp->if_sadl); 961 for (i = 0; i < ETHER_ADDR_LEN; i++) 962 aue_csr_write_1(sc, AUE_PAR0 + i, eaddr[i]); 963 964 /* If we want promiscuous mode, set the allframes bit. */ 965 if (usbnet_ispromisc(un)) 966 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); 967 else 968 AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); 969 970 /* Enable RX and TX */ 971 aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB); 972 AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB); 973 AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR); 974 975 return 0; 976 } 977 978 static void 979 aue_uno_stop(struct ifnet *ifp, int disable) 980 { 981 struct usbnet * const un = ifp->if_softc; 982 struct aue_softc * const sc = usbnet_softc(un); 983 984 AUEHIST_FUNC(); 985 AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0); 986 987 aue_csr_write_1(sc, AUE_CTL0, 0); 988 aue_csr_write_1(sc, AUE_CTL1, 0); 989 aue_reset(sc); 990 } 991 992 #ifdef _MODULE 993 #include "ioconf.c" 994 #endif 995 996 USBNET_MODULE(aue) 997