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 static void 795 axf_dump_packet(struct usbgem_dev *dp, uint8_t *bp, int n) 796 { 797 int i; 798 799 for (i = 0; i < n; i += 8, bp += 8) { 800 cmn_err(CE_CONT, "%02x %02x %02x %02x %02x %02x %02x %02x", 801 bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]); 802 } 803 } 804 805 static mblk_t * 806 axf_rx_make_packet(struct usbgem_dev *dp, mblk_t *mp) 807 { 808 mblk_t *tp; 809 uintptr_t rest; 810 811 if (AX88172(dp)) { 812 return (mp); 813 } 814 815 tp = mp; 816 rest = (uintptr_t)tp->b_wptr - (uintptr_t)tp->b_rptr; 817 818 if (rest <= PKT_HEADER_SIZE) { 819 /* 820 * the usb bulk-in frame doesn't include any valid 821 * ethernet packets. 822 */ 823 return (NULL); 824 } 825 826 for (; ; ) { 827 uint16_t len; 828 uint16_t cksum; 829 830 /* analyse the header of the received usb frame */ 831 len = LE16P(tp->b_rptr + 0); 832 cksum = LE16P(tp->b_rptr + 2); 833 834 /* test if the header is valid */ 835 if (len + cksum != 0xffff) { 836 /* discard whole the packet */ 837 cmn_err(CE_WARN, 838 "!%s: %s: corrupted header:%04x %04x", 839 dp->name, __func__, len, cksum); 840 return (NULL); 841 } 842 #if DEBUG_LEVEL > 0 843 if (len < ETHERMIN || len > ETHERMAX) { 844 cmn_err(CE_NOTE, 845 "!%s: %s: incorrect pktsize:%d", 846 dp->name, __func__, len); 847 } 848 #endif 849 /* extract a ethernet packet from the bulk-in frame */ 850 tp->b_rptr += PKT_HEADER_SIZE; 851 tp->b_wptr = tp->b_rptr + len; 852 853 if (len & 1) { 854 /* 855 * skip a tailing pad byte if the packet 856 * length is odd 857 */ 858 len++; 859 } 860 rest -= len + PKT_HEADER_SIZE; 861 862 if (rest <= PKT_HEADER_SIZE) { 863 /* no more vaild ethernet packets */ 864 break; 865 } 866 867 #if DEBUG_LEVEL > 10 868 axf_dump_packet(dp, tp->b_wptr, 18); 869 #endif 870 /* allocate a mblk_t header for the next ethernet packet */ 871 tp->b_next = dupb(mp); 872 tp->b_next->b_rptr = tp->b_rptr + len; 873 tp = tp->b_next; 874 } 875 876 return (mp); 877 } 878 879 /* 880 * MII Interfaces 881 */ 882 static uint16_t 883 axf_mii_read(struct usbgem_dev *dp, uint_t index, int *errp) 884 { 885 uint8_t buf[2]; 886 uint16_t val; 887 888 DPRINTF(4, (CE_CONT, "!%s: %s: called, ix:%d", 889 dp->name, __func__, index)); 890 891 /* switch to software MII operation mode */ 892 OUT(dp, VCMD_SOFTWARE_MII_OP, 0, 0, 0, NULL, errp, usberr); 893 894 /* Read MII register */ 895 IN(dp, VCMD_READ_MII_REG, dp->mii_phy_addr, index, 896 2, buf, errp, usberr); 897 898 /* switch to hardware MII operation mode */ 899 OUT(dp, VCMD_HARDWARE_MII_OP, 0, 0, 0, NULL, errp, usberr); 900 901 return (LE16P(buf)); 902 903 usberr: 904 cmn_err(CE_CONT, 905 "!%s: %s: usberr(%d) detected", dp->name, __func__, *errp); 906 return (0); 907 } 908 909 static void 910 axf_mii_write(struct usbgem_dev *dp, uint_t index, uint16_t val, int *errp) 911 { 912 uint8_t buf[2]; 913 914 DPRINTF(4, (CE_CONT, "!%s: %s called, reg:%x val:%x", 915 dp->name, __func__, index, val)); 916 917 /* switch software MII operation mode */ 918 OUT(dp, VCMD_SOFTWARE_MII_OP, 0, 0, 0, NULL, errp, usberr); 919 920 /* Write to the specified MII register */ 921 buf[0] = (uint8_t)val; 922 buf[1] = (uint8_t)(val >> 8); 923 OUT(dp, VCMD_WRITE_MII_REG, dp->mii_phy_addr, index, 924 2, buf, errp, usberr); 925 926 /* switch to hardware MII operation mode */ 927 OUT(dp, VCMD_HARDWARE_MII_OP, 0, 0, 0, NULL, errp, usberr); 928 929 usberr: 930 ; 931 } 932 933 static void 934 axf_interrupt(struct usbgem_dev *dp, mblk_t *mp) 935 { 936 uint8_t *bp; 937 struct axf_dev *lp = dp->private; 938 939 bp = mp->b_rptr; 940 941 DPRINTF(2, (CE_CONT, 942 "!%s: %s: size:%d, %02x %02x %02x %02x %02x %02x %02x %02x", 943 dp->name, __func__, mp->b_wptr - mp->b_rptr, 944 bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7])); 945 946 if (lp->last_link_state ^ bp[2]) { 947 usbgem_mii_update_link(dp); 948 } 949 950 lp->last_link_state = bp[2]; 951 } 952 953 /* ======================================================== */ 954 /* 955 * OS depend (device driver DKI) routine 956 */ 957 /* ======================================================== */ 958 #ifdef DEBUG_LEVEL 959 static void 960 axf_eeprom_dump(struct usbgem_dev *dp, int size) 961 { 962 int i; 963 int err; 964 uint8_t w0[2], w1[2], w2[2], w3[2]; 965 966 cmn_err(CE_CONT, "!%s: eeprom dump:", dp->name); 967 968 err = USB_SUCCESS; 969 970 for (i = 0; i < size; i += 4) { 971 IN(dp, VCMD_READ_SROM, i + 0, 0, 2, w0, &err, usberr); 972 IN(dp, VCMD_READ_SROM, i + 1, 0, 2, w1, &err, usberr); 973 IN(dp, VCMD_READ_SROM, i + 2, 0, 2, w2, &err, usberr); 974 IN(dp, VCMD_READ_SROM, i + 3, 0, 2, w3, &err, usberr); 975 cmn_err(CE_CONT, "!0x%02x: 0x%04x 0x%04x 0x%04x 0x%04x", 976 i, 977 (w0[1] << 8) | w0[0], 978 (w1[1] << 8) | w1[0], 979 (w2[1] << 8) | w2[0], 980 (w3[1] << 8) | w3[0]); 981 } 982 usberr: 983 ; 984 } 985 #endif 986 987 static int 988 axf_attach_chip(struct usbgem_dev *dp) 989 { 990 uint8_t phys[2]; 991 int err; 992 uint_t vcmd; 993 int ret; 994 #ifdef CONFIG_FULLSIZE_VLAN 995 uint8_t maxpktsize[2]; 996 uint16_t vlan_pktsize; 997 #endif 998 #ifdef DEBUG_LEVEL 999 uint8_t val8; 1000 #endif 1001 struct axf_dev *lp = dp->private; 1002 1003 DPRINTF(0, (CE_CONT, "!%s: %s enter", dp->name, __func__)); 1004 1005 ret = USB_SUCCESS; 1006 /* 1007 * mac address in EEPROM has loaded to ID registers. 1008 */ 1009 vcmd = AX88172(dp) ? VCMD_READ_NODE_ID : VCMD_READ_NODE_ID_88772; 1010 IN(dp, vcmd, 0, 0, 1011 ETHERADDRL, dp->dev_addr.ether_addr_octet, &err, usberr); 1012 1013 /* 1014 * setup IPG values 1015 */ 1016 lp->ipg[0] = 0x15; 1017 lp->ipg[1] = 0x0c; 1018 lp->ipg[2] = 0x12; 1019 1020 /* 1021 * We cannot scan phy because the nic returns undefined 1022 * value, i.e. remained garbage, when MII phy is not at the 1023 * specified index. 1024 */ 1025 #ifdef DEBUG_LEVELx 1026 if (lp->chip->vid == 0x07b8 && lp->chip->pid == 0x420a) { 1027 /* 1028 * restore the original phy address of brain 1029 * damaged Planex UE2-100TX 1030 */ 1031 OUT(dp, VCMD_WRITE_SROM_ENABLE, 0, 0, 0, NULL, &err, usberr); 1032 OUT(dp, VCMD_WRITE_SROM, 0x11, 0xe004, 0, NULL, &err, usberr); 1033 OUT(dp, VCMD_WRITE_SROM_DISABLE, 0, 0, 0, NULL, &err, usberr); 1034 } 1035 #endif 1036 if (AX88172(dp)) { 1037 IN(dp, VCMD_READ_PHY_IDS, 0, 0, 2, &phys, &err, usberr); 1038 dp->mii_phy_addr = phys[1]; 1039 DPRINTF(0, (CE_CONT, "!%s: %s: phys_addr:%d %d", 1040 dp->name, __func__, phys[0], phys[1])); 1041 } else { 1042 /* use built-in phy */ 1043 dp->mii_phy_addr = 0x10; 1044 } 1045 1046 dp->misc_flag |= USBGEM_VLAN; 1047 #ifdef CONFIG_FULLSIZE_VLAN 1048 if (AX88172(dp) || AX88772(dp)) { 1049 /* check max packet size in srom */ 1050 IN(dp, VCMD_READ_SROM, 0x10, 0, 2, maxpktsize, &err, usberr); 1051 vlan_pktsize = ETHERMAX + ETHERFCSL + 4 /* VTAG_SIZE */; 1052 1053 if (LE16P(maxpktsize) < vlan_pktsize) { 1054 cmn_err(CE_CONT, 1055 "!%s: %s: max packet size in srom is too small, " 1056 "changing %d -> %d, do power cycle for the device", 1057 dp->name, __func__, 1058 LE16P(maxpktsize), vlan_pktsize); 1059 OUT(dp, VCMD_WRITE_SROM_ENABLE, 1060 0, 0, 0, NULL, &err, usberr); 1061 OUT(dp, VCMD_WRITE_SROM, 0x10, 1062 vlan_pktsize, 0, NULL, &err, usberr); 1063 OUT(dp, VCMD_WRITE_SROM_DISABLE, 1064 0, 0, 0, NULL, &err, usberr); 1065 1066 /* need to power off the device */ 1067 ret = USB_FAILURE; 1068 } 1069 } 1070 #endif 1071 #ifdef DEBUG_LEVEL 1072 IN(dp, VCMD_READ_GPIO, 0, 0, 1, &val8, &err, usberr); 1073 cmn_err(CE_CONT, 1074 "!%s: %s: ipg 0x%02x 0x%02x 0x%02x, gpio 0x%b", 1075 dp->name, __func__, lp->ipg[0], lp->ipg[1], lp->ipg[2], 1076 val8, GPIO_BITS); 1077 #endif 1078 /* fix rx buffer size */ 1079 if (!AX88172(dp)) { 1080 dp->rx_buf_len = 2048; 1081 } 1082 1083 #if DEBUG_LEVEL > 0 1084 axf_eeprom_dump(dp, 0x20); 1085 #endif 1086 return (ret); 1087 1088 usberr: 1089 cmn_err(CE_WARN, "%s: %s: usb error detected (%d)", 1090 dp->name, __func__, err); 1091 return (USB_FAILURE); 1092 } 1093 1094 static boolean_t 1095 axf_scan_phy(struct usbgem_dev *dp) 1096 { 1097 int i; 1098 int err; 1099 uint16_t val; 1100 int phy_addr_saved; 1101 struct axf_dev *lp = dp->private; 1102 1103 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 1104 1105 phy_addr_saved = dp->mii_phy_addr; 1106 1107 /* special probe routine for unreliable MII addr */ 1108 #define PROBE_PAT \ 1109 (MII_ABILITY_100BASE_TX_FD | \ 1110 MII_ABILITY_100BASE_TX | \ 1111 MII_ABILITY_10BASE_T_FD | \ 1112 MII_ABILITY_10BASE_T) 1113 1114 for (i = 0; i < 32; i++) { 1115 dp->mii_phy_addr = i; 1116 axf_mii_write(dp, MII_AN_ADVERT, 0, &err); 1117 if (err != USBGEM_SUCCESS) { 1118 break; 1119 } 1120 val = axf_mii_read(dp, MII_AN_ADVERT, &err); 1121 if (err != USBGEM_SUCCESS) { 1122 break; 1123 } 1124 if (val != 0) { 1125 DPRINTF(0, (CE_CONT, "!%s: %s: index:%d, val %b != 0", 1126 dp->name, __func__, i, val, MII_ABILITY_BITS)); 1127 continue; 1128 } 1129 1130 axf_mii_write(dp, MII_AN_ADVERT, PROBE_PAT, &err); 1131 if (err != USBGEM_SUCCESS) { 1132 break; 1133 } 1134 val = axf_mii_read(dp, MII_AN_ADVERT, &err); 1135 if (err != USBGEM_SUCCESS) { 1136 break; 1137 } 1138 if ((val & MII_ABILITY_TECH) != PROBE_PAT) { 1139 DPRINTF(0, (CE_CONT, "!%s: %s: " 1140 "index:%d, pat:%x != val:%b", 1141 dp->name, __func__, i, 1142 PROBE_PAT, val, MII_ABILITY_BITS)); 1143 continue; 1144 } 1145 1146 /* found */ 1147 dp->mii_phy_addr = phy_addr_saved; 1148 return (i); 1149 } 1150 #undef PROBE_PAT 1151 if (i == 32) { 1152 cmn_err(CE_CONT, "!%s: %s: no mii phy found", 1153 dp->name, __func__); 1154 } else { 1155 cmn_err(CE_CONT, "!%s: %s: i/o error while scanning phy", 1156 dp->name, __func__); 1157 } 1158 dp->mii_phy_addr = phy_addr_saved; 1159 return (-1); 1160 } 1161 1162 static int 1163 axf_mii_probe(struct usbgem_dev *dp) 1164 { 1165 int my_guess; 1166 int err; 1167 uint8_t old_11th[2]; 1168 uint8_t new_11th[2]; 1169 struct axf_dev *lp = dp->private; 1170 1171 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 1172 (void) axf_reset_phy(dp); 1173 lp->phy_has_reset = B_TRUE; 1174 1175 if (AX88172(dp)) { 1176 my_guess = axf_scan_phy(dp); 1177 if (my_guess >= 0 && my_guess < 32 && 1178 my_guess != dp->mii_phy_addr) { 1179 /* 1180 * phy addr in srom is wrong, need to fix it 1181 */ 1182 IN(dp, VCMD_READ_SROM, 1183 0x11, 0, 2, old_11th, &err, usberr); 1184 1185 new_11th[0] = my_guess; 1186 new_11th[1] = old_11th[1]; 1187 1188 OUT(dp, VCMD_WRITE_SROM_ENABLE, 1189 0, 0, 0, NULL, &err, usberr); 1190 OUT(dp, VCMD_WRITE_SROM, 1191 0x11, LE16P(new_11th), 0, NULL, &err, usberr); 1192 OUT(dp, VCMD_WRITE_SROM_DISABLE, 1193 0, 0, 0, NULL, &err, usberr); 1194 #if 1 1195 /* XXX - read back, but it doesn't work, why? */ 1196 delay(drv_usectohz(1000*1000)); 1197 IN(dp, VCMD_READ_SROM, 1198 0x11, 0, 2, new_11th, &err, usberr); 1199 #endif 1200 cmn_err(CE_NOTE, "!%s: %s: phy addr in srom fixed: " 1201 "%04x -> %04x", 1202 dp->name, __func__, 1203 LE16P(old_11th), LE16P(new_11th)); 1204 return (USBGEM_FAILURE); 1205 usberr: 1206 cmn_err(CE_NOTE, 1207 "!%s: %s: failed to patch phy addr, " 1208 "current: %04x", 1209 dp->name, __func__, LE16P(old_11th)); 1210 return (USBGEM_FAILURE); 1211 } 1212 } 1213 return (usbgem_mii_probe_default(dp)); 1214 } 1215 1216 static int 1217 axf_mii_init(struct usbgem_dev *dp) 1218 { 1219 struct axf_dev *lp = dp->private; 1220 1221 DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 1222 1223 if (!lp->phy_has_reset) { 1224 (void) axf_reset_phy(dp); 1225 } 1226 1227 /* prepare to reset phy on the next reconnect or resume */ 1228 lp->phy_has_reset = B_FALSE; 1229 1230 return (USB_SUCCESS); 1231 } 1232 1233 static int 1234 axfattach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1235 { 1236 int i; 1237 ddi_iblock_cookie_t c; 1238 int ret; 1239 int revid; 1240 int unit; 1241 int vid; 1242 int pid; 1243 struct chip_info *p; 1244 int len; 1245 const char *drv_name; 1246 struct usbgem_dev *dp; 1247 void *base; 1248 struct usbgem_conf *ugcp; 1249 struct axf_dev *lp; 1250 1251 unit = ddi_get_instance(dip); 1252 drv_name = ddi_driver_name(dip); 1253 1254 DPRINTF(3, (CE_CONT, "!%s%d: %s: called, cmd:%d", 1255 drv_name, unit, __func__, cmd)); 1256 1257 if (cmd == DDI_ATTACH) { 1258 /* 1259 * Check if the chip is supported. 1260 */ 1261 vid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1262 "usb-vendor-id", -1); 1263 pid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1264 "usb-product-id", -1); 1265 revid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1266 "usb-revision-id", -1); 1267 1268 for (i = 0, p = chiptbl_88x7x; i < CHIPTABLESIZE; i++, p++) { 1269 if (p->vid == vid && p->pid == pid) { 1270 /* found */ 1271 cmn_err(CE_CONT, "!%s%d: %s " 1272 "(vid: 0x%04x, did: 0x%04x, revid: 0x%02x)", 1273 drv_name, unit, p->name, vid, pid, revid); 1274 goto chip_found; 1275 } 1276 } 1277 1278 /* Not found */ 1279 cmn_err(CE_WARN, "!%s: %s: wrong usb venid/prodid (0x%x, 0x%x)", 1280 drv_name, __func__, vid, pid); 1281 1282 /* assume 88772 */ 1283 p = &chiptbl_88x7x[CHIPTABLESIZE - 1]; 1284 chip_found: 1285 /* 1286 * construct usbgem configration 1287 */ 1288 ugcp = kmem_zalloc(sizeof (*ugcp), KM_SLEEP); 1289 1290 /* name */ 1291 /* 1292 * softmac requires that ppa is the instance number 1293 * of the device, otherwise it hangs in seaching the device. 1294 */ 1295 (void) sprintf(ugcp->usbgc_name, "%s%d", drv_name, unit); 1296 ugcp->usbgc_ppa = unit; 1297 1298 ugcp->usbgc_ifnum = 0; 1299 ugcp->usbgc_alt = 0; 1300 1301 ugcp->usbgc_tx_list_max = 64; 1302 1303 ugcp->usbgc_rx_header_len = 0; 1304 ugcp->usbgc_rx_list_max = 64; 1305 1306 /* time out parameters */ 1307 ugcp->usbgc_tx_timeout = USBGEM_TX_TIMEOUT; 1308 ugcp->usbgc_tx_timeout_interval = USBGEM_TX_TIMEOUT_INTERVAL; 1309 1310 /* flow control */ 1311 /* 1312 * XXX - flow control caused link down frequently under 1313 * heavy traffic 1314 */ 1315 ugcp->usbgc_flow_control = FLOW_CONTROL_RX_PAUSE; 1316 1317 /* MII timeout parameters */ 1318 ugcp->usbgc_mii_link_watch_interval = ONESEC; 1319 ugcp->usbgc_mii_an_watch_interval = ONESEC/5; 1320 ugcp->usbgc_mii_reset_timeout = MII_RESET_TIMEOUT; /* 1 sec */ 1321 ugcp->usbgc_mii_an_timeout = MII_AN_TIMEOUT; /* 5 sec */ 1322 ugcp->usbgc_mii_an_wait = 0; 1323 ugcp->usbgc_mii_linkdown_timeout = MII_LINKDOWN_TIMEOUT; 1324 1325 ugcp->usbgc_mii_an_delay = ONESEC/10; 1326 ugcp->usbgc_mii_linkdown_action = MII_ACTION_RSA; 1327 ugcp->usbgc_mii_linkdown_timeout_action = MII_ACTION_RESET; 1328 ugcp->usbgc_mii_dont_reset = B_FALSE; 1329 ugcp->usbgc_mii_hw_link_detection = B_TRUE; 1330 ugcp->usbgc_mii_stop_mac_on_linkdown = B_FALSE; 1331 1332 /* I/O methods */ 1333 1334 /* mac operation */ 1335 ugcp->usbgc_attach_chip = &axf_attach_chip; 1336 ugcp->usbgc_reset_chip = &axf_reset_chip; 1337 ugcp->usbgc_init_chip = &axf_init_chip; 1338 ugcp->usbgc_start_chip = &axf_start_chip; 1339 ugcp->usbgc_stop_chip = &axf_stop_chip; 1340 ugcp->usbgc_multicast_hash = &axf_mcast_hash; 1341 1342 ugcp->usbgc_set_rx_filter = &axf_set_rx_filter; 1343 ugcp->usbgc_set_media = &axf_set_media; 1344 ugcp->usbgc_get_stats = &axf_get_stats; 1345 ugcp->usbgc_interrupt = &axf_interrupt; 1346 1347 /* packet operation */ 1348 ugcp->usbgc_tx_make_packet = &axf_tx_make_packet; 1349 ugcp->usbgc_rx_make_packet = &axf_rx_make_packet; 1350 1351 /* mii operations */ 1352 ugcp->usbgc_mii_probe = &axf_mii_probe; 1353 ugcp->usbgc_mii_init = &axf_mii_init; 1354 ugcp->usbgc_mii_config = &usbgem_mii_config_default; 1355 ugcp->usbgc_mii_read = &axf_mii_read; 1356 ugcp->usbgc_mii_write = &axf_mii_write; 1357 1358 /* mtu */ 1359 ugcp->usbgc_min_mtu = ETHERMTU; 1360 ugcp->usbgc_max_mtu = ETHERMTU; 1361 ugcp->usbgc_default_mtu = ETHERMTU; 1362 1363 lp = kmem_zalloc(sizeof (struct axf_dev), KM_SLEEP); 1364 lp->chip = p; 1365 lp->last_link_state = 0; 1366 lp->phy_has_reset = B_FALSE; 1367 1368 dp = usbgem_do_attach(dip, ugcp, lp, sizeof (struct axf_dev)); 1369 1370 kmem_free(ugcp, sizeof (*ugcp)); 1371 1372 if (dp != NULL) { 1373 return (DDI_SUCCESS); 1374 } 1375 1376 err_free_mem: 1377 kmem_free(lp, sizeof (struct axf_dev)); 1378 err_close_pipe: 1379 err: 1380 return (DDI_FAILURE); 1381 } 1382 1383 if (cmd == DDI_RESUME) { 1384 return (usbgem_resume(dip)); 1385 } 1386 1387 return (DDI_FAILURE); 1388 } 1389 1390 static int 1391 axfdetach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1392 { 1393 int ret; 1394 1395 if (cmd == DDI_DETACH) { 1396 ret = usbgem_do_detach(dip); 1397 if (ret != DDI_SUCCESS) { 1398 return (DDI_FAILURE); 1399 } 1400 return (DDI_SUCCESS); 1401 } 1402 if (cmd == DDI_SUSPEND) { 1403 return (usbgem_suspend(dip)); 1404 } 1405 return (DDI_FAILURE); 1406 } 1407 1408 /* ======================================================== */ 1409 /* 1410 * OS depend (loadable streams driver) routine 1411 */ 1412 /* ======================================================== */ 1413 #ifdef USBGEM_CONFIG_GLDv3 1414 USBGEM_STREAM_OPS(axf_ops, axfattach, axfdetach); 1415 #else 1416 static struct module_info axfminfo = { 1417 0, /* mi_idnum */ 1418 "axf", /* mi_idname */ 1419 0, /* mi_minpsz */ 1420 ETHERMTU, /* mi_maxpsz */ 1421 ETHERMTU*128, /* mi_hiwat */ 1422 1, /* mi_lowat */ 1423 }; 1424 1425 static struct qinit axfrinit = { 1426 (int (*)()) NULL, /* qi_putp */ 1427 usbgem_rsrv, /* qi_srvp */ 1428 usbgem_open, /* qi_qopen */ 1429 usbgem_close, /* qi_qclose */ 1430 (int (*)()) NULL, /* qi_qadmin */ 1431 &axfminfo, /* qi_minfo */ 1432 NULL /* qi_mstat */ 1433 }; 1434 1435 static struct qinit axfwinit = { 1436 usbgem_wput, /* qi_putp */ 1437 usbgem_wsrv, /* qi_srvp */ 1438 (int (*)()) NULL, /* qi_qopen */ 1439 (int (*)()) NULL, /* qi_qclose */ 1440 (int (*)()) NULL, /* qi_qadmin */ 1441 &axfminfo, /* qi_minfo */ 1442 NULL /* qi_mstat */ 1443 }; 1444 1445 static struct streamtab axf_info = { 1446 &axfrinit, /* st_rdinit */ 1447 &axfwinit, /* st_wrinit */ 1448 NULL, /* st_muxrinit */ 1449 NULL /* st_muxwrinit */ 1450 }; 1451 1452 static struct cb_ops cb_axf_ops = { 1453 nulldev, /* cb_open */ 1454 nulldev, /* cb_close */ 1455 nodev, /* cb_strategy */ 1456 nodev, /* cb_print */ 1457 nodev, /* cb_dump */ 1458 nodev, /* cb_read */ 1459 nodev, /* cb_write */ 1460 nodev, /* cb_ioctl */ 1461 nodev, /* cb_devmap */ 1462 nodev, /* cb_mmap */ 1463 nodev, /* cb_segmap */ 1464 nochpoll, /* cb_chpoll */ 1465 ddi_prop_op, /* cb_prop_op */ 1466 &axf_info, /* cb_stream */ 1467 D_NEW|D_MP /* cb_flag */ 1468 }; 1469 1470 static struct dev_ops axf_ops = { 1471 DEVO_REV, /* devo_rev */ 1472 0, /* devo_refcnt */ 1473 usbgem_getinfo, /* devo_getinfo */ 1474 nulldev, /* devo_identify */ 1475 nulldev, /* devo_probe */ 1476 axfattach, /* devo_attach */ 1477 axfdetach, /* devo_detach */ 1478 nodev, /* devo_reset */ 1479 &cb_axf_ops, /* devo_cb_ops */ 1480 NULL, /* devo_bus_ops */ 1481 usbgem_power, /* devo_power */ 1482 #if DEVO_REV >= 4 1483 usbgem_quiesce, /* devo_quiesce */ 1484 #endif 1485 }; 1486 #endif 1487 1488 static struct modldrv modldrv = { 1489 &mod_driverops, /* Type of module. This one is a driver */ 1490 ident, 1491 &axf_ops, /* driver ops */ 1492 }; 1493 1494 static struct modlinkage modlinkage = { 1495 MODREV_1, &modldrv, NULL 1496 }; 1497 1498 /* ======================================================== */ 1499 /* 1500 * _init : done 1501 */ 1502 /* ======================================================== */ 1503 int 1504 _init(void) 1505 { 1506 int status; 1507 1508 DPRINTF(2, (CE_CONT, "!axf: _init: called")); 1509 1510 status = usbgem_mod_init(&axf_ops, "axf"); 1511 if (status != DDI_SUCCESS) { 1512 return (status); 1513 } 1514 status = mod_install(&modlinkage); 1515 if (status != DDI_SUCCESS) { 1516 usbgem_mod_fini(&axf_ops); 1517 } 1518 return (status); 1519 } 1520 1521 /* 1522 * _fini : done 1523 */ 1524 int 1525 _fini(void) 1526 { 1527 int status; 1528 1529 DPRINTF(2, (CE_CONT, "!axf: _fini: called")); 1530 status = mod_remove(&modlinkage); 1531 if (status == DDI_SUCCESS) { 1532 usbgem_mod_fini(&axf_ops); 1533 } 1534 return (status); 1535 } 1536 1537 int 1538 _info(struct modinfo *modinfop) 1539 { 1540 return (mod_info(&modlinkage, modinfop)); 1541 } 1542