1 /* 2 * axf_usbgem.c : ASIX AX88172/772 USB to Fast Ethernet Driver for Solaris 3 * 4 * Copyright (c) 2004-2012 Masayuki Murayama. 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 are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * 3. Neither the name of the author nor the names of its contributors may be 17 * used to endorse or promote products derived from this software without 18 * specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 31 * DAMAGE. 32 */ 33 34 #pragma ident "@(#)axf_usbgem.c 1.3 12/02/09" 35 36 /* 37 * Changelog: 38 */ 39 40 /* 41 * TODO 42 * handle RXMODE_ENABLE in set_rx_filter() 43 */ 44 /* ======================================================= */ 45 46 /* 47 * Solaris system header files and macros 48 */ 49 50 /* minimum kernel headers for drivers */ 51 #include <sys/types.h> 52 #include <sys/conf.h> 53 #include <sys/debug.h> 54 #include <sys/kmem.h> 55 #include <sys/modctl.h> 56 #include <sys/errno.h> 57 #include <sys/ddi.h> 58 #include <sys/sunddi.h> 59 #include <sys/byteorder.h> 60 61 /* ethernet stuff */ 62 #include <sys/ethernet.h> 63 64 /* interface card depend stuff */ 65 #include <sys/stropts.h> 66 #include <sys/stream.h> 67 #include <sys/strlog.h> 68 #include <sys/usb/usba.h> 69 #include "usbgem.h" 70 71 /* hardware stuff */ 72 #include "usbgem_mii.h" 73 #include "ax88172reg.h" 74 75 char ident[] = "ax88x72 usbnic driver v" VERSION; 76 77 /* 78 * Useful macros 79 */ 80 #define CHECK_AND_JUMP(err, label) if (err != USB_SUCCESS) goto label 81 #define LE16P(p) ((((uint8_t *)(p))[1] << 8) | ((uint8_t *)(p))[0]) 82 83 #define AX88172(dp) \ 84 (((struct axf_dev *)(dp)->private)->chip->type == CHIP_TYPE_AX88172) 85 86 #define AX88772(dp) \ 87 (((struct axf_dev *)(dp)->private)->chip->type == CHIP_TYPE_AX88772) 88 89 /* 90 * Debugging 91 */ 92 #ifdef DEBUG_LEVEL 93 static int axf_debug = DEBUG_LEVEL; 94 #define DPRINTF(n, args) if (axf_debug > (n)) cmn_err args 95 #else 96 #define DPRINTF(n, args) 97 #endif 98 99 /* 100 * Our configration for ax88172 101 */ 102 /* timeouts */ 103 #define ONESEC (drv_usectohz(1*1000000)) 104 105 /* 106 * RX/TX buffer size 107 */ 108 109 /* 110 * Local device definitions 111 */ 112 struct chip_info { 113 uint16_t vid; /* usb vendor id */ 114 uint16_t pid; /* usb product id */ 115 int type; 116 uint8_t gpio_reset[2]; 117 uint8_t gpio_speed[2]; 118 uint8_t gpio_duplex[2]; 119 char *name; 120 #define CHIP_TYPE_AX88172 0 121 #define CHIP_TYPE_AX88772 1 122 #define CHIP_TYPE_AX88178 2 123 }; 124 125 #define GPIO_DEFAULT {0x00, 0x15}, {0, 0}, {0, 0} 126 struct chip_info chiptbl_88x7x[] = { 127 /* AX88172 */ 128 { 129 /* Planex UE2-100TX, Hawking UF200, TrendNet TU2-ET100 */ 130 0x07b8, 0x420a, CHIP_TYPE_AX88172, 131 132 /* 133 * the default setting covers below: 134 * gpio bit2 has to be 0 and gpio bit0 has to be 1 135 */ 136 {0, 0}, 137 {GPIO_EN1, GPIO_DATA1 | GPIO_EN1}, 138 {0, 0}, 139 "Planex UE2-100TX", /* tested */ 140 }, 141 { 142 0x2001, 0x1a00, CHIP_TYPE_AX88172, 143 {0x9f, 0x9e}, {0, 0}, {0, 0}, 144 "D-Link dube100", /* XXX */ 145 }, 146 { 147 0x077b, 0x2226, CHIP_TYPE_AX88172, 148 GPIO_DEFAULT, 149 "Linksys USB200M", 150 }, 151 { 152 0x0846, 0x1040, CHIP_TYPE_AX88172, 153 GPIO_DEFAULT, 154 "Netgear FA120", 155 }, 156 { 157 0x0b95, 0x1720, CHIP_TYPE_AX88172, 158 GPIO_DEFAULT, 159 "Intellinet, ST Lab USB Ethernet", 160 }, 161 { 162 0x08dd, 0x90ff, CHIP_TYPE_AX88172, 163 GPIO_DEFAULT, 164 "Billionton Systems, USB2AR", 165 }, 166 { 167 0x0557, 0x2009, CHIP_TYPE_AX88172, 168 GPIO_DEFAULT, 169 "ATEN UC210T", 170 }, 171 { 172 0x0411, 0x003d, CHIP_TYPE_AX88172, 173 GPIO_DEFAULT, 174 "Buffalo LUA-U2-KTX", 175 }, 176 { 177 0x6189, 0x182d, CHIP_TYPE_AX88172, 178 GPIO_DEFAULT, 179 "Sitecom LN-029 USB 2.0 10/100 Ethernet adapter", 180 }, 181 { 182 0x07aa, 0x0017, CHIP_TYPE_AX88172, 183 GPIO_DEFAULT, 184 "corega FEther USB2-TX", 185 }, 186 { 187 0x1189, 0x0893, CHIP_TYPE_AX88172, 188 GPIO_DEFAULT, 189 "Surecom EP-1427X-2", 190 }, 191 { 192 0x1631, 0x6200, CHIP_TYPE_AX88172, 193 GPIO_DEFAULT, 194 "goodway corp usb gwusb2e", 195 }, 196 /* AX88772 and AX88178 */ 197 { 198 0x13b1, 0x0018, CHIP_TYPE_AX88772, 199 {0, 0}, {0, 0}, {0, 0}, 200 "Linksys USB200M rev.2", 201 }, 202 { 203 0x1557, 0x7720, CHIP_TYPE_AX88772, 204 {0, 0}, {0, 0}, {0, 0}, 205 "0Q0 cable ethernet", 206 }, 207 { 208 0x07d1, 0x3c05, CHIP_TYPE_AX88772, 209 {0, 0}, {0, 0}, {0, 0}, 210 "DLink DUB E100 ver B1", 211 }, 212 { 213 0x2001, 0x3c05, CHIP_TYPE_AX88772, 214 {0, 0}, {0, 0}, {0, 0}, 215 "DLink DUB E100 ver B1(2)", 216 }, 217 { 218 0x05ac, 0x1402, CHIP_TYPE_AX88772, 219 {0, 0}, {0, 0}, {0, 0}, 220 "Apple Ethernet USB Adapter", 221 }, 222 { 223 0x1737, 0x0039, CHIP_TYPE_AX88178, 224 {0, 0}, {0, 0}, {0, 0}, 225 "Linksys USB1000", 226 }, 227 { 228 0x0411, 0x006e, CHIP_TYPE_AX88178, 229 {0, 0}, {0, 0}, {0, 0}, 230 "Buffalo LUA-U2-KGT/LUA-U2-GT", 231 }, 232 { 233 0x04bb, 0x0930, CHIP_TYPE_AX88178, 234 {0, 0}, {0, 0}, {0, 0}, 235 "I/O DATA ETG-US2", 236 }, 237 { 238 0x050d, 0x5055, CHIP_TYPE_AX88178, 239 {0, 0}, {0, 0}, {0, 0}, 240 "Belkin F5D5055", 241 }, 242 { 243 /* generic ax88772 must be the last entry */ 244 /* planex UE-200TX-G */ 245 0x0b95, 0x7720, CHIP_TYPE_AX88772, 246 {0, 0}, {0, 0}, {0, 0}, 247 "ASIX AX88772/AX88178", /* tested */ 248 }, 249 }; 250 251 #define CHIPTABLESIZE (sizeof (chiptbl_88x7x) / sizeof (struct chip_info)) 252 253 struct axf_dev { 254 /* 255 * Misc HW information 256 */ 257 struct chip_info *chip; 258 uint8_t ipg[3]; 259 uint8_t gpio; 260 uint16_t rcr; 261 uint16_t msr; 262 uint8_t last_link_state; 263 boolean_t phy_has_reset; 264 }; 265 266 /* 267 * private functions 268 */ 269 270 /* mii operations */ 271 static uint16_t axf_mii_read(struct usbgem_dev *, uint_t, int *errp); 272 static void axf_mii_write(struct usbgem_dev *, uint_t, uint16_t, int *errp); 273 274 /* nic operations */ 275 static int axf_reset_chip(struct usbgem_dev *); 276 static int axf_init_chip(struct usbgem_dev *); 277 static int axf_start_chip(struct usbgem_dev *); 278 static int axf_stop_chip(struct usbgem_dev *); 279 static int axf_set_media(struct usbgem_dev *); 280 static int axf_set_rx_filter(struct usbgem_dev *); 281 static int axf_get_stats(struct usbgem_dev *); 282 static void axf_interrupt(struct usbgem_dev *, mblk_t *); 283 284 /* packet operations */ 285 static mblk_t *axf_tx_make_packet(struct usbgem_dev *, mblk_t *); 286 static mblk_t *axf_rx_make_packet(struct usbgem_dev *, mblk_t *); 287 288 /* =============================================================== */ 289 /* 290 * I/O functions 291 */ 292 /* =============================================================== */ 293 /* BEGIN CSTYLED */ 294 #define OUT(dp, req, val, ix, len, buf, errp, label) \ 295 if ((*(errp) = usbgem_ctrl_out((dp), \ 296 /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \ 297 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 298 /* bRequest */ (req), \ 299 /* wValue */ (val), \ 300 /* wIndex */ (ix), \ 301 /* wLength */ (len), \ 302 /* value */ (buf), \ 303 /* size */ (len))) != USB_SUCCESS) goto label 304 305 #define IN(dp, req, val, ix, len, buf, errp, label) \ 306 if ((*(errp) = usbgem_ctrl_in((dp), \ 307 /* bmRequestType */ USB_DEV_REQ_DEV_TO_HOST \ 308 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 309 /* bRequest */ (req), \ 310 /* wValue */ (val), \ 311 /* wIndex */ (ix), \ 312 /* wLength */ (len), \ 313 /* valuep */ (buf), \ 314 /* size */ (len))) != USB_SUCCESS) goto label 315 /* END CSTYLED */ 316 317 /* =============================================================== */ 318 /* 319 * Hardware manupilation 320 */ 321 /* =============================================================== */ 322 static int 323 axf_reset_phy(struct usbgem_dev *dp) 324 { 325 uint8_t phys[2]; 326 uint8_t val8; 327 int err; 328 struct axf_dev *lp = dp->private; 329 330 DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 331 332 if (AX88172(dp)) { 333 delay(drv_usectohz(5000)); 334 IN(dp, VCMD_READ_GPIO, 0, 0, 1, &val8, &err, usberr); 335 336 DPRINTF(0, (CE_CONT, "!%s: %s: gpio 0x%b", 337 dp->name, __func__, val8, GPIO_BITS)); 338 339 /* reset MII PHY */ 340 val8 = lp->chip->gpio_reset[1] 341 | lp->chip->gpio_speed[dp->speed] 342 | lp->chip->gpio_duplex[dp->full_duplex]; 343 344 OUT(dp, VCMD_WRITE_GPIO, 345 val8, 0, 0, NULL, &err, usberr); 346 delay(drv_usectohz(5000)); 347 348 val8 = lp->chip->gpio_reset[0] 349 | lp->chip->gpio_speed[dp->speed] 350 | lp->chip->gpio_duplex[dp->full_duplex]; 351 352 OUT(dp, VCMD_WRITE_GPIO, 353 val8, 0, 0, NULL, &err, usberr); 354 delay(drv_usectohz(5000)); 355 } else { 356 lp->gpio = GPIO_RSE | GPIO_DATA2 | GPIO_EN2; 357 OUT(dp, VCMD_WRITE_GPIO, lp->gpio, 0, 358 0, NULL, &err, usberr); 359 drv_usecwait(1000); 360 361 OUT(dp, VCMD_WRITE_PHY_SELECT_88772, 362 dp->mii_phy_addr == 16 ? 1 : 0, 0, 0, NULL, &err, usberr); 363 364 OUT(dp, VCMD_SOFTWARE_RESET_88772, 365 SWRST_IPPD | SWRST_PRL, 0, 0, NULL, &err, usberr); 366 delay(drv_usectohz(150*1000)); 367 OUT(dp, VCMD_SOFTWARE_RESET_88772, 368 0, 0, 0, NULL, &err, usberr); 369 370 OUT(dp, VCMD_SOFTWARE_RESET_88772, 371 dp->mii_phy_addr == 16 ? SWRST_IPRL : SWRST_PRTE, 372 0, 0, NULL, &err, usberr); 373 delay(drv_usectohz(150*1000)); 374 } 375 376 377 return (USB_SUCCESS); 378 379 usberr: 380 return (USB_FAILURE); 381 } 382 383 static int 384 axf_reset_chip(struct usbgem_dev *dp) 385 { 386 int err = USB_SUCCESS; 387 388 if (AX88172(dp)) { 389 /* there are no ways to reset nic */ 390 return (USB_SUCCESS); 391 } 392 #ifdef NEVER 393 OUT(dp, VCMD_SOFTWARE_RESET_88772, 394 SWRST_RR | SWRST_RT, 0, 0, NULL, &err, usberr); 395 OUT(dp, VCMD_SOFTWARE_RESET_88772, 396 0, 0, 0, NULL, &err, usberr); 397 usberr: 398 #endif 399 return (err); 400 } 401 402 /* 403 * Setup ax88172 404 */ 405 static int 406 axf_init_chip(struct usbgem_dev *dp) 407 { 408 int i; 409 uint32_t val; 410 int err = USB_SUCCESS; 411 uint16_t reg; 412 uint8_t buf[2]; 413 uint16_t tmp16; 414 struct axf_dev *lp = dp->private; 415 416 DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 417 418 /* rx conrol register: read default value */ 419 if (!AX88172(dp)) { 420 /* clear rx control */ 421 OUT(dp, VCMD_WRITE_RXCTRL, 0, 0, 0, NULL, &err, usberr); 422 } 423 424 IN(dp, VCMD_READ_RXCTRL, 0, 0, 2, buf, &err, usberr); 425 lp->rcr = LE16P(buf); 426 DPRINTF(0, (CE_CONT, "!%s: %s: rcr(default):%b", 427 dp->name, __func__, lp->rcr, RCR_BITS)); 428 429 lp->rcr &= ~RCR_SO; 430 431 /* Media status register */ 432 if (AX88172(dp)) { 433 #ifdef notdef 434 lp->msr = MSR_TXABT; 435 #else 436 lp->msr = 0; 437 #endif 438 } else { 439 lp->msr = MSR_RE | MSR_TXABT; 440 } 441 DPRINTF(0, (CE_CONT, "!%s: %s: msr:%b", 442 dp->name, __func__, lp->msr, MSR_BITS)); 443 err = axf_set_media(dp); 444 CHECK_AND_JUMP(err, usberr); 445 446 /* write IPG0-2 registers */ 447 if (AX88172(dp)) { 448 OUT(dp, VCMD_WRITE_IPG, lp->ipg[0], 0, 0, NULL, &err, usberr); 449 OUT(dp, VCMD_WRITE_IPG1, lp->ipg[1], 0, 0, NULL, &err, usberr); 450 OUT(dp, VCMD_WRITE_IPG2, lp->ipg[2], 0, 0, NULL, &err, usberr); 451 } else { 452 /* EMPTY */ 453 } 454 #ifdef ENABLE_RX_IN_INIT_CHIP 455 /* enable Rx */ 456 lp->rcr |= RCR_SO; 457 OUT(dp, VCMD_WRITE_RXCTRL, lp->rcr, 0, 0, NULL, &err, usberr); 458 #endif 459 usberr: 460 DPRINTF(2, (CE_CONT, "!%s: %s: end (%s)", 461 dp->name, __func__, 462 err, err == USB_SUCCESS ? "success" : "error")); 463 return (err); 464 } 465 466 static int 467 axf_start_chip(struct usbgem_dev *dp) 468 { 469 int err = USB_SUCCESS; 470 struct axf_dev *lp = dp->private; 471 #ifndef ENABLE_RX_IN_INIT_CHIP 472 /* enable Rx */ 473 lp->rcr |= RCR_SO; 474 OUT(dp, VCMD_WRITE_RXCTRL, lp->rcr, 0, 0, NULL, &err, usberr); 475 476 usberr: 477 DPRINTF(2, (CE_CONT, "!%s: %s: end (%s)", 478 dp->name, __func__, 479 err, err == USB_SUCCESS ? "success" : "error")); 480 #endif 481 return (err); 482 } 483 484 static int 485 axf_stop_chip(struct usbgem_dev *dp) 486 { 487 int err = USB_SUCCESS; 488 struct axf_dev *lp = dp->private; 489 490 /* Disable Rx */ 491 lp->rcr &= ~RCR_SO; 492 OUT(dp, VCMD_WRITE_RXCTRL, lp->rcr, 0, 0, NULL, &err, usberr); 493 494 /* 495 * Restore factory mac address 496 * if we have changed current mac address 497 */ 498 if (!AX88172(dp) && 499 bcmp(dp->dev_addr.ether_addr_octet, 500 dp->cur_addr.ether_addr_octet, 501 ETHERADDRL) != 0) { 502 OUT(dp, VCMD_WRITE_NODE_ID_88772, 0, 0, 503 ETHERADDRL, dp->cur_addr.ether_addr_octet, &err, usberr); 504 } 505 usberr: 506 return (axf_reset_chip(dp)); 507 } 508 509 static int 510 axf_get_stats(struct usbgem_dev *dp) 511 { 512 /* empty */ 513 return (USB_SUCCESS); 514 } 515 516 static uint_t 517 axf_mcast_hash(struct usbgem_dev *dp, const uint8_t *addr) 518 { 519 return (usbgem_ether_crc_be(addr) >> (32 - 6)); 520 } 521 522 static int 523 axf_set_rx_filter(struct usbgem_dev *dp) 524 { 525 int i; 526 uint8_t mode; 527 uint8_t mhash[8]; 528 uint8_t buf[2]; 529 uint_t h; 530 int err = USB_SUCCESS; 531 struct axf_dev *lp = dp->private; 532 533 DPRINTF(2, (CE_CONT, "!%s: %s: called, rxmode:%x", 534 dp->name, __func__, dp->rxmode)); 535 536 if (lp->rcr & RCR_SO) { 537 /* set promiscuous mode before changing it. */ 538 OUT(dp, VCMD_WRITE_RXCTRL, 539 lp->rcr | RCR_PRO, 0, 0, NULL, &err, usberr); 540 } 541 542 lp->rcr &= ~(RCR_AP_88772 | RCR_AM | RCR_SEP | RCR_AMALL | RCR_PRO); 543 mode = RCR_AB; /* accept broadcast packets */ 544 545 bzero(mhash, sizeof (mhash)); 546 547 if (dp->rxmode & RXMODE_PROMISC) { 548 /* promiscious mode implies all multicast and all physical */ 549 mode |= RCR_PRO; 550 } else if ((dp->rxmode & RXMODE_ALLMULTI) || dp->mc_count > 32) { 551 /* accept all multicast packets */ 552 mode |= RCR_AMALL; 553 } else if (dp->mc_count > 0) { 554 /* 555 * make hash table to select interresting 556 * multicast address only. 557 */ 558 mode |= RCR_AM; 559 for (i = 0; i < dp->mc_count; i++) { 560 h = dp->mc_list[i].hash; 561 mhash[h / 8] |= 1 << (h % 8); 562 } 563 } 564 if (AX88172(dp)) { 565 if (bcmp(dp->dev_addr.ether_addr_octet, 566 dp->cur_addr.ether_addr_octet, ETHERADDRL) != 0) { 567 /* 568 * we use promiscious mode instead of changing the 569 * mac address in ax88172 570 */ 571 mode |= RCR_PRO; 572 } 573 } else { 574 OUT(dp, VCMD_WRITE_NODE_ID_88772, 0, 0, 575 ETHERADDRL, dp->cur_addr.ether_addr_octet, &err, usberr); 576 } 577 lp->rcr |= mode; 578 579 /* set multicast hash table */ 580 if (mode & RCR_AM) { 581 /* need to set up multicast hash table */ 582 OUT(dp, VCMD_WRITE_MCAST_FILTER, 0, 0, 583 sizeof (mhash), mhash, &err, usberr); 584 } 585 586 /* update rcr */ 587 OUT(dp, VCMD_WRITE_RXCTRL, lp->rcr, 0, 588 0, NULL, &err, usberr); 589 590 #if DEBUG_LEVEL > 1 591 /* verify rxctrl reg */ 592 IN(dp, VCMD_READ_RXCTRL, 0, 0, 2, buf, &err, usberr); 593 cmn_err(CE_CONT, "!%s: %s: rcr:%b returned", 594 dp->name, __func__, LE16P(buf), RCR_BITS); 595 #endif 596 usberr: 597 DPRINTF(2, (CE_CONT, "!%s: %s: end (%s)", 598 dp->name, __func__, 599 err, err == USB_SUCCESS ? "success" : "error")); 600 return (err); 601 } 602 603 static int 604 axf_set_media(struct usbgem_dev *dp) 605 { 606 uint8_t val8; 607 uint8_t gpio; 608 uint8_t gpio_old; 609 int err = USB_SUCCESS; 610 uint16_t msr; 611 struct axf_dev *lp = dp->private; 612 613 IN(dp, VCMD_READ_GPIO, 0, 0, 1, &gpio, &err, usberr); 614 615 DPRINTF(0, (CE_CONT, "!%s: %s: called, gpio:%b", 616 dp->name, __func__, gpio, GPIO_BITS)); 617 618 msr = lp->msr; 619 gpio_old = gpio; 620 gpio = lp->chip->gpio_reset[0]; 621 622 /* setup speed */ 623 if (AX88172(dp)) { 624 /* EMPTY */ 625 } else { 626 msr &= ~(MSR_PS | MSR_GM | MSR_ENCK); 627 628 switch (dp->speed) { 629 case USBGEM_SPD_1000: 630 msr |= MSR_GM | MSR_ENCK; 631 break; 632 633 case USBGEM_SPD_100: 634 msr |= MSR_PS; 635 break; 636 637 case USBGEM_SPD_10: 638 break; 639 } 640 } 641 gpio |= lp->chip->gpio_speed[dp->speed == USBGEM_SPD_100 ? 1 : 0]; 642 643 /* select duplex */ 644 msr &= ~MSR_FDPX; 645 if (dp->full_duplex) { 646 msr |= MSR_FDPX; 647 648 /* select flow control */ 649 if (AX88172(dp)) { 650 msr &= ~MSR_FCEN; 651 switch (dp->flow_control) { 652 case FLOW_CONTROL_TX_PAUSE: 653 case FLOW_CONTROL_SYMMETRIC: 654 case FLOW_CONTROL_RX_PAUSE: 655 msr |= MSR_FCEN; 656 break; 657 } 658 } else { 659 msr &= ~(MSR_RFC | MSR_TFC); 660 switch (dp->flow_control) { 661 case FLOW_CONTROL_TX_PAUSE: 662 msr |= MSR_TFC; 663 break; 664 665 case FLOW_CONTROL_SYMMETRIC: 666 msr |= MSR_TFC | MSR_RFC; 667 break; 668 669 case FLOW_CONTROL_RX_PAUSE: 670 msr |= MSR_RFC; 671 break; 672 } 673 } 674 } 675 gpio |= lp->chip->gpio_duplex[dp->full_duplex ? 1 : 0]; 676 677 /* update medium status register */ 678 lp->msr = msr; 679 OUT(dp, VCMD_WRITE_MEDIUM_STATUS, lp->msr, 0, 680 0, NULL, &err, usberr); 681 682 if (gpio != gpio_old) { 683 /* LED control required for some products */ 684 OUT(dp, VCMD_WRITE_GPIO, 685 gpio, 0, 0, NULL, &err, usberr); 686 } 687 688 usberr: 689 DPRINTF(2, (CE_CONT, "!%s: %s: end (%s)", 690 dp->name, __func__, 691 err, err == USB_SUCCESS ? "success" : "error")); 692 return (err); 693 } 694 695 #define FILL_PKT_HEADER(bp, len) { \ 696 (bp)[0] = (uint8_t)(len); \ 697 (bp)[1] = (uint8_t)((len) >> 8); \ 698 (bp)[2] = (uint8_t)(~(len)); \ 699 (bp)[3] = (uint8_t)((~(len)) >> 8); \ 700 } 701 702 #define PKT_HEADER_SIZE 4 703 704 /* 705 * send/receive packet check 706 */ 707 static mblk_t * 708 axf_tx_make_packet(struct usbgem_dev *dp, mblk_t *mp) 709 { 710 int n; 711 size_t len; 712 size_t pkt_size; 713 mblk_t *new; 714 mblk_t *tp; 715 uint8_t *bp; 716 uint8_t *last_pos; 717 uint_t align_mask; 718 size_t header_size; 719 int pad_size; 720 721 len = msgdsize(mp); 722 723 if (AX88172(dp)) { 724 #ifdef notdef 725 align_mask = 63; 726 #else 727 align_mask = 511; 728 #endif 729 header_size = 0; 730 731 if (len >= ETHERMIN && mp->b_cont == NULL && 732 (len & align_mask) != 0) { 733 /* use the mp "as is" */ 734 return (mp); 735 } 736 } else { 737 align_mask = 511; 738 header_size = PKT_HEADER_SIZE; 739 } 740 741 /* 742 * re-allocate the mp 743 */ 744 /* minimum ethernet packet size of ETHERMIN */ 745 pkt_size = max(len, ETHERMIN); 746 747 if (((pkt_size + header_size) & align_mask) == 0) { 748 /* padding is required in usb communication */ 749 pad_size = PKT_HEADER_SIZE; 750 } else { 751 pad_size = 0; 752 } 753 754 if ((new = allocb(header_size + pkt_size + pad_size, 0)) == NULL) { 755 return (NULL); 756 } 757 758 bp = new->b_rptr; 759 if (header_size) { 760 uint16_t tmp; 761 762 /* add a header */ 763 tmp = (uint16_t)pkt_size; 764 FILL_PKT_HEADER(bp, tmp); 765 bp += header_size; 766 } 767 768 /* copy contents of the buffer */ 769 for (tp = mp; tp; tp = tp->b_cont) { 770 n = (uintptr_t)tp->b_wptr - (uintptr_t)tp->b_rptr; 771 bcopy(tp->b_rptr, bp, n); 772 bp += n; 773 } 774 775 /* add pads for ethernet packets */ 776 last_pos = new->b_rptr + header_size + pkt_size; 777 while (bp < last_pos) { 778 *bp++ = 0; 779 } 780 781 /* add a zero-length pad segment for usb communications */ 782 if (pad_size) { 783 /* add a dummy header for zero-length packet */ 784 FILL_PKT_HEADER(bp, 0); 785 bp += pad_size; 786 } 787 788 /* close the payload of the packet */ 789 new->b_wptr = bp; 790 791 return (new); 792 } 793 794 #if DEBUG_LEVEL > 10 795 static void 796 axf_dump_packet(struct usbgem_dev *dp, uint8_t *bp, int n) 797 { 798 int i; 799 800 for (i = 0; i < n; i += 8, bp += 8) { 801 cmn_err(CE_CONT, "%02x %02x %02x %02x %02x %02x %02x %02x", 802 bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]); 803 } 804 } 805 #endif 806 807 static mblk_t * 808 axf_rx_make_packet(struct usbgem_dev *dp, mblk_t *mp) 809 { 810 mblk_t *tp; 811 uintptr_t rest; 812 813 if (AX88172(dp)) { 814 return (mp); 815 } 816 817 tp = mp; 818 rest = (uintptr_t)tp->b_wptr - (uintptr_t)tp->b_rptr; 819 820 if (rest <= PKT_HEADER_SIZE) { 821 /* 822 * the usb bulk-in frame doesn't include any valid 823 * ethernet packets. 824 */ 825 return (NULL); 826 } 827 828 for (; ; ) { 829 uint16_t len; 830 uint16_t cksum; 831 832 /* analyse the header of the received usb frame */ 833 len = LE16P(tp->b_rptr + 0); 834 cksum = LE16P(tp->b_rptr + 2); 835 836 /* test if the header is valid */ 837 if (len + cksum != 0xffff) { 838 /* discard whole the packet */ 839 cmn_err(CE_WARN, 840 "!%s: %s: corrupted header:%04x %04x", 841 dp->name, __func__, len, cksum); 842 return (NULL); 843 } 844 #if DEBUG_LEVEL > 0 845 if (len < ETHERMIN || len > ETHERMAX) { 846 cmn_err(CE_NOTE, 847 "!%s: %s: incorrect pktsize:%d", 848 dp->name, __func__, len); 849 } 850 #endif 851 /* extract a ethernet packet from the bulk-in frame */ 852 tp->b_rptr += PKT_HEADER_SIZE; 853 tp->b_wptr = tp->b_rptr + len; 854 855 if (len & 1) { 856 /* 857 * skip a tailing pad byte if the packet 858 * length is odd 859 */ 860 len++; 861 } 862 rest -= len + PKT_HEADER_SIZE; 863 864 if (rest <= PKT_HEADER_SIZE) { 865 /* no more vaild ethernet packets */ 866 break; 867 } 868 869 #if DEBUG_LEVEL > 10 870 axf_dump_packet(dp, tp->b_wptr, 18); 871 #endif 872 /* allocate a mblk_t header for the next ethernet packet */ 873 tp->b_next = dupb(mp); 874 tp->b_next->b_rptr = tp->b_rptr + len; 875 tp = tp->b_next; 876 } 877 878 return (mp); 879 } 880 881 /* 882 * MII Interfaces 883 */ 884 static uint16_t 885 axf_mii_read(struct usbgem_dev *dp, uint_t index, int *errp) 886 { 887 uint8_t buf[2]; 888 uint16_t val; 889 890 DPRINTF(4, (CE_CONT, "!%s: %s: called, ix:%d", 891 dp->name, __func__, index)); 892 893 /* switch to software MII operation mode */ 894 OUT(dp, VCMD_SOFTWARE_MII_OP, 0, 0, 0, NULL, errp, usberr); 895 896 /* Read MII register */ 897 IN(dp, VCMD_READ_MII_REG, dp->mii_phy_addr, index, 898 2, buf, errp, usberr); 899 900 /* switch to hardware MII operation mode */ 901 OUT(dp, VCMD_HARDWARE_MII_OP, 0, 0, 0, NULL, errp, usberr); 902 903 return (LE16P(buf)); 904 905 usberr: 906 cmn_err(CE_CONT, 907 "!%s: %s: usberr(%d) detected", dp->name, __func__, *errp); 908 return (0); 909 } 910 911 static void 912 axf_mii_write(struct usbgem_dev *dp, uint_t index, uint16_t val, int *errp) 913 { 914 uint8_t buf[2]; 915 916 DPRINTF(4, (CE_CONT, "!%s: %s called, reg:%x val:%x", 917 dp->name, __func__, index, val)); 918 919 /* switch software MII operation mode */ 920 OUT(dp, VCMD_SOFTWARE_MII_OP, 0, 0, 0, NULL, errp, usberr); 921 922 /* Write to the specified MII register */ 923 buf[0] = (uint8_t)val; 924 buf[1] = (uint8_t)(val >> 8); 925 OUT(dp, VCMD_WRITE_MII_REG, dp->mii_phy_addr, index, 926 2, buf, errp, usberr); 927 928 /* switch to hardware MII operation mode */ 929 OUT(dp, VCMD_HARDWARE_MII_OP, 0, 0, 0, NULL, errp, usberr); 930 931 usberr: 932 ; 933 } 934 935 static void 936 axf_interrupt(struct usbgem_dev *dp, mblk_t *mp) 937 { 938 uint8_t *bp; 939 struct axf_dev *lp = dp->private; 940 941 bp = mp->b_rptr; 942 943 DPRINTF(2, (CE_CONT, 944 "!%s: %s: size:%d, %02x %02x %02x %02x %02x %02x %02x %02x", 945 dp->name, __func__, mp->b_wptr - mp->b_rptr, 946 bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7])); 947 948 if (lp->last_link_state ^ bp[2]) { 949 usbgem_mii_update_link(dp); 950 } 951 952 lp->last_link_state = bp[2]; 953 } 954 955 /* ======================================================== */ 956 /* 957 * OS depend (device driver DKI) routine 958 */ 959 /* ======================================================== */ 960 #ifdef DEBUG_LEVEL 961 static void 962 axf_eeprom_dump(struct usbgem_dev *dp, int size) 963 { 964 int i; 965 int err; 966 uint8_t w0[2], w1[2], w2[2], w3[2]; 967 968 cmn_err(CE_CONT, "!%s: eeprom dump:", dp->name); 969 970 err = USB_SUCCESS; 971 972 for (i = 0; i < size; i += 4) { 973 IN(dp, VCMD_READ_SROM, i + 0, 0, 2, w0, &err, usberr); 974 IN(dp, VCMD_READ_SROM, i + 1, 0, 2, w1, &err, usberr); 975 IN(dp, VCMD_READ_SROM, i + 2, 0, 2, w2, &err, usberr); 976 IN(dp, VCMD_READ_SROM, i + 3, 0, 2, w3, &err, usberr); 977 cmn_err(CE_CONT, "!0x%02x: 0x%04x 0x%04x 0x%04x 0x%04x", 978 i, 979 (w0[1] << 8) | w0[0], 980 (w1[1] << 8) | w1[0], 981 (w2[1] << 8) | w2[0], 982 (w3[1] << 8) | w3[0]); 983 } 984 usberr: 985 ; 986 } 987 #endif 988 989 static int 990 axf_attach_chip(struct usbgem_dev *dp) 991 { 992 uint8_t phys[2]; 993 int err; 994 uint_t vcmd; 995 int ret; 996 #ifdef CONFIG_FULLSIZE_VLAN 997 uint8_t maxpktsize[2]; 998 uint16_t vlan_pktsize; 999 #endif 1000 #ifdef DEBUG_LEVEL 1001 uint8_t val8; 1002 #endif 1003 struct axf_dev *lp = dp->private; 1004 1005 DPRINTF(0, (CE_CONT, "!%s: %s enter", dp->name, __func__)); 1006 1007 ret = USB_SUCCESS; 1008 /* 1009 * mac address in EEPROM has loaded to ID registers. 1010 */ 1011 vcmd = AX88172(dp) ? VCMD_READ_NODE_ID : VCMD_READ_NODE_ID_88772; 1012 IN(dp, vcmd, 0, 0, 1013 ETHERADDRL, dp->dev_addr.ether_addr_octet, &err, usberr); 1014 1015 /* 1016 * setup IPG values 1017 */ 1018 lp->ipg[0] = 0x15; 1019 lp->ipg[1] = 0x0c; 1020 lp->ipg[2] = 0x12; 1021 1022 /* 1023 * We cannot scan phy because the nic returns undefined 1024 * value, i.e. remained garbage, when MII phy is not at the 1025 * specified index. 1026 */ 1027 #ifdef DEBUG_LEVELx 1028 if (lp->chip->vid == 0x07b8 && lp->chip->pid == 0x420a) { 1029 /* 1030 * restore the original phy address of brain 1031 * damaged Planex UE2-100TX 1032 */ 1033 OUT(dp, VCMD_WRITE_SROM_ENABLE, 0, 0, 0, NULL, &err, usberr); 1034 OUT(dp, VCMD_WRITE_SROM, 0x11, 0xe004, 0, NULL, &err, usberr); 1035 OUT(dp, VCMD_WRITE_SROM_DISABLE, 0, 0, 0, NULL, &err, usberr); 1036 } 1037 #endif 1038 if (AX88172(dp)) { 1039 IN(dp, VCMD_READ_PHY_IDS, 0, 0, 2, &phys, &err, usberr); 1040 dp->mii_phy_addr = phys[1]; 1041 DPRINTF(0, (CE_CONT, "!%s: %s: phys_addr:%d %d", 1042 dp->name, __func__, phys[0], phys[1])); 1043 } else { 1044 /* use built-in phy */ 1045 dp->mii_phy_addr = 0x10; 1046 } 1047 1048 dp->misc_flag |= USBGEM_VLAN; 1049 #ifdef CONFIG_FULLSIZE_VLAN 1050 if (AX88172(dp) || AX88772(dp)) { 1051 /* check max packet size in srom */ 1052 IN(dp, VCMD_READ_SROM, 0x10, 0, 2, maxpktsize, &err, usberr); 1053 vlan_pktsize = ETHERMAX + ETHERFCSL + 4 /* VTAG_SIZE */; 1054 1055 if (LE16P(maxpktsize) < vlan_pktsize) { 1056 cmn_err(CE_CONT, 1057 "!%s: %s: max packet size in srom is too small, " 1058 "changing %d -> %d, do power cycle for the device", 1059 dp->name, __func__, 1060 LE16P(maxpktsize), vlan_pktsize); 1061 OUT(dp, VCMD_WRITE_SROM_ENABLE, 1062 0, 0, 0, NULL, &err, usberr); 1063 OUT(dp, VCMD_WRITE_SROM, 0x10, 1064 vlan_pktsize, 0, NULL, &err, usberr); 1065 OUT(dp, VCMD_WRITE_SROM_DISABLE, 1066 0, 0, 0, NULL, &err, usberr); 1067 1068 /* need to power off the device */ 1069 ret = USB_FAILURE; 1070 } 1071 } 1072 #endif 1073 #ifdef DEBUG_LEVEL 1074 IN(dp, VCMD_READ_GPIO, 0, 0, 1, &val8, &err, usberr); 1075 cmn_err(CE_CONT, 1076 "!%s: %s: ipg 0x%02x 0x%02x 0x%02x, gpio 0x%b", 1077 dp->name, __func__, lp->ipg[0], lp->ipg[1], lp->ipg[2], 1078 val8, GPIO_BITS); 1079 #endif 1080 /* fix rx buffer size */ 1081 if (!AX88172(dp)) { 1082 dp->rx_buf_len = 2048; 1083 } 1084 1085 #if DEBUG_LEVEL > 0 1086 axf_eeprom_dump(dp, 0x20); 1087 #endif 1088 return (ret); 1089 1090 usberr: 1091 cmn_err(CE_WARN, "%s: %s: usb error detected (%d)", 1092 dp->name, __func__, err); 1093 return (USB_FAILURE); 1094 } 1095 1096 static boolean_t 1097 axf_scan_phy(struct usbgem_dev *dp) 1098 { 1099 int i; 1100 int err; 1101 uint16_t val; 1102 int phy_addr_saved; 1103 struct axf_dev *lp = dp->private; 1104 1105 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 1106 1107 phy_addr_saved = dp->mii_phy_addr; 1108 1109 /* special probe routine for unreliable MII addr */ 1110 #define PROBE_PAT \ 1111 (MII_ABILITY_100BASE_TX_FD | \ 1112 MII_ABILITY_100BASE_TX | \ 1113 MII_ABILITY_10BASE_T_FD | \ 1114 MII_ABILITY_10BASE_T) 1115 1116 for (i = 0; i < 32; i++) { 1117 dp->mii_phy_addr = i; 1118 axf_mii_write(dp, MII_AN_ADVERT, 0, &err); 1119 if (err != USBGEM_SUCCESS) { 1120 break; 1121 } 1122 val = axf_mii_read(dp, MII_AN_ADVERT, &err); 1123 if (err != USBGEM_SUCCESS) { 1124 break; 1125 } 1126 if (val != 0) { 1127 DPRINTF(0, (CE_CONT, "!%s: %s: index:%d, val %b != 0", 1128 dp->name, __func__, i, val, MII_ABILITY_BITS)); 1129 continue; 1130 } 1131 1132 axf_mii_write(dp, MII_AN_ADVERT, PROBE_PAT, &err); 1133 if (err != USBGEM_SUCCESS) { 1134 break; 1135 } 1136 val = axf_mii_read(dp, MII_AN_ADVERT, &err); 1137 if (err != USBGEM_SUCCESS) { 1138 break; 1139 } 1140 if ((val & MII_ABILITY_TECH) != PROBE_PAT) { 1141 DPRINTF(0, (CE_CONT, "!%s: %s: " 1142 "index:%d, pat:%x != val:%b", 1143 dp->name, __func__, i, 1144 PROBE_PAT, val, MII_ABILITY_BITS)); 1145 continue; 1146 } 1147 1148 /* found */ 1149 dp->mii_phy_addr = phy_addr_saved; 1150 return (i); 1151 } 1152 #undef PROBE_PAT 1153 if (i == 32) { 1154 cmn_err(CE_CONT, "!%s: %s: no mii phy found", 1155 dp->name, __func__); 1156 } else { 1157 cmn_err(CE_CONT, "!%s: %s: i/o error while scanning phy", 1158 dp->name, __func__); 1159 } 1160 dp->mii_phy_addr = phy_addr_saved; 1161 return (-1); 1162 } 1163 1164 static int 1165 axf_mii_probe(struct usbgem_dev *dp) 1166 { 1167 int my_guess; 1168 int err; 1169 uint8_t old_11th[2]; 1170 uint8_t new_11th[2]; 1171 struct axf_dev *lp = dp->private; 1172 1173 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 1174 (void) axf_reset_phy(dp); 1175 lp->phy_has_reset = B_TRUE; 1176 1177 if (AX88172(dp)) { 1178 my_guess = axf_scan_phy(dp); 1179 if (my_guess >= 0 && my_guess < 32 && 1180 my_guess != dp->mii_phy_addr) { 1181 /* 1182 * phy addr in srom is wrong, need to fix it 1183 */ 1184 IN(dp, VCMD_READ_SROM, 1185 0x11, 0, 2, old_11th, &err, usberr); 1186 1187 new_11th[0] = my_guess; 1188 new_11th[1] = old_11th[1]; 1189 1190 OUT(dp, VCMD_WRITE_SROM_ENABLE, 1191 0, 0, 0, NULL, &err, usberr); 1192 OUT(dp, VCMD_WRITE_SROM, 1193 0x11, LE16P(new_11th), 0, NULL, &err, usberr); 1194 OUT(dp, VCMD_WRITE_SROM_DISABLE, 1195 0, 0, 0, NULL, &err, usberr); 1196 #if 1 1197 /* XXX - read back, but it doesn't work, why? */ 1198 delay(drv_usectohz(1000*1000)); 1199 IN(dp, VCMD_READ_SROM, 1200 0x11, 0, 2, new_11th, &err, usberr); 1201 #endif 1202 cmn_err(CE_NOTE, "!%s: %s: phy addr in srom fixed: " 1203 "%04x -> %04x", 1204 dp->name, __func__, 1205 LE16P(old_11th), LE16P(new_11th)); 1206 return (USBGEM_FAILURE); 1207 usberr: 1208 cmn_err(CE_NOTE, 1209 "!%s: %s: failed to patch phy addr, " 1210 "current: %04x", 1211 dp->name, __func__, LE16P(old_11th)); 1212 return (USBGEM_FAILURE); 1213 } 1214 } 1215 return (usbgem_mii_probe_default(dp)); 1216 } 1217 1218 static int 1219 axf_mii_init(struct usbgem_dev *dp) 1220 { 1221 struct axf_dev *lp = dp->private; 1222 1223 DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 1224 1225 if (!lp->phy_has_reset) { 1226 (void) axf_reset_phy(dp); 1227 } 1228 1229 /* prepare to reset phy on the next reconnect or resume */ 1230 lp->phy_has_reset = B_FALSE; 1231 1232 return (USB_SUCCESS); 1233 } 1234 1235 static int 1236 axfattach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1237 { 1238 int i; 1239 ddi_iblock_cookie_t c; 1240 int ret; 1241 int revid; 1242 int unit; 1243 int vid; 1244 int pid; 1245 struct chip_info *p; 1246 int len; 1247 const char *drv_name; 1248 struct usbgem_dev *dp; 1249 void *base; 1250 struct usbgem_conf *ugcp; 1251 struct axf_dev *lp; 1252 1253 unit = ddi_get_instance(dip); 1254 drv_name = ddi_driver_name(dip); 1255 1256 DPRINTF(3, (CE_CONT, "!%s%d: %s: called, cmd:%d", 1257 drv_name, unit, __func__, cmd)); 1258 1259 if (cmd == DDI_ATTACH) { 1260 /* 1261 * Check if the chip is supported. 1262 */ 1263 vid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1264 "usb-vendor-id", -1); 1265 pid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1266 "usb-product-id", -1); 1267 revid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1268 "usb-revision-id", -1); 1269 1270 for (i = 0, p = chiptbl_88x7x; i < CHIPTABLESIZE; i++, p++) { 1271 if (p->vid == vid && p->pid == pid) { 1272 /* found */ 1273 cmn_err(CE_CONT, "!%s%d: %s " 1274 "(vid: 0x%04x, did: 0x%04x, revid: 0x%02x)", 1275 drv_name, unit, p->name, vid, pid, revid); 1276 goto chip_found; 1277 } 1278 } 1279 1280 /* Not found */ 1281 cmn_err(CE_WARN, "!%s: %s: wrong usb venid/prodid (0x%x, 0x%x)", 1282 drv_name, __func__, vid, pid); 1283 1284 /* assume 88772 */ 1285 p = &chiptbl_88x7x[CHIPTABLESIZE - 1]; 1286 chip_found: 1287 /* 1288 * construct usbgem configration 1289 */ 1290 ugcp = kmem_zalloc(sizeof (*ugcp), KM_SLEEP); 1291 1292 /* name */ 1293 /* 1294 * softmac requires that ppa is the instance number 1295 * of the device, otherwise it hangs in seaching the device. 1296 */ 1297 (void) sprintf(ugcp->usbgc_name, "%s%d", drv_name, unit); 1298 ugcp->usbgc_ppa = unit; 1299 1300 ugcp->usbgc_ifnum = 0; 1301 ugcp->usbgc_alt = 0; 1302 1303 ugcp->usbgc_tx_list_max = 64; 1304 1305 ugcp->usbgc_rx_header_len = 0; 1306 ugcp->usbgc_rx_list_max = 64; 1307 1308 /* time out parameters */ 1309 ugcp->usbgc_tx_timeout = USBGEM_TX_TIMEOUT; 1310 ugcp->usbgc_tx_timeout_interval = USBGEM_TX_TIMEOUT_INTERVAL; 1311 1312 /* flow control */ 1313 /* 1314 * XXX - flow control caused link down frequently under 1315 * heavy traffic 1316 */ 1317 ugcp->usbgc_flow_control = FLOW_CONTROL_RX_PAUSE; 1318 1319 /* MII timeout parameters */ 1320 ugcp->usbgc_mii_link_watch_interval = ONESEC; 1321 ugcp->usbgc_mii_an_watch_interval = ONESEC/5; 1322 ugcp->usbgc_mii_reset_timeout = MII_RESET_TIMEOUT; /* 1 sec */ 1323 ugcp->usbgc_mii_an_timeout = MII_AN_TIMEOUT; /* 5 sec */ 1324 ugcp->usbgc_mii_an_wait = 0; 1325 ugcp->usbgc_mii_linkdown_timeout = MII_LINKDOWN_TIMEOUT; 1326 1327 ugcp->usbgc_mii_an_delay = ONESEC/10; 1328 ugcp->usbgc_mii_linkdown_action = MII_ACTION_RSA; 1329 ugcp->usbgc_mii_linkdown_timeout_action = MII_ACTION_RESET; 1330 ugcp->usbgc_mii_dont_reset = B_FALSE; 1331 ugcp->usbgc_mii_hw_link_detection = B_TRUE; 1332 ugcp->usbgc_mii_stop_mac_on_linkdown = B_FALSE; 1333 1334 /* I/O methods */ 1335 1336 /* mac operation */ 1337 ugcp->usbgc_attach_chip = &axf_attach_chip; 1338 ugcp->usbgc_reset_chip = &axf_reset_chip; 1339 ugcp->usbgc_init_chip = &axf_init_chip; 1340 ugcp->usbgc_start_chip = &axf_start_chip; 1341 ugcp->usbgc_stop_chip = &axf_stop_chip; 1342 ugcp->usbgc_multicast_hash = &axf_mcast_hash; 1343 1344 ugcp->usbgc_set_rx_filter = &axf_set_rx_filter; 1345 ugcp->usbgc_set_media = &axf_set_media; 1346 ugcp->usbgc_get_stats = &axf_get_stats; 1347 ugcp->usbgc_interrupt = &axf_interrupt; 1348 1349 /* packet operation */ 1350 ugcp->usbgc_tx_make_packet = &axf_tx_make_packet; 1351 ugcp->usbgc_rx_make_packet = &axf_rx_make_packet; 1352 1353 /* mii operations */ 1354 ugcp->usbgc_mii_probe = &axf_mii_probe; 1355 ugcp->usbgc_mii_init = &axf_mii_init; 1356 ugcp->usbgc_mii_config = &usbgem_mii_config_default; 1357 ugcp->usbgc_mii_read = &axf_mii_read; 1358 ugcp->usbgc_mii_write = &axf_mii_write; 1359 1360 /* mtu */ 1361 ugcp->usbgc_min_mtu = ETHERMTU; 1362 ugcp->usbgc_max_mtu = ETHERMTU; 1363 ugcp->usbgc_default_mtu = ETHERMTU; 1364 1365 lp = kmem_zalloc(sizeof (struct axf_dev), KM_SLEEP); 1366 lp->chip = p; 1367 lp->last_link_state = 0; 1368 lp->phy_has_reset = B_FALSE; 1369 1370 dp = usbgem_do_attach(dip, ugcp, lp, sizeof (struct axf_dev)); 1371 1372 kmem_free(ugcp, sizeof (*ugcp)); 1373 1374 if (dp != NULL) { 1375 return (DDI_SUCCESS); 1376 } 1377 1378 err_free_mem: 1379 kmem_free(lp, sizeof (struct axf_dev)); 1380 err_close_pipe: 1381 err: 1382 return (DDI_FAILURE); 1383 } 1384 1385 if (cmd == DDI_RESUME) { 1386 return (usbgem_resume(dip)); 1387 } 1388 1389 return (DDI_FAILURE); 1390 } 1391 1392 static int 1393 axfdetach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1394 { 1395 int ret; 1396 1397 if (cmd == DDI_DETACH) { 1398 ret = usbgem_do_detach(dip); 1399 if (ret != DDI_SUCCESS) { 1400 return (DDI_FAILURE); 1401 } 1402 return (DDI_SUCCESS); 1403 } 1404 if (cmd == DDI_SUSPEND) { 1405 return (usbgem_suspend(dip)); 1406 } 1407 return (DDI_FAILURE); 1408 } 1409 1410 /* ======================================================== */ 1411 /* 1412 * OS depend (loadable streams driver) routine 1413 */ 1414 /* ======================================================== */ 1415 USBGEM_STREAM_OPS(axf_ops, axfattach, axfdetach); 1416 1417 static struct modldrv modldrv = { 1418 &mod_driverops, /* Type of module. This one is a driver */ 1419 ident, 1420 &axf_ops, /* driver ops */ 1421 }; 1422 1423 static struct modlinkage modlinkage = { 1424 MODREV_1, &modldrv, NULL 1425 }; 1426 1427 /* ======================================================== */ 1428 /* 1429 * _init : done 1430 */ 1431 /* ======================================================== */ 1432 int 1433 _init(void) 1434 { 1435 int status; 1436 1437 DPRINTF(2, (CE_CONT, "!axf: _init: called")); 1438 1439 status = usbgem_mod_init(&axf_ops, "axf"); 1440 if (status != DDI_SUCCESS) { 1441 return (status); 1442 } 1443 status = mod_install(&modlinkage); 1444 if (status != DDI_SUCCESS) { 1445 usbgem_mod_fini(&axf_ops); 1446 } 1447 return (status); 1448 } 1449 1450 /* 1451 * _fini : done 1452 */ 1453 int 1454 _fini(void) 1455 { 1456 int status; 1457 1458 DPRINTF(2, (CE_CONT, "!axf: _fini: called")); 1459 status = mod_remove(&modlinkage); 1460 if (status == DDI_SUCCESS) { 1461 usbgem_mod_fini(&axf_ops); 1462 } 1463 return (status); 1464 } 1465 1466 int 1467 _info(struct modinfo *modinfop) 1468 { 1469 return (mod_info(&modlinkage, modinfop)); 1470 } 1471