1 /* 2 * upf_usbgem.c : ADMtek an986/adm8511/adm8513/adm8515 USB to 3 * Fast Ethernet Driver for Solaris 4 */ 5 6 /* 7 * Copyright (c) 2004-2011 Masayuki Murayama. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the author nor the names of its contributors may be 20 * used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 30 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 34 * DAMAGE. 35 */ 36 37 /* 38 * Changelog: 39 */ 40 41 /* 42 * TODO 43 */ 44 /* ======================================================= */ 45 46 /* 47 * Solaris system header files and macros 48 */ 49 #include <sys/types.h> 50 #include <sys/conf.h> 51 #include <sys/debug.h> 52 #include <sys/kmem.h> 53 #include <sys/modctl.h> 54 #include <sys/errno.h> 55 #include <sys/ddi.h> 56 #include <sys/sunddi.h> 57 #include <sys/byteorder.h> 58 59 /* ethernet stuff */ 60 #include <sys/ethernet.h> 61 62 /* interface card depend stuff */ 63 #include <sys/stropts.h> 64 #include <sys/stream.h> 65 #include <sys/strlog.h> 66 #include <sys/usb/usba.h> 67 #include "usbgem.h" 68 69 /* hardware stuff */ 70 #include "usbgem_mii.h" 71 #include "adm8511reg.h" 72 73 char ident[] = "pegasus usbnic driver v" VERSION; 74 75 /* 76 * Useful macros 77 */ 78 #define CHECK_AND_JUMP(val, label) \ 79 if ((val) != USB_SUCCESS) { goto label; } 80 81 /* 82 * Debugging 83 */ 84 #ifdef DEBUG_LEVEL 85 static int upf_debug = DEBUG_LEVEL; 86 #define DPRINTF(n, args) if (upf_debug > (n)) cmn_err args 87 #else 88 #define DPRINTF(n, args) 89 #endif 90 91 /* 92 * Our configration for ADMtek Pegasus/PegasusII 93 */ 94 /* timeouts */ 95 #define ONESEC (drv_usectohz(1*1000000)) 96 97 /* 98 * Local device definitions 99 */ 100 struct upf_dev { 101 /* 102 * Misc HW information 103 */ 104 uint8_t ec[3]; 105 uint8_t mac_addr[ETHERADDRL]; 106 int chip_type; 107 #define CHIP_AN986 1 /* avoid 0 */ 108 #define CHIP_ADM8511 2 /* including adm8515 */ 109 #define CHIP_ADM8513 3 110 boolean_t phy_init_done; 111 uint8_t last_link_state; 112 113 uint16_t vid; /* vendor id */ 114 uint16_t pid; /* product id */ 115 }; 116 117 /* 118 * private functions 119 */ 120 121 /* mii operations */ 122 static uint16_t upf_mii_read(struct usbgem_dev *, uint_t, int *errp); 123 static void upf_mii_write(struct usbgem_dev *, uint_t, uint16_t, int *errp); 124 125 /* nic operations */ 126 static int upf_attach_chip(struct usbgem_dev *); 127 static int upf_reset_chip(struct usbgem_dev *); 128 static int upf_init_chip(struct usbgem_dev *); 129 static int upf_start_chip(struct usbgem_dev *); 130 static int upf_stop_chip(struct usbgem_dev *); 131 static int upf_set_media(struct usbgem_dev *); 132 static int upf_set_rx_filter(struct usbgem_dev *); 133 static int upf_get_stats(struct usbgem_dev *); 134 135 /* packet operations */ 136 static mblk_t *upf_tx_make_packet(struct usbgem_dev *, mblk_t *); 137 static mblk_t *upf_rx_make_packet(struct usbgem_dev *, mblk_t *); 138 139 /* interrupt handler */ 140 static void upf_interrupt(struct usbgem_dev *, mblk_t *); 141 142 /* =============================================================== */ 143 /* 144 * I/O functions 145 */ 146 /* =============================================================== */ 147 #define UPF_REQ_GET_REGISTER 0xf0 148 #define UPF_REQ_SET_REGISTER 0xf1 149 #define OUTB(dp, p, v, errp, label) \ 150 if ((*(errp) = usbgem_ctrl_out((dp), \ 151 /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \ 152 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 153 /* bRequest */ UPF_REQ_SET_REGISTER, \ 154 /* wValue */ (v), \ 155 /* wIndex */ (p), \ 156 /* wLength */ 1, \ 157 /* buf */ NULL, \ 158 /* size */ 0)) != USB_SUCCESS) goto label; 159 160 #define OUTW(dp, p, v, errp, label) \ 161 if ((*(errp) = usbgem_ctrl_out_val((dp), \ 162 /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \ 163 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 164 /* bRequest */ UPF_REQ_SET_REGISTER, \ 165 /* wValue */ 0, \ 166 /* wIndex */ (p), \ 167 /* wLength */ 2, \ 168 /* value */ (v))) != USB_SUCCESS) goto label 169 170 #define OUTS(dp, p, buf, len, errp, label) \ 171 if ((*(errp) = usbgem_ctrl_out((dp), \ 172 /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \ 173 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 174 /* bRequest */ UPF_REQ_SET_REGISTER, \ 175 /* wValue */ 0, \ 176 /* wIndex */ (p), \ 177 /* wLength */ (len), \ 178 /* buf */ (buf), \ 179 /* size */ (len))) != USB_SUCCESS) goto label 180 181 #define INB(dp, p, vp, errp, label) \ 182 if ((*(errp) = usbgem_ctrl_in_val((dp), \ 183 /* bmRequestType */ USB_DEV_REQ_DEV_TO_HOST \ 184 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 185 /* bRequest */ UPF_REQ_GET_REGISTER, \ 186 /* wValue */ 0, \ 187 /* wIndex */ (p), \ 188 /* wLength */ 1, \ 189 /* valuep */ (vp))) != USB_SUCCESS) goto label 190 191 #define INW(dp, p, vp, errp, label) \ 192 if ((*(errp) = usbgem_ctrl_in_val((dp), \ 193 /* bmRequestType */ USB_DEV_REQ_DEV_TO_HOST \ 194 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 195 /* bRequest */ UPF_REQ_GET_REGISTER, \ 196 /* wValue */ 0, \ 197 /* wIndex */ (p), \ 198 /* wLength */ 2, \ 199 /* valuep */ (vp))) != USB_SUCCESS) goto label 200 201 #define INS(dp, p, buf, len, errp, label) \ 202 if ((*(errp) = usbgem_ctrl_in((dp), \ 203 /* bmRequestType */ USB_DEV_REQ_DEV_TO_HOST \ 204 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 205 /* bRequest */ UPF_REQ_GET_REGISTER, \ 206 /* wValue */ 0, \ 207 /* wIndex */ (p), \ 208 /* wLength */ (len), \ 209 /* buf */ (buf), \ 210 /* size */ (len))) != USB_SUCCESS) goto label 211 212 /* =============================================================== */ 213 /* 214 * Hardware manupilation 215 */ 216 /* =============================================================== */ 217 static int 218 upf_reset_chip(struct usbgem_dev *dp) 219 { 220 int i; 221 uint8_t val; 222 int err; 223 struct upf_dev *lp = dp->private; 224 225 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 226 bzero(lp->mac_addr, sizeof (lp->mac_addr)); 227 228 lp->ec[1] = 0; 229 OUTB(dp, EC1, EC1_RM, &err, usberr); 230 231 for (i = 0; i < 1000; i++) { 232 INB(dp, EC1, &val, &err, usberr); 233 if ((val & EC1_RM) == 0) { 234 lp->ec[1] = val; 235 return (USB_SUCCESS); 236 } 237 drv_usecwait(10); 238 } 239 240 /* time out */ 241 cmn_err(CE_WARN, "!%s: failed to reset: timeout", dp->name); 242 return (USB_FAILURE); 243 244 usberr: 245 cmn_err(CE_NOTE, "!%s: %s: usberr detected", dp->name, __func__); 246 return (USB_FAILURE); 247 } 248 249 /* 250 * Setup an986/adm8511/adm8513/adm8515 251 */ 252 static int 253 upf_init_chip(struct usbgem_dev *dp) 254 { 255 uint64_t zero64 = 0; 256 int err = USB_SUCCESS; 257 struct upf_dev *lp = dp->private; 258 259 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 260 261 /* ethernet control register 0 */ 262 lp->ec[0] |= EC0_RXSA | EC0_RXCS; 263 OUTB(dp, EC0, lp->ec[0], &err, usberr); 264 265 /* ethernet control reg1: will be set later in set_rx_filter() */ 266 267 /* ethernet control register 2: will be set later in set_rx_filter() */ 268 INB(dp, EC2, &lp->ec[2], &err, usberr); 269 lp->ec[2] |= EC2_RXBP | EC2_EP3RC; 270 #ifdef CONFIG_VLAN 271 if (dp->misc_flag & USBGEM_VLAN) { 272 lp->ec[2] |= EC2_MEPL; 273 } 274 #endif 275 OUTB(dp, EC2, lp->ec[2], &err, usberr); 276 277 /* Multicast address hash: clear */ 278 OUTS(dp, MA, &zero64, 8, &err, usberr); 279 280 /* Ethernet ID : will be set later in upf_set_rx_filter() */ 281 282 /* PAUSE timer */ 283 OUTB(dp, PAUSETIMER, 0x1f, &err, usberr); 284 285 /* receive packet number based pause control:set in upf_set_media() */ 286 287 /* occupied receive FIFO based pause control:set in upf_set_media() */ 288 289 /* EP1 control: default */ 290 291 /* Rx FIFO control */ 292 if (lp->chip_type != CHIP_AN986) { 293 /* use 24K internal sram, 16pkts in fifo */ 294 OUTB(dp, RXFC, 0, &err, usberr); 295 } 296 297 /* BIST contror: do nothing */ 298 err = upf_set_media(dp); 299 CHECK_AND_JUMP(err, usberr); 300 301 DPRINTF(2, (CE_CONT, "!%s: %s: end (success)", dp->name, __func__)); 302 return (USB_SUCCESS); 303 304 usberr: 305 cmn_err(CE_NOTE, "!%s: %s: usberr(%d) detected", 306 dp->name, __func__, err); 307 return (err); 308 } 309 310 static int 311 upf_start_chip(struct usbgem_dev *dp) 312 { 313 int err = USB_SUCCESS; 314 struct upf_dev *lp = dp->private; 315 316 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 317 318 /* enable RX and TX */ 319 lp->ec[0] |= EC0_TXE | EC0_RXE; 320 OUTB(dp, EC0, lp->ec[0], &err, usberr); 321 return (USB_SUCCESS); 322 323 usberr: 324 cmn_err(CE_WARN, "!%s: %s: usberr(%d) detected", 325 dp->name, __func__, err); 326 return (err); 327 } 328 329 static int 330 upf_stop_chip(struct usbgem_dev *dp) 331 { 332 int err; 333 struct upf_dev *lp = dp->private; 334 335 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 336 337 /* disable RX and TX */ 338 lp->ec[0] &= ~(EC0_TXE | EC0_RXE); 339 OUTB(dp, EC0, lp->ec[0], &err, usberr); 340 341 return (USB_SUCCESS); 342 343 usberr: 344 cmn_err(CE_WARN, "!%s: %s: usberr(%d) detected", 345 dp->name, __func__, err); 346 return (err); 347 } 348 349 static int 350 upf_get_stats(struct usbgem_dev *dp) 351 { 352 /* do nothing */ 353 return (USB_SUCCESS); 354 } 355 356 static uint_t 357 upf_mcast_hash(struct usbgem_dev *dp, const uint8_t *addr) 358 { 359 /* hash table is 64 = 2^6 bit width */ 360 return (usbgem_ether_crc_le(addr) & 0x3f); 361 } 362 363 static int 364 upf_set_rx_filter(struct usbgem_dev *dp) 365 { 366 int i; 367 int err; 368 #ifdef DEBUG_LEVEL 369 uint8_t reg0; 370 uint8_t reg1; 371 uint8_t reg2; 372 #endif 373 struct upf_dev *lp = dp->private; 374 375 DPRINTF(0, (CE_CONT, "!%s: %s: called, rxmode:%b", 376 dp->name, __func__, dp->rxmode, RXMODE_BITS)); 377 378 /* reset rx mode */ 379 lp->ec[0] &= ~EC0_RXMA; 380 lp->ec[2] &= ~EC2_PROM; 381 382 if (dp->rxmode & RXMODE_PROMISC) { 383 /* promiscious mode implies all multicast and all physical */ 384 lp->ec[0] |= EC0_RXMA; 385 lp->ec[2] |= EC2_PROM; 386 } else if ((dp->rxmode & RXMODE_ALLMULTI) || dp->mc_count > 0) { 387 /* XXX - multicast hash table didin't work */ 388 /* accept all multicast packets */ 389 lp->ec[0] |= EC0_RXMA; 390 } 391 392 if (bcmp(dp->cur_addr.ether_addr_octet, 393 lp->mac_addr, ETHERADDRL) != 0) { 394 395 /* need to update mac address */ 396 bcopy(dp->cur_addr.ether_addr_octet, 397 lp->mac_addr, ETHERADDRL); 398 OUTS(dp, EID, 399 lp->mac_addr, ETHERADDRL, &err, usberr); 400 } 401 402 /* update rx mode */ 403 OUTS(dp, EC0, lp->ec, 3, &err, usberr); 404 405 #if DEBUG_LEVEL > 0 406 INB(dp, EC0, ®0, &err, usberr); 407 INB(dp, EC1, ®1, &err, usberr); 408 INB(dp, EC2, ®2, &err, usberr); 409 410 cmn_err(CE_CONT, "!%s: %s: returned, ec:%b %b %b", 411 dp->name, __func__, 412 reg0, EC0_BITS, reg1, EC1_BITS, reg2, EC2_BITS); 413 #endif 414 return (USB_SUCCESS); 415 416 usberr: 417 cmn_err(CE_NOTE, "!%s: %s: usberr detected", dp->name, __func__); 418 return (err); 419 } 420 421 static int 422 upf_set_media(struct usbgem_dev *dp) 423 { 424 int err; 425 struct upf_dev *lp = dp->private; 426 427 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 428 429 lp->ec[1] &= ~(EC1_FD | EC1_100M); 430 431 /* select duplex */ 432 if (dp->full_duplex) { 433 lp->ec[1] |= EC1_FD; 434 } 435 436 /* select speed */ 437 if (dp->speed == USBGEM_SPD_100) { 438 lp->ec[1] |= EC1_100M; 439 } 440 441 /* rx flow control */ 442 switch (dp->flow_control) { 443 case FLOW_CONTROL_SYMMETRIC: 444 case FLOW_CONTROL_RX_PAUSE: 445 lp->ec[0] |= EC0_RXFCE; 446 break; 447 448 default: 449 lp->ec[0] &= ~EC0_RXFCE; 450 break; 451 } 452 453 /* tx flow control */ 454 switch (dp->flow_control) { 455 case FLOW_CONTROL_SYMMETRIC: 456 case FLOW_CONTROL_TX_PAUSE: 457 if (lp->chip_type != CHIP_AN986) { 458 /* pegasus II has internal 24k fifo */ 459 OUTB(dp, ORFBFC, 460 (12 << ORFBFC_RXS_SHIFT) | ORFBFC_FCRXS, 461 &err, usberr); 462 463 /* 16 packts can be stored in rx fifo */ 464 OUTB(dp, RPNBFC_PN, 465 (8 << RPNBFC_PN_SHIFT) | RPNBFC_FCP, 466 &err, usberr); 467 } else { 468 /* an986 has external 32k fifo */ 469 OUTB(dp, ORFBFC, 470 (16 << ORFBFC_RXS_SHIFT) | ORFBFC_FCRXS, 471 &err, usberr); 472 473 /* AN986 fails to link up when RPNBFC is enabled */ 474 OUTB(dp, RPNBFC, 0, &err, usberr); 475 } 476 break; 477 478 default: 479 OUTB(dp, ORFBFC, 0, &err, usberr); 480 OUTB(dp, RPNBFC, 0, &err, usberr); 481 break; 482 } 483 484 /* update ether control registers */ 485 OUTS(dp, EC0, lp->ec, 2, &err, usberr); 486 DPRINTF(0, (CE_CONT, "!%s: %s: returned, ec0:%b, ec1:%b", 487 dp->name, __func__, lp->ec[0], EC0_BITS, lp->ec[1], EC1_BITS)); 488 489 return (USB_SUCCESS); 490 491 usberr: 492 cmn_err(CE_WARN, "%s: %s: failed to write ec1", dp->name, __func__); 493 return (err); 494 } 495 496 /* 497 * send/receive packet check 498 */ 499 static mblk_t * 500 upf_tx_make_packet(struct usbgem_dev *dp, mblk_t *mp) 501 { 502 size_t len; 503 mblk_t *new; 504 mblk_t *tp; 505 uint8_t *bp; 506 uint8_t *last_pos; 507 int msglen; 508 509 DPRINTF(3, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 510 511 len = msgdsize(mp); 512 if (len < ETHERMIN) { 513 len = ETHERMIN; 514 } 515 516 /* allocate msg block */ 517 msglen = len + sizeof (uint16_t); 518 519 /* avoid usb controller bug */ 520 if ((msglen & 0x3f) == 0) { 521 /* add a header for additional 0-length usb message */ 522 msglen += sizeof (uint16_t); 523 } 524 525 if ((new = allocb(msglen, 0)) == NULL) { 526 return (NULL); 527 } 528 529 /* copy contents of the buffer */ 530 new->b_wptr = new->b_rptr + msglen; 531 bp = new->b_rptr; 532 533 /* the nic requires a two byte header of the packet size */ 534 bp[0] = (uint8_t)len; 535 bp[1] = (uint8_t)(len >> 8); 536 bp += sizeof (uint16_t); 537 538 /* copy the payload */ 539 for (tp = mp; tp; tp = tp->b_cont) { 540 len = (uintptr_t)tp->b_wptr - (uintptr_t)tp->b_rptr; 541 if (len > 0) { 542 bcopy(tp->b_rptr, bp, len); 543 bp += len; 544 } 545 } 546 547 /* clear ethernet pads and additional usb header if we have */ 548 last_pos = new->b_wptr; 549 while (bp < last_pos) { 550 *bp++ = 0; 551 } 552 553 return (new); 554 } 555 556 static void 557 upf_dump_packet(struct usbgem_dev *dp, uint8_t *bp, int n) 558 { 559 int i; 560 561 for (i = 0; i < n; i += 8, bp += 8) { 562 cmn_err(CE_CONT, "%02x %02x %02x %02x %02x %02x %02x %02x", 563 bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]); 564 } 565 } 566 567 static mblk_t * 568 upf_rx_make_packet(struct usbgem_dev *dp, mblk_t *mp) 569 { 570 uint8_t *p; 571 uint16_t rxhd; 572 uint_t len; 573 uint8_t rsr; 574 struct upf_dev *lp = dp->private; 575 576 ASSERT(mp != NULL); 577 578 #ifdef DEBUG_LEVEL 579 len = msgdsize(mp); 580 DPRINTF(2, (CE_CONT, "!%s: time:%d %s: cont:%p", 581 dp->name, ddi_get_lbolt(), __func__, len, mp->b_cont)); 582 583 if (upf_debug > 3) { 584 upf_dump_packet(dp, mp->b_rptr, max(6, len)); 585 } 586 #endif 587 /* get the length of Rx packet */ 588 p = mp->b_wptr - 4; 589 rsr = p[3]; 590 if (lp->chip_type == CHIP_ADM8513) { 591 /* As Rx packets from ADM8513 have two byte header, remove it */ 592 p = mp->b_rptr; 593 len = ((p[1] << 8) | p[0]) & 0x0fff; 594 mp->b_rptr += 2; 595 } else { 596 len = (((p[1] << 8) | p[0]) & 0x0fff) - ETHERFCSL - 4; 597 } 598 599 DPRINTF(2, (CE_CONT, "!%s: %s: rsr:%b len:%d", 600 dp->name, __func__, rsr, RSR_BITS, len)); 601 602 /* check if error happen */ 603 if (rsr & RSR_ERRORS) { 604 DPRINTF(0, (CE_CONT, "!%s: rsr:%b", dp->name, rsr, RSR_BITS)); 605 if (rsr & (RSR_CRC | RSR_DRIBBLE)) { 606 dp->stats.frame++; 607 } 608 if (rsr & RSR_LONG) { 609 dp->stats.frame_too_long++; 610 } 611 if (rsr & RSR_RUNT) { 612 dp->stats.runt++; 613 } 614 615 dp->stats.errrcv++; 616 return (NULL); 617 } 618 #ifndef CONFIG_VLAN 619 /* check packet size */ 620 if (len > ETHERMAX) { 621 /* too long */ 622 dp->stats.frame_too_long++; 623 dp->stats.errrcv++; 624 return (NULL); 625 } else if (len < ETHERMIN) { 626 dp->stats.runt++; 627 dp->stats.errrcv++; 628 return (NULL); 629 } 630 #endif 631 /* remove tailing crc and rx status fields */ 632 mp->b_wptr = mp->b_rptr + len; 633 ASSERT(mp->b_next == NULL); 634 return (mp); 635 } 636 637 /* 638 * Device depend interrupt handler 639 */ 640 static void 641 upf_interrupt(struct usbgem_dev *dp, mblk_t *mp) 642 { 643 uint8_t *bp; 644 struct upf_dev *lp = dp->private; 645 646 bp = mp->b_rptr; 647 648 DPRINTF(2, (CE_CONT, 649 "!%s: %s: size:%d, %02x %02x %02x %02x %02x %02x %02x %02x", 650 dp->name, __func__, mp->b_wptr - mp->b_rptr, 651 bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7])); 652 653 if ((lp->last_link_state ^ bp[5]) & 1) { 654 DPRINTF(1, (CE_CONT, "!%s:%s link status changed:", 655 dp->name, __func__)); 656 usbgem_mii_update_link(dp); 657 } 658 659 lp->last_link_state = bp[5] & 1; 660 } 661 662 /* 663 * MII Interfaces 664 */ 665 static uint16_t 666 upf_mii_read(struct usbgem_dev *dp, uint_t index, int *errp) 667 { 668 uint8_t phyctrl; 669 uint16_t val; 670 int i; 671 672 DPRINTF(4, (CE_CONT, "!%s: %s: called, ix:%d", 673 dp->name, __func__, index)); 674 ASSERT(index >= 0 && index < 32); 675 676 *errp = USB_SUCCESS; 677 678 /* set PHYADDR */ 679 OUTB(dp, PHYA, dp->mii_phy_addr, errp, usberr); 680 681 /* Initiate MII read transaction */ 682 OUTB(dp, PHYAC, index | PHYAC_RDPHY, errp, usberr); 683 684 for (i = 0; i < 100; i++) { 685 INB(dp, PHYAC, &phyctrl, errp, usberr); 686 if (phyctrl & PHYAC_DO) { 687 /* done */ 688 INW(dp, PHYD, &val, errp, usberr); 689 DPRINTF(4, (CE_CONT, "!%s: %s: return %04x", 690 dp->name, __func__, val)); 691 return (val); 692 } 693 drv_usecwait(10); 694 } 695 /* timeout */ 696 cmn_err(CE_WARN, "!%s: %s: timeout detected", dp->name, __func__); 697 *errp = USB_FAILURE; 698 return (0); 699 700 usberr: 701 cmn_err(CE_CONT, 702 "!%s: %s: usberr(%d) detected", dp->name, __func__, *errp); 703 return (0); 704 } 705 706 static void 707 upf_mii_write(struct usbgem_dev *dp, uint_t index, uint16_t val, int *errp) 708 { 709 int i; 710 uint8_t phyctrl; 711 712 DPRINTF(4, (CE_CONT, "!%s: %s called index:%d val:0x%04x", 713 dp->name, __func__, index, val)); 714 ASSERT(index >= 0 && index < 32); 715 716 *errp = USB_SUCCESS; 717 718 OUTW(dp, PHYD, val, errp, usberr); 719 OUTB(dp, PHYA, dp->mii_phy_addr, errp, usberr); 720 OUTB(dp, PHYAC, index | PHYAC_WRPHY, errp, usberr); 721 722 for (i = 0; i < 100; i++) { 723 INB(dp, PHYAC, &phyctrl, errp, usberr); 724 if (phyctrl & PHYAC_DO) { 725 /* done */ 726 return; 727 } 728 drv_usecwait(10); 729 } 730 731 /* time out */ 732 cmn_err(CE_WARN, "!%s: %s: timeout detected", dp->name, __func__); 733 *errp = USB_FAILURE; 734 return; 735 736 usberr: 737 cmn_err(CE_CONT, 738 "!%s: %s: usberr(%d) detected", dp->name, __func__, *errp); 739 } 740 741 742 static int 743 upf_enable_phy(struct usbgem_dev *dp) 744 { 745 uint8_t val; 746 int err; 747 struct upf_dev *lp = dp->private; 748 749 /* 750 * first, try to enable internal phy 751 */ 752 INB(dp, IPHYC, &val, &err, usberr); 753 val = (val | IPHYC_EPHY) & ~IPHYC_PHYR; 754 OUTB(dp, IPHYC, val, &err, usberr); 755 756 INB(dp, IPHYC, &val, &err, usberr); 757 DPRINTF(0, (CE_CONT, "!%s: %s: IPHYC: %b", 758 dp->name, __func__, val, IPHYC_BITS)); 759 if (val) { 760 /* reset internal phy */ 761 OUTB(dp, IPHYC, val | IPHYC_PHYR, &err, usberr); 762 OUTB(dp, IPHYC, val, &err, usberr); 763 delay(drv_usectohz(10000)); 764 765 /* identify the chip generation */ 766 OUTB(dp, 0x83, 0xa5, &err, usberr); 767 INB(dp, 0x83, &val, &err, usberr); 768 if (val == 0xa5) { 769 lp->chip_type = CHIP_ADM8513; 770 } else { 771 /* adm8511 or adm8515 */ 772 lp->chip_type = CHIP_ADM8511; 773 } 774 dp->ugc.usbgc_mii_hw_link_detection = B_TRUE; 775 } else { 776 /* 777 * It should be AN986 which doesn't have an internal PHY. 778 * We need to setup gpio ports in AN986, which are 779 * connected to external PHY control pins. 780 */ 781 lp->chip_type = CHIP_AN986; 782 783 /* reset external phy */ 784 /* output port#0 L, port#1 L */ 785 OUTB(dp, GPIO10, GPIO10_0O | GPIO10_0OE, &err, usberr); 786 787 /* output port#0 H, port#1 L */ 788 OUTB(dp, GPIO10, 789 GPIO10_0O | GPIO10_0OE | GPIO10_1OE, &err, usberr); 790 791 /* hw link detection doesn't work correctly */ 792 dp->ugc.usbgc_mii_hw_link_detection = B_FALSE; 793 } 794 795 return (USB_SUCCESS); 796 797 usberr: 798 cmn_err(CE_NOTE, "!%s: %s: usberr detected", dp->name, __func__); 799 return (USB_FAILURE); 800 } 801 802 static int 803 upf_mii_probe(struct usbgem_dev *dp) 804 { 805 int err; 806 uint16_t val; 807 struct upf_dev *lp = dp->private; 808 809 if (!lp->phy_init_done) { 810 upf_enable_phy(dp); 811 lp->phy_init_done = B_TRUE; 812 } 813 814 return (usbgem_mii_probe_default(dp)); 815 } 816 817 static int 818 upf_mii_init(struct usbgem_dev *dp) 819 { 820 uint16_t val; 821 int err = USB_SUCCESS; 822 struct upf_dev *lp = dp->private; 823 824 if (!lp->phy_init_done) { 825 upf_enable_phy(dp); 826 } 827 lp->phy_init_done = B_FALSE; 828 829 if (lp->chip_type == CHIP_AN986 && 830 (lp->vid == 0x0db7 /* elecom */ || 831 lp->vid == 0x066b /* linksys */ || 832 lp->vid == 0x077b /* linksys */ || 833 lp->vid == 0x2001 /* dlink */)) { 834 /* special treatment for Linksys products */ 835 val = upf_mii_read(dp, 0x1b, &err) | 0x4; 836 upf_mii_write(dp, 0x1b, val, &err); 837 } 838 return (err); 839 } 840 841 /* ======================================================== */ 842 /* 843 * OS depend (device driver DKI) routine 844 */ 845 /* ======================================================== */ 846 static uint16_t 847 upf_read_eeprom(struct usbgem_dev *dp, int index, int *errp) 848 { 849 int i; 850 uint8_t eectrl; 851 uint16_t data; 852 853 *errp = USB_SUCCESS; 854 855 OUTB(dp, EECTRL, 0, errp, usberr); 856 857 OUTB(dp, EEOFFSET, index, errp, usberr); 858 OUTB(dp, EECTRL, EECTRL_RD, errp, usberr); 859 860 for (i = 0; i < 100; i++) { 861 INB(dp, EECTRL, &eectrl, errp, usberr); 862 if (eectrl & EECTRL_DONE) { 863 INW(dp, EEDATA, &data, errp, usberr); 864 return (data); 865 } 866 drv_usecwait(10); 867 } 868 869 /* time out */ 870 *errp = USB_FAILURE; 871 return (0); 872 873 usberr: 874 cmn_err(CE_CONT, 875 "!%s: %s: usberr(%d) detected", dp->name, __func__, *errp); 876 return (0); 877 } 878 879 static void 880 upf_eeprom_dump(struct usbgem_dev *dp, int size) 881 { 882 int i; 883 int err; 884 885 cmn_err(CE_CONT, "!%s: %s dump:", dp->name, __func__); 886 887 for (i = 0; i < size; i += 4) { 888 cmn_err(CE_CONT, "!0x%02x: 0x%04x 0x%04x 0x%04x 0x%04x", 889 i*2, 890 upf_read_eeprom(dp, i + 0, &err), 891 upf_read_eeprom(dp, i + 1, &err), 892 upf_read_eeprom(dp, i + 2, &err), 893 upf_read_eeprom(dp, i + 3, &err)); 894 } 895 } 896 897 static int 898 upf_attach_chip(struct usbgem_dev *dp) 899 { 900 int i; 901 int err; 902 uint16_t val; 903 uint8_t *mac; 904 struct upf_dev *lp = dp->private; 905 906 /* 907 * Read mac address from EEPROM 908 */ 909 mac = dp->dev_addr.ether_addr_octet; 910 for (i = 0; i < 3; i++) { 911 val = upf_read_eeprom(dp, i, &err); 912 if (err != USB_SUCCESS) { 913 goto usberr; 914 } 915 mac[i*2+0] = (uint8_t)val; 916 mac[i*2+1] = (uint8_t)(val >> 8); 917 } 918 919 DPRINTF(0, (CE_CONT, 920 "%s: %s: mac: %02x:%02x:%02x:%02x:%02x:%02x", 921 dp->name, __func__, 922 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); 923 924 dp->misc_flag = 0; 925 #ifdef CONFIG_VLAN 926 dp->misc_flag |= USBGEM_VLAN; 927 #endif 928 #if DEBUG_LEVEL > 3 929 upf_eeprom_dump(dp, 0x80); 930 #endif 931 return (USB_SUCCESS); 932 933 usberr: 934 cmn_err(CE_WARN, "!%s: %s: usb error detected", dp->name, __func__); 935 return (USB_FAILURE); 936 } 937 938 static int 939 upfattach(dev_info_t *dip, ddi_attach_cmd_t cmd) 940 { 941 int i; 942 ddi_iblock_cookie_t c; 943 int ret; 944 int unit; 945 uint32_t tcr; 946 int len; 947 const char *drv_name; 948 struct usbgem_dev *dp; 949 void *base; 950 struct usbgem_conf *ugcp; 951 struct upf_dev *lp; 952 953 unit = ddi_get_instance(dip); 954 drv_name = ddi_driver_name(dip); 955 956 DPRINTF(3, (CE_CONT, "!%s%d: %s: called, cmd:%d", 957 drv_name, unit, __func__, cmd)); 958 959 if (cmd == DDI_ATTACH) { 960 /* 961 * construct usbgem configration 962 */ 963 ugcp = kmem_zalloc(sizeof (*ugcp), KM_SLEEP); 964 965 /* name */ 966 (void) sprintf(ugcp->usbgc_name, "%s%d", drv_name, unit); 967 ugcp->usbgc_ppa = unit; 968 969 ugcp->usbgc_ifnum = 0; 970 ugcp->usbgc_alt = 0; 971 972 ugcp->usbgc_tx_list_max = 16; 973 974 ugcp->usbgc_rx_header_len = 4; 975 ugcp->usbgc_rx_list_max = 64; 976 977 /* time out parameters */ 978 ugcp->usbgc_tx_timeout = USBGEM_TX_TIMEOUT; 979 ugcp->usbgc_tx_timeout_interval = USBGEM_TX_TIMEOUT_INTERVAL; 980 981 /* flow control */ 982 ugcp->usbgc_flow_control = FLOW_CONTROL_NONE; 983 ugcp->usbgc_flow_control = FLOW_CONTROL_RX_PAUSE; 984 985 /* MII timeout parameters */ 986 ugcp->usbgc_mii_link_watch_interval = ONESEC; 987 ugcp->usbgc_mii_an_watch_interval = ONESEC/5; 988 ugcp->usbgc_mii_reset_timeout = MII_RESET_TIMEOUT; /* 1 sec */ 989 ugcp->usbgc_mii_an_timeout = MII_AN_TIMEOUT; /* 5 sec */ 990 ugcp->usbgc_mii_an_wait = MII_AN_TIMEOUT/2; 991 ugcp->usbgc_mii_linkdown_timeout = MII_LINKDOWN_TIMEOUT; 992 ugcp->usbgc_mii_an_delay = ONESEC/10; 993 994 ugcp->usbgc_mii_linkdown_action = MII_ACTION_RESET; 995 ugcp->usbgc_mii_linkdown_timeout_action = MII_ACTION_RESET; 996 ugcp->usbgc_mii_dont_reset = B_FALSE; 997 998 /* I/O methods */ 999 1000 /* mac operation */ 1001 ugcp->usbgc_attach_chip = &upf_attach_chip; 1002 ugcp->usbgc_reset_chip = &upf_reset_chip; 1003 ugcp->usbgc_init_chip = &upf_init_chip; 1004 ugcp->usbgc_start_chip = &upf_start_chip; 1005 ugcp->usbgc_stop_chip = &upf_stop_chip; 1006 ugcp->usbgc_multicast_hash = &upf_mcast_hash; 1007 1008 ugcp->usbgc_set_rx_filter = &upf_set_rx_filter; 1009 ugcp->usbgc_set_media = &upf_set_media; 1010 ugcp->usbgc_get_stats = &upf_get_stats; 1011 ugcp->usbgc_interrupt = &upf_interrupt; 1012 1013 /* packet operation */ 1014 ugcp->usbgc_tx_make_packet = &upf_tx_make_packet; 1015 ugcp->usbgc_rx_make_packet = &upf_rx_make_packet; 1016 1017 /* mii operations */ 1018 ugcp->usbgc_mii_probe = &upf_mii_probe; 1019 ugcp->usbgc_mii_init = &upf_mii_init; 1020 ugcp->usbgc_mii_config = &usbgem_mii_config_default; 1021 ugcp->usbgc_mii_read = &upf_mii_read; 1022 ugcp->usbgc_mii_write = &upf_mii_write; 1023 1024 /* mtu */ 1025 ugcp->usbgc_min_mtu = ETHERMTU; 1026 ugcp->usbgc_max_mtu = ETHERMTU; 1027 ugcp->usbgc_default_mtu = ETHERMTU; 1028 1029 lp = kmem_zalloc(sizeof (struct upf_dev), KM_SLEEP); 1030 1031 lp->vid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1032 DDI_PROP_DONTPASS, "usb-vendor-id", -1); 1033 lp->pid = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1034 DDI_PROP_DONTPASS, "usb-product-id", -1); 1035 1036 dp = usbgem_do_attach(dip, ugcp, lp, sizeof (struct upf_dev)); 1037 1038 kmem_free(ugcp, sizeof (*ugcp)); 1039 1040 if (dp != NULL) { 1041 return (DDI_SUCCESS); 1042 } 1043 1044 err_free_mem: 1045 kmem_free(lp, sizeof (struct upf_dev)); 1046 err_close_pipe: 1047 err: 1048 return (DDI_FAILURE); 1049 } 1050 if (cmd == DDI_RESUME) { 1051 dp = USBGEM_GET_DEV(dip); 1052 lp = dp->private; 1053 lp->phy_init_done = B_FALSE; 1054 1055 return (usbgem_resume(dip)); 1056 } 1057 return (DDI_FAILURE); 1058 } 1059 1060 static int 1061 upfdetach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1062 { 1063 int ret; 1064 1065 if (cmd == DDI_DETACH) { 1066 ret = usbgem_do_detach(dip); 1067 if (ret != DDI_SUCCESS) { 1068 return (DDI_FAILURE); 1069 } 1070 return (DDI_SUCCESS); 1071 } 1072 if (cmd == DDI_SUSPEND) { 1073 return (usbgem_suspend(dip)); 1074 } 1075 return (DDI_FAILURE); 1076 } 1077 1078 /* ======================================================== */ 1079 /* 1080 * OS depend (loadable streams driver) routine 1081 */ 1082 /* ======================================================== */ 1083 #ifdef USBGEM_CONFIG_GLDv3 1084 USBGEM_STREAM_OPS(upf_ops, upfattach, upfdetach); 1085 #else 1086 static struct module_info upfminfo = { 1087 0, /* mi_idnum */ 1088 "upf", /* mi_idname */ 1089 0, /* mi_minpsz */ 1090 ETHERMTU, /* mi_maxpsz */ 1091 32*1024, /* mi_hiwat */ 1092 1, /* mi_lowat */ 1093 }; 1094 1095 static struct qinit upfrinit = { 1096 (int (*)()) NULL, /* qi_putp */ 1097 usbgem_rsrv, /* qi_srvp */ 1098 usbgem_open, /* qi_qopen */ 1099 usbgem_close, /* qi_qclose */ 1100 (int (*)()) NULL, /* qi_qadmin */ 1101 &upfminfo, /* qi_minfo */ 1102 NULL /* qi_mstat */ 1103 }; 1104 1105 static struct qinit upfwinit = { 1106 usbgem_wput, /* qi_putp */ 1107 usbgem_wsrv, /* qi_srvp */ 1108 (int (*)()) NULL, /* qi_qopen */ 1109 (int (*)()) NULL, /* qi_qclose */ 1110 (int (*)()) NULL, /* qi_qadmin */ 1111 &upfminfo, /* qi_minfo */ 1112 NULL /* qi_mstat */ 1113 }; 1114 1115 static struct streamtab upf_info = { 1116 &upfrinit, /* st_rdinit */ 1117 &upfwinit, /* st_wrinit */ 1118 NULL, /* st_muxrinit */ 1119 NULL /* st_muxwrinit */ 1120 }; 1121 1122 static struct cb_ops cb_upf_ops = { 1123 nulldev, /* cb_open */ 1124 nulldev, /* cb_close */ 1125 nodev, /* cb_strategy */ 1126 nodev, /* cb_print */ 1127 nodev, /* cb_dump */ 1128 nodev, /* cb_read */ 1129 nodev, /* cb_write */ 1130 nodev, /* cb_ioctl */ 1131 nodev, /* cb_devmap */ 1132 nodev, /* cb_mmap */ 1133 nodev, /* cb_segmap */ 1134 nochpoll, /* cb_chpoll */ 1135 ddi_prop_op, /* cb_prop_op */ 1136 &upf_info, /* cb_stream */ 1137 D_MP /* cb_flag */ 1138 }; 1139 1140 static struct dev_ops upf_ops = { 1141 DEVO_REV, /* devo_rev */ 1142 0, /* devo_refcnt */ 1143 usbgem_getinfo, /* devo_getinfo */ 1144 nulldev, /* devo_identify */ 1145 nulldev, /* devo_probe */ 1146 upfattach, /* devo_attach */ 1147 upfdetach, /* devo_detach */ 1148 nodev, /* devo_reset */ 1149 &cb_upf_ops, /* devo_cb_ops */ 1150 NULL, /* devo_bus_ops */ 1151 usbgem_power, /* devo_power */ 1152 #if DEVO_REV >= 4 1153 usbgem_quiesce, /* devo_quiesce */ 1154 #endif 1155 1156 }; 1157 #endif 1158 static struct modldrv modldrv = { 1159 &mod_driverops, /* Type of module. This one is a driver */ 1160 ident, 1161 &upf_ops, /* driver ops */ 1162 }; 1163 1164 static struct modlinkage modlinkage = { 1165 MODREV_1, &modldrv, NULL 1166 }; 1167 1168 /* ======================================================== */ 1169 /* 1170 * _init : done 1171 */ 1172 /* ======================================================== */ 1173 int 1174 _init(void) 1175 { 1176 int status; 1177 1178 DPRINTF(2, (CE_CONT, "!upf: _init: called")); 1179 1180 status = usbgem_mod_init(&upf_ops, "upf"); 1181 if (status != DDI_SUCCESS) { 1182 return (status); 1183 } 1184 status = mod_install(&modlinkage); 1185 if (status != DDI_SUCCESS) { 1186 usbgem_mod_fini(&upf_ops); 1187 } 1188 return (status); 1189 } 1190 1191 /* 1192 * _fini : done 1193 */ 1194 int 1195 _fini(void) 1196 { 1197 int status; 1198 1199 DPRINTF(2, (CE_CONT, "!upf: _fini: called")); 1200 status = mod_remove(&modlinkage); 1201 if (status == DDI_SUCCESS) { 1202 usbgem_mod_fini(&upf_ops); 1203 } 1204 return (status); 1205 } 1206 1207 int 1208 _info(struct modinfo *modinfop) 1209 { 1210 return (mod_info(&modlinkage, modinfop)); 1211 } 1212