1 /* 2 * urf_usbgem.c : Realtek RTL8150 USB to Fast Ethernet Driver for Solaris 3 * 4 * Copyright (c) 2003-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 /* 35 * Changelog: 36 */ 37 38 /* 39 * TODO 40 */ 41 /* ======================================================= */ 42 43 /* 44 * Solaris system header files and macros 45 */ 46 47 /* minimum kernel headers for drivers */ 48 #include <sys/types.h> 49 #include <sys/conf.h> 50 #include <sys/debug.h> 51 #include <sys/kmem.h> 52 #include <sys/modctl.h> 53 #include <sys/errno.h> 54 #include <sys/ddi.h> 55 #include <sys/sunddi.h> 56 #include <sys/byteorder.h> 57 58 /* ethernet stuff */ 59 #include <sys/ethernet.h> 60 61 /* interface card depend stuff */ 62 #include <sys/stropts.h> 63 #include <sys/stream.h> 64 #include <sys/strlog.h> 65 #include <sys/usb/usba.h> 66 #include "usbgem.h" 67 #include "usbgem_mii.h" 68 #include "rtl8150reg.h" 69 70 char ident[] = "rtl8150 usbnic driver v" VERSION; 71 72 /* 73 * Useful macros 74 */ 75 #define ROUNDUP2(x, y) (((x)+(y)-1) & ~((y)-1)) 76 #define CHECK_AND_JUMP(err, label) if (err != USB_SUCCESS) goto label 77 78 /* 79 * Debugging 80 */ 81 #ifdef DEBUG_LEVEL 82 static int urf_debug = DEBUG_LEVEL; 83 #define DPRINTF(n, args) if (urf_debug > (n)) cmn_err args 84 #else 85 #define DPRINTF(n, args) 86 #endif 87 88 /* 89 * Our configration for rtl8150 90 */ 91 /* timeouts */ 92 #define ONESEC (drv_usectohz(1*1000000)) 93 94 /* 95 * Local device definitions 96 */ 97 struct chip_info { 98 int flags; 99 char *name; 100 int type; 101 }; 102 103 #define CHIPTABLESIZE (sizeof (chiptbl_8150) / sizeof (struct chip_info)) 104 105 struct urf_dev { 106 /* 107 * Misc HW information 108 */ 109 struct chip_info *chip; 110 uint8_t cr; 111 uint8_t tsr; 112 uint16_t rcr; 113 uint8_t txok_cnt; 114 }; 115 116 /* 117 * private functions 118 */ 119 120 /* mii operations */ 121 static uint16_t urf_mii_read(struct usbgem_dev *, uint_t, int *errp); 122 static void urf_mii_write(struct usbgem_dev *, uint_t, uint16_t, int *errp); 123 124 /* nic operations */ 125 static int urf_attach_chip(struct usbgem_dev *); 126 static int urf_reset_chip(struct usbgem_dev *); 127 static int urf_init_chip(struct usbgem_dev *); 128 static int urf_start_chip(struct usbgem_dev *); 129 static int urf_stop_chip(struct usbgem_dev *); 130 static int urf_set_media(struct usbgem_dev *); 131 static int urf_set_rx_filter(struct usbgem_dev *); 132 static int urf_get_stats(struct usbgem_dev *); 133 134 /* packet operations */ 135 static mblk_t *urf_tx_make_packet(struct usbgem_dev *, mblk_t *); 136 static mblk_t *urf_rx_make_packet(struct usbgem_dev *, mblk_t *); 137 138 /* =============================================================== */ 139 /* 140 * I/O functions 141 */ 142 /* =============================================================== */ 143 #define OUTB(dp, p, v, errp, label) \ 144 if ((*(errp) = usbgem_ctrl_out_val((dp), \ 145 /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \ 146 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 147 /* bRequest */ USB_REQ_SET_ADDRESS, \ 148 /* wValue */ (p), \ 149 /* wIndex */ 0, \ 150 /* wLength */ 1, \ 151 /* value */ (v))) != USB_SUCCESS) goto label 152 153 #define OUTW(dp, p, v, errp, label) \ 154 if ((*(errp) = usbgem_ctrl_out_val((dp), \ 155 /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \ 156 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 157 /* bRequest */ USB_REQ_SET_ADDRESS, \ 158 /* wValue */ (p), \ 159 /* wIndex */ 0, \ 160 /* wLength */ 2, \ 161 /* value */ (v))) != USB_SUCCESS) goto label 162 163 /* BEGIN CSTYLED */ 164 #define OUTS(dp, p, buf, len, errp, label) \ 165 if ((*(errp) = usbgem_ctrl_out((dp), \ 166 /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \ 167 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 168 /* bRequest */ USB_REQ_SET_ADDRESS, \ 169 /* wValue */ (p), \ 170 /* wIndex */ 0, \ 171 /* wLength */ (len), \ 172 /* value */ (buf), \ 173 /* size */ (len))) != USB_SUCCESS) goto label 174 /* END CSTYLED */ 175 176 #define IN(dp, p, vp, errp, label) \ 177 if ((*(errp) = usbgem_ctrl_in_val((dp), \ 178 /* bmRequestType */ USB_DEV_REQ_DEV_TO_HOST \ 179 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 180 /* bRequest */ USB_REQ_SET_ADDRESS, \ 181 /* wValue */ (p), \ 182 /* wIndex */ 0, \ 183 /* wLength */ sizeof ((*vp)), \ 184 /* valuep */ (vp))) != USB_SUCCESS) goto label 185 186 #define INS(dp, p, buf, len, errp, label) \ 187 if ((*(errp) = usbgem_ctrl_in((dp), \ 188 /* bmRequestType */ USB_DEV_REQ_DEV_TO_HOST \ 189 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 190 /* bRequest */ USB_REQ_SET_ADDRESS, \ 191 /* wValue */ (p), \ 192 /* wIndex */ 0, \ 193 /* wLength */ (len), \ 194 /* valuep */ (buf), \ 195 /* size */ (len))) != USB_SUCCESS) goto label 196 197 /* =============================================================== */ 198 /* 199 * variables 200 */ 201 /* =============================================================== */ 202 static int urf_ppa = 0; 203 204 /* =============================================================== */ 205 /* 206 * Hardware manupilation 207 */ 208 /* =============================================================== */ 209 static int 210 urf_reset_chip(struct usbgem_dev *dp) 211 { 212 int i; 213 int err; 214 uint8_t reg; 215 struct urf_dev *lp = dp->private; 216 217 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 218 219 lp->cr = 0; 220 OUTB(dp, CR, lp->cr | CR_SOFT_RST, &err, usberr); 221 222 for (i = 0; i < 100; i++) { 223 IN(dp, CR, ®, &err, usberr); 224 if ((reg & CR_SOFT_RST) == 0) { 225 return (USB_SUCCESS); 226 } 227 } 228 /* time out */ 229 cmn_err(CE_WARN, "%s: failed to reset: timeout", dp->name); 230 return (USB_FAILURE); 231 232 usberr: 233 cmn_err(CE_NOTE, "!%s: %s: usberr detected", dp->name, __func__); 234 return (USB_FAILURE); 235 } 236 237 /* 238 * Setup rtl8150 239 */ 240 static int 241 urf_init_chip(struct usbgem_dev *dp) 242 { 243 int i; 244 uint32_t val; 245 int err; 246 struct urf_dev *lp = dp->private; 247 248 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 249 250 /* ID registers: set later by urf_set_rx_filter */ 251 252 /* Multicast registers: set later by urf_set_rx_filter */ 253 254 /* Command register : Enable Tx and Rx before writing TCR and RCR */ 255 lp->cr |= CR_RE | CR_TE; 256 OUTB(dp, CR, lp->cr, &err, usberr); 257 258 /* Transmit configration register : */ 259 OUTB(dp, TCR, TCR_IFG_802_3, &err, usberr); 260 261 /* Receive configuration register : disable rx filter */ 262 lp->rcr = RCR_TAIL | RCR_AER | RCR_AR; 263 OUTW(dp, RCR, lp->rcr, &err, usberr); 264 #ifdef notdef 265 /* Media status register */ 266 err = urf_set_media(dp); 267 CHECK_AND_JUMP(err, usberr); 268 #endif 269 /* Configuration register 0: no need to change */ 270 271 DPRINTF(2, (CE_CONT, "!%s: %s: end (success)", dp->name, __func__)); 272 return (USB_SUCCESS); 273 274 usberr: 275 cmn_err(CE_NOTE, "!%s: %s: usberr detected", dp->name, __func__); 276 return (USB_FAILURE); 277 } 278 279 static int 280 urf_start_chip(struct usbgem_dev *dp) 281 { 282 struct urf_dev *lp = dp->private; 283 284 /* do nothing */ 285 return (USB_SUCCESS); 286 } 287 288 static int 289 urf_stop_chip(struct usbgem_dev *dp) 290 { 291 return (urf_reset_chip(dp)); 292 } 293 294 static int 295 urf_get_stats(struct usbgem_dev *dp) 296 { 297 /* do nothing */ 298 return (USB_SUCCESS); 299 } 300 301 static uint_t 302 urf_mcast_hash(struct usbgem_dev *dp, const uint8_t *addr) 303 { 304 return (usbgem_ether_crc_be(addr)); 305 } 306 307 static int 308 urf_set_rx_filter(struct usbgem_dev *dp) 309 { 310 int i; 311 uint16_t mode; 312 uint8_t mhash[8]; 313 int err; 314 int16_t rcr; 315 struct urf_dev *lp = dp->private; 316 317 DPRINTF(2, (CE_CONT, "!%s: %s: called, rxmode:%x", 318 dp->name, __func__, dp->rxmode)); 319 320 if (lp->rcr & (RCR_AB | RCR_AD | RCR_AAM | RCR_AAP | RCR_AM)) { 321 #ifdef notdef 322 /* disable rx filter before changing it. */ 323 lp->rcr &= ~(RCR_AB | RCR_AD | RCR_AAM | RCR_AAP | RCR_AM); 324 OUTW(dp, RCR, lp->rcr, &err, usberr); 325 #else 326 /* receive all packets while we change rx filter */ 327 OUTW(dp, RCR, lp->rcr | RCR_AAM | RCR_AAP, &err, usberr); 328 #endif 329 } 330 331 mode = RCR_AB /* accept broadcast */ 332 | RCR_AD; /* accept physical match */ 333 bzero(mhash, sizeof (mhash)); 334 335 if (dp->rxmode & RXMODE_PROMISC) { 336 /* promiscious mode implies all multicast and all physical */ 337 mode |= RCR_AAM | RCR_AAP; 338 } else if ((dp->rxmode & RXMODE_ALLMULTI) || dp->mc_count > 64/2) { 339 /* accept all multicast packets */ 340 mode |= RCR_AAM; 341 } else if (dp->mc_count > 0) { 342 /* 343 * make hash table to select interresting 344 * multicast address only. 345 */ 346 mode |= RCR_AM; 347 for (i = 0; i < dp->mc_count; i++) { 348 uint_t h; 349 /* hash table is 64 = 2^6 bit width */ 350 h = dp->mc_list[i].hash >> (32 - 6); 351 mhash[h / 8] |= 1 << (h % 8); 352 } 353 } 354 lp->rcr |= mode; 355 356 /* set mac address */ 357 OUTS(dp, IDR, dp->cur_addr.ether_addr_octet, ETHERADDRL, &err, usberr); 358 359 /* set multicast hash table */ 360 if (mode & RCR_AM) { 361 /* need to set up multicast hash table */ 362 OUTS(dp, MAR, mhash, sizeof (mhash), &err, usberr); 363 } 364 365 OUTW(dp, RCR, lp->rcr, &err, usberr); 366 367 #if DEBUG_LEVEL > 2 368 IN(dp, RCR, &rcr, &err, usberr); 369 cmn_err(CE_CONT, "!%s: %s: rcr:%b returned", 370 dp->name, __func__, rcr, RCR_BITS); 371 #endif 372 return (USB_SUCCESS); 373 374 usberr: 375 cmn_err(CE_NOTE, "!%s: %s: usberr detected", dp->name, __func__); 376 return (USB_FAILURE); 377 } 378 379 static int 380 urf_set_media(struct usbgem_dev *dp) 381 { 382 uint8_t new; 383 uint8_t old; 384 int err; 385 struct urf_dev *lp = dp->private; 386 387 DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 388 389 /* select duplex: do nothing */ 390 391 /* select speed: do nothing */ 392 393 /* flow control */ 394 IN(dp, MSR, &old, &err, usberr); 395 396 397 /* setup flow control */ 398 new = old & ~(MSR_TXFCE | MSR_RXFCE); 399 switch (dp->flow_control) { 400 case FLOW_CONTROL_SYMMETRIC: 401 new |= MSR_TXFCE | MSR_RXFCE; 402 break; 403 404 case FLOW_CONTROL_TX_PAUSE: 405 new |= MSR_TXFCE; 406 break; 407 408 case FLOW_CONTROL_RX_PAUSE: 409 new |= MSR_RXFCE; 410 break; 411 412 case FLOW_CONTROL_NONE: 413 default: 414 break; 415 } 416 417 if (new != old) { 418 OUTB(dp, MSR, new, &err, usberr); 419 } 420 DPRINTF(2, (CE_CONT, "!%s: %s: returned", dp->name, __func__)); 421 return (USB_SUCCESS); 422 423 usberr: 424 cmn_err(CE_NOTE, "!%s: %s: usberr detected", dp->name, __func__); 425 return (USB_FAILURE); 426 } 427 428 /* 429 * send/receive packet check 430 */ 431 static mblk_t * 432 urf_tx_make_packet(struct usbgem_dev *dp, mblk_t *mp) 433 { 434 size_t len; 435 mblk_t *new; 436 mblk_t *tp; 437 uint8_t *bp; 438 uint8_t *last_pos; 439 440 len = msgdsize(mp); 441 442 if (len < ETHERMIN || mp->b_cont != NULL || (len & 0x3f) == 0) { 443 /* 444 * re-allocate mp 445 */ 446 len = max(len, ETHERMIN); 447 448 if ((len & 0x3f) == 0) { 449 /* workaround for buggy USB hba */ 450 len++; 451 } 452 453 if ((new = allocb(len, 0)) == NULL) { 454 return (NULL); 455 } 456 457 /* copy contents of the buffer */ 458 new->b_wptr = new->b_rptr + len; 459 bp = new->b_rptr; 460 for (tp = mp; tp; tp = tp->b_cont) { 461 len = (uintptr_t)tp->b_wptr - (uintptr_t)tp->b_rptr; 462 bcopy(tp->b_rptr, bp, len); 463 bp += len; 464 } 465 466 last_pos = new->b_wptr; 467 while (bp < last_pos) { 468 *bp++ = 0; 469 } 470 471 mp = new; 472 } 473 474 return (mp); 475 } 476 477 static void 478 urf_dump_packet(struct usbgem_dev *dp, uint8_t *bp, int n) 479 { 480 int i; 481 482 for (i = 0; i < n; i += 8, bp += 8) { 483 cmn_err(CE_CONT, "%02x %02x %02x %02x %02x %02x %02x %02x", 484 bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]); 485 } 486 } 487 488 static mblk_t * 489 urf_rx_make_packet(struct usbgem_dev *dp, mblk_t *mp) 490 { 491 uint8_t *p; 492 uint16_t rxhd; 493 uint_t len; 494 495 ASSERT(mp != NULL); 496 len = msgdsize(mp); 497 #ifdef DEBUG_LEVEL 498 DPRINTF(2, (CE_CONT, "!%s: time:%d %s: len:%d cont:%p", 499 dp->name, ddi_get_lbolt(), __func__, len, mp->b_cont)); 500 501 if (urf_debug > 2) { 502 urf_dump_packet(dp, mp->b_rptr, max(6, len)); 503 } 504 #endif 505 if (len < ETHERMIN + ETHERFCSL) { 506 /* Too short */ 507 dp->stats.runt++; 508 dp->stats.errrcv++; 509 return (NULL); 510 } 511 512 /* get Rx header which is placed at tail of the packet. */ 513 p = mp->b_wptr - 4; 514 rxhd = (p[1] << 8) | p[0]; 515 len = rxhd & RXHD_BYTECNT; 516 517 DPRINTF(2, (CE_CONT, "!%s: %s: rsr:%b len:%d", 518 dp->name, __func__, rxhd, RXHD_BITS, len)); 519 520 /* check if error happen */ 521 if ((rxhd & (RXHD_VALID)) == 0) { 522 DPRINTF(-1, (CE_CONT, "!%s: %s: rxhd:%b", 523 dp->name, __func__, rxhd, RXHD_BITS)); 524 if (rxhd & RXHD_RUNT) { 525 dp->stats.runt++; 526 } 527 528 dp->stats.errrcv++; 529 return (NULL); 530 } 531 #ifdef notdef 532 /* check packet size */ 533 if (len > ETHERMAX + ETHERFCSL) { 534 /* too long */ 535 dp->stats.frame_too_long++; 536 dp->stats.errrcv++; 537 return (NULL); 538 } else if (len < ETHERMIN + ETHERFCSL) { 539 dp->stats.runt++; 540 dp->stats.errrcv++; 541 return (NULL); 542 } 543 #endif 544 /* remove tailing crc field */ 545 mp->b_wptr -= ETHERFCSL; 546 return (mp); 547 } 548 549 /* 550 * MII Interfaces 551 */ 552 static uint16_t 553 urf_mii_read(struct usbgem_dev *dp, uint_t index, int *errp) 554 { 555 int reg; 556 uint16_t val; 557 558 DPRINTF(4, (CE_CONT, "!%s: %s: called, ix:%d", 559 dp->name, __func__, index)); 560 561 *errp = USB_SUCCESS; 562 563 switch (index) { 564 case MII_CONTROL: 565 reg = BMCR; 566 break; 567 568 case MII_STATUS: 569 reg = BMSR; 570 break; 571 572 case MII_AN_ADVERT: 573 reg = ANAR; 574 break; 575 576 case MII_AN_LPABLE: 577 reg = ANLP; 578 break; 579 580 case MII_AN_EXPANSION: 581 reg = ANER; 582 break; 583 584 default: 585 return (0); 586 } 587 588 IN(dp, reg, &val, errp, usberr); 589 590 if (index == MII_STATUS) { 591 uint8_t msr; 592 /* 593 * Fix MII status register as it does't have LINKUP and 594 * MFPRMBLSUPR bits. 595 */ 596 IN(dp, MSR, &msr, errp, usberr); 597 598 val |= (MII_STATUS_MFPRMBLSUPR | MII_STATUS_LINKUP); 599 if ((msr & MSR_LINK) == 0) { 600 val &= ~MII_STATUS_LINKUP; 601 } 602 } 603 604 return (val); 605 606 usberr: 607 cmn_err(CE_CONT, 608 "!%s: %s: usberr(%d) detected", dp->name, __func__, *errp); 609 610 return (0); 611 } 612 613 static void 614 urf_mii_write(struct usbgem_dev *dp, uint_t index, uint16_t val, int *errp) 615 { 616 int reg; 617 618 DPRINTF(5, (CE_CONT, "!%s: %s called", dp->name, __func__)); 619 620 *errp = USB_SUCCESS; 621 622 switch (index) { 623 case MII_CONTROL: 624 reg = BMCR; 625 break; 626 627 case MII_STATUS: 628 reg = BMSR; 629 break; 630 631 case MII_AN_ADVERT: 632 reg = ANAR; 633 break; 634 635 case MII_AN_LPABLE: 636 reg = ANLP; 637 break; 638 639 case MII_AN_EXPANSION: 640 reg = ANER; 641 break; 642 643 default: 644 return; 645 } 646 647 OUTW(dp, reg, val, errp, usberr); 648 usberr: 649 ; 650 } 651 652 /* ======================================================== */ 653 /* 654 * OS depend (device driver DKI) routine 655 */ 656 /* ======================================================== */ 657 static void 658 urf_eeprom_dump(struct usbgem_dev *dp, int size) 659 { 660 int i; 661 int err; 662 uint16_t w0, w1, w2, w3; 663 664 cmn_err(CE_CONT, "!%s: eeprom dump:", dp->name); 665 for (i = URF_EEPROM_BASE; i < size + URF_EEPROM_BASE; i += 8) { 666 IN(dp, i + 0, &w0, &err, usberr); 667 IN(dp, i + 2, &w1, &err, usberr); 668 IN(dp, i + 4, &w2, &err, usberr); 669 IN(dp, i + 6, &w3, &err, usberr); 670 cmn_err(CE_CONT, "!0x%02x: 0x%04x 0x%04x 0x%04x 0x%04x", 671 i - URF_EEPROM_BASE, w0, w1, w2, w3); 672 } 673 usberr: 674 ; 675 } 676 677 static int 678 urf_attach_chip(struct usbgem_dev *dp) 679 { 680 int i; 681 uint8_t old; 682 uint_t new; 683 uint8_t reg; 684 int err; 685 struct urf_dev *lp = dp->private; 686 687 /* 688 * setup flow control bit in eeprom 689 */ 690 IN(dp, URF_EEPROM_BASE + 9, &old, &err, usberr); 691 692 DPRINTF(0, (CE_CONT, "!%s: eeprom offset 9: %02x", dp->name, old)); 693 694 if (dp->ugc.usbgc_flow_control != FLOW_CONTROL_NONE) { 695 /* enable PAUSE bit */ 696 new = old | 0x04; 697 } else { 698 /* clear PAUSE bit */ 699 new = old & ~0x04; 700 } 701 if (new != old) { 702 /* make eeprom writable */ 703 OUTB(dp, CR, lp->cr | CR_WEPROM, &err, usberr); 704 705 /* eerom allows only word access for writing */ 706 IN(dp, URF_EEPROM_BASE + 8, ®, &err, usberr); 707 new = (new << 8) | reg; 708 709 OUTW(dp, URF_EEPROM_BASE + 8, new, &err, usberr); 710 711 /* make eeprom non-writable */ 712 OUTB(dp, CR, lp->cr, &err, usberr); 713 } 714 715 /* 716 * load EEPROM contents into nic 717 */ 718 OUTB(dp, CR, lp->cr | CR_AUTOLOAD, &err, usberr); 719 CHECK_AND_JUMP(err, usberr); 720 721 for (i = 0; i < 100; i++) { 722 IN(dp, CR, ®, &err, usberr); 723 if ((reg & CR_AUTOLOAD) == 0) { 724 goto autoload_done; 725 } 726 } 727 /* timeout */ 728 cmn_err(CE_WARN, "%s: %s: failed to autoload: timeout", 729 dp->name, __func__); 730 goto usberr; 731 732 autoload_done: 733 /* 734 * mac address in EEPROM has loaded to ID registers. 735 */ 736 INS(dp, IDR, dp->dev_addr.ether_addr_octet, ETHERADDRL, &err, usberr); 737 738 /* no need to scan phy */ 739 dp->mii_phy_addr = -1; 740 741 #if DEBUG_LEVEL > 2 742 urf_eeprom_dump(dp, 0x80); 743 #endif 744 745 #ifdef CONFIG_VLAN 746 dp->misc_flag = USBGEM_VLAN; 747 #endif 748 return (USB_SUCCESS); 749 750 usberr: 751 cmn_err(CE_WARN, "%s: urf_attach_chip: usb error detected", dp->name); 752 return (USB_FAILURE); 753 } 754 755 static int 756 urfattach(dev_info_t *dip, ddi_attach_cmd_t cmd) 757 { 758 int i; 759 ddi_iblock_cookie_t c; 760 int ret; 761 int unit; 762 struct chip_info *p; 763 const char *drv_name; 764 struct usbgem_dev *dp; 765 void *base; 766 struct usbgem_conf *ugcp; 767 struct urf_dev *lp; 768 769 unit = ddi_get_instance(dip); 770 drv_name = ddi_driver_name(dip); 771 772 DPRINTF(3, (CE_CONT, "!%s%d: %s: called, cmd:%d", 773 drv_name, __func__, unit, cmd)); 774 775 if (cmd == DDI_ATTACH) { 776 /* 777 * Check if the chip is supported. 778 */ 779 780 /* 781 * Check the chip if it is really realtek rtl8150 782 */ 783 784 /* 785 * construct usbgem configration 786 */ 787 ugcp = kmem_zalloc(sizeof (*ugcp), KM_SLEEP); 788 789 /* name */ 790 (void) sprintf(ugcp->usbgc_name, 791 "%s%d(ppa=%d)", drv_name, unit, urf_ppa); 792 #ifdef USBGEM_CONFIG_GLDv3 793 ugcp->usbgc_ppa = urf_ppa; 794 #else 795 ugcp->usbgc_ppa = unit; 796 #endif 797 ugcp->usbgc_ifnum = 0; 798 ugcp->usbgc_alt = 0; 799 800 ugcp->usbgc_tx_list_max = 16; 801 802 /* the rx status partially replaces FCS */ 803 ugcp->usbgc_rx_header_len = 0; 804 ugcp->usbgc_rx_list_max = 64; 805 806 /* time out parameters */ 807 ugcp->usbgc_tx_timeout = USBGEM_TX_TIMEOUT; 808 ugcp->usbgc_tx_timeout_interval = ONESEC; 809 810 /* flow control */ 811 ugcp->usbgc_flow_control = FLOW_CONTROL_RX_PAUSE; 812 813 /* MII timeout parameters */ 814 ugcp->usbgc_mii_link_watch_interval = ONESEC; 815 ugcp->usbgc_mii_an_watch_interval = ONESEC/5; 816 ugcp->usbgc_mii_reset_timeout = MII_RESET_TIMEOUT; /* 1 sec */ 817 ugcp->usbgc_mii_an_timeout = MII_AN_TIMEOUT; /* 5 sec */ 818 ugcp->usbgc_mii_an_wait = (25*ONESEC)/10; 819 ugcp->usbgc_mii_linkdown_timeout = MII_LINKDOWN_TIMEOUT; 820 821 ugcp->usbgc_mii_an_delay = ONESEC/10; 822 ugcp->usbgc_mii_linkdown_action = MII_ACTION_RSA; 823 ugcp->usbgc_mii_linkdown_timeout_action = MII_ACTION_RESET; 824 ugcp->usbgc_mii_dont_reset = B_FALSE; 825 826 /* I/O methods */ 827 828 /* mac operation */ 829 ugcp->usbgc_attach_chip = &urf_attach_chip; 830 ugcp->usbgc_reset_chip = &urf_reset_chip; 831 ugcp->usbgc_init_chip = &urf_init_chip; 832 ugcp->usbgc_start_chip = &urf_start_chip; 833 ugcp->usbgc_stop_chip = &urf_stop_chip; 834 ugcp->usbgc_multicast_hash = &urf_mcast_hash; 835 836 ugcp->usbgc_set_rx_filter = &urf_set_rx_filter; 837 ugcp->usbgc_set_media = &urf_set_media; 838 ugcp->usbgc_get_stats = &urf_get_stats; 839 #ifdef notdef 840 ugcp->usbgc_interrupt = &urf_interrupt; 841 #else 842 ugcp->usbgc_interrupt = NULL; 843 #endif 844 /* packet operation */ 845 ugcp->usbgc_tx_make_packet = &urf_tx_make_packet; 846 ugcp->usbgc_rx_make_packet = &urf_rx_make_packet; 847 848 /* mii operations */ 849 ugcp->usbgc_mii_probe = &usbgem_mii_probe_default; 850 ugcp->usbgc_mii_init = &usbgem_mii_init_default; 851 ugcp->usbgc_mii_config = &usbgem_mii_config_default; 852 ugcp->usbgc_mii_read = &urf_mii_read; 853 ugcp->usbgc_mii_write = &urf_mii_write; 854 855 /* mtu */ 856 ugcp->usbgc_min_mtu = ETHERMTU; 857 ugcp->usbgc_max_mtu = ETHERMTU; 858 ugcp->usbgc_default_mtu = ETHERMTU; 859 860 lp = kmem_zalloc(sizeof (struct urf_dev), KM_SLEEP); 861 lp->chip = NULL; 862 863 ddi_set_driver_private(dip, NULL); 864 865 dp = usbgem_do_attach(dip, ugcp, lp, sizeof (struct urf_dev)); 866 867 kmem_free(ugcp, sizeof (*ugcp)); 868 869 if (dp != NULL) { 870 urf_ppa++; 871 return (DDI_SUCCESS); 872 } 873 874 err_free_mem: 875 kmem_free(lp, sizeof (struct urf_dev)); 876 err_close_pipe: 877 err: 878 return (DDI_FAILURE); 879 } 880 if (cmd == DDI_RESUME) { 881 return (usbgem_resume(dip)); 882 } 883 return (DDI_FAILURE); 884 } 885 886 static int 887 urfdetach(dev_info_t *dip, ddi_detach_cmd_t cmd) 888 { 889 int ret; 890 891 if (cmd == DDI_DETACH) { 892 ret = usbgem_do_detach(dip); 893 if (ret != DDI_SUCCESS) { 894 return (DDI_FAILURE); 895 } 896 urf_ppa--; 897 return (DDI_SUCCESS); 898 } 899 if (cmd == DDI_SUSPEND) { 900 return (usbgem_suspend(dip)); 901 } 902 return (DDI_FAILURE); 903 } 904 905 /* ======================================================== */ 906 /* 907 * OS depend (loadable streams driver) routine 908 */ 909 /* ======================================================== */ 910 #ifdef USBGEM_CONFIG_GLDv3 911 USBGEM_STREAM_OPS(urf_ops, urfattach, urfdetach); 912 #else 913 static struct module_info urfminfo = { 914 0, /* mi_idnum */ 915 "urf", /* mi_idname */ 916 0, /* mi_minpsz */ 917 ETHERMTU, /* mi_maxpsz */ 918 ETHERMTU*128, /* mi_hiwat */ 919 1, /* mi_lowat */ 920 }; 921 922 static struct qinit urfrinit = { 923 (int (*)()) NULL, /* qi_putp */ 924 usbgem_rsrv, /* qi_srvp */ 925 usbgem_open, /* qi_qopen */ 926 usbgem_close, /* qi_qclose */ 927 (int (*)()) NULL, /* qi_qadmin */ 928 &urfminfo, /* qi_minfo */ 929 NULL /* qi_mstat */ 930 }; 931 932 static struct qinit urfwinit = { 933 usbgem_wput, /* qi_putp */ 934 usbgem_wsrv, /* qi_srvp */ 935 (int (*)()) NULL, /* qi_qopen */ 936 (int (*)()) NULL, /* qi_qclose */ 937 (int (*)()) NULL, /* qi_qadmin */ 938 &urfminfo, /* qi_minfo */ 939 NULL /* qi_mstat */ 940 }; 941 942 static struct streamtab urf_info = { 943 &urfrinit, /* st_rdinit */ 944 &urfwinit, /* st_wrinit */ 945 NULL, /* st_muxrinit */ 946 NULL /* st_muxwrinit */ 947 }; 948 949 static struct cb_ops cb_urf_ops = { 950 nulldev, /* cb_open */ 951 nulldev, /* cb_close */ 952 nodev, /* cb_strategy */ 953 nodev, /* cb_print */ 954 nodev, /* cb_dump */ 955 nodev, /* cb_read */ 956 nodev, /* cb_write */ 957 nodev, /* cb_ioctl */ 958 nodev, /* cb_devmap */ 959 nodev, /* cb_mmap */ 960 nodev, /* cb_segmap */ 961 nochpoll, /* cb_chpoll */ 962 ddi_prop_op, /* cb_prop_op */ 963 &urf_info, /* cb_stream */ 964 D_NEW|D_MP /* cb_flag */ 965 }; 966 967 static struct dev_ops urf_ops = { 968 DEVO_REV, /* devo_rev */ 969 0, /* devo_refcnt */ 970 usbgem_getinfo, /* devo_getinfo */ 971 nulldev, /* devo_identify */ 972 nulldev, /* devo_probe */ 973 urfattach, /* devo_attach */ 974 urfdetach, /* devo_detach */ 975 nodev, /* devo_reset */ 976 &cb_urf_ops, /* devo_cb_ops */ 977 NULL, /* devo_bus_ops */ 978 usbgem_power, /* devo_power */ 979 #if DEVO_REV >= 4 980 usbgem_quiesce, /* devo_quiesce */ 981 #endif 982 983 }; 984 #endif 985 986 static struct modldrv modldrv = { 987 &mod_driverops, /* Type of module. This one is a driver */ 988 ident, 989 &urf_ops, /* driver ops */ 990 }; 991 992 static struct modlinkage modlinkage = { 993 MODREV_1, &modldrv, NULL 994 }; 995 996 /* ======================================================== */ 997 /* 998 * _init : done 999 */ 1000 /* ======================================================== */ 1001 int 1002 _init(void) 1003 { 1004 int status; 1005 1006 DPRINTF(2, (CE_CONT, "!urf: _init: called")); 1007 1008 status = usbgem_mod_init(&urf_ops, "urf"); 1009 if (status != DDI_SUCCESS) { 1010 return (status); 1011 } 1012 status = mod_install(&modlinkage); 1013 if (status != DDI_SUCCESS) { 1014 usbgem_mod_fini(&urf_ops); 1015 } 1016 return (status); 1017 } 1018 1019 /* 1020 * _fini : done 1021 */ 1022 int 1023 _fini(void) 1024 { 1025 int status; 1026 1027 DPRINTF(2, (CE_CONT, "!urf: _fini: called")); 1028 status = mod_remove(&modlinkage); 1029 if (status == DDI_SUCCESS) { 1030 usbgem_mod_fini(&urf_ops); 1031 } 1032 return (status); 1033 } 1034 1035 int 1036 _info(struct modinfo *modinfop) 1037 { 1038 return (mod_info(&modlinkage, modinfop)); 1039 } 1040