1 /* 2 * udmfE_usbgem.c : Davicom DM9601E USB to Fast Ethernet Driver for Solaris 3 * 4 * Copyright (c) 2009-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/strsun.h> 66 #include <sys/usb/usba.h> 67 #include "usbgem.h" 68 69 /* hardware stuff */ 70 #include "usbgem_mii.h" 71 #include "dm9601reg.h" 72 73 char ident[] = "dm9601 usbnic driver v" VERSION; 74 75 /* 76 * Useful macros 77 */ 78 #define CHECK_AND_JUMP(err, label) if (err != USB_SUCCESS) goto label 79 #define LE16P(p) ((((uint8_t *)(p))[1] << 8) | ((uint8_t *)(p))[0]) 80 81 /* 82 * Debugging 83 */ 84 #ifdef DEBUG_LEVEL 85 static int udmf_debug = DEBUG_LEVEL; 86 #define DPRINTF(n, args) if (udmf_debug > (n)) cmn_err args 87 #else 88 #define DPRINTF(n, args) 89 #endif 90 91 /* 92 * Our configration for dm9601 93 */ 94 /* timeouts */ 95 #define ONESEC (drv_usectohz(1*1000000)) 96 97 /* 98 * Local device definitions 99 */ 100 struct udmf_dev { 101 /* 102 * Misc HW information 103 */ 104 uint8_t rcr; 105 uint8_t last_nsr; 106 uint8_t mac_addr[ETHERADDRL]; 107 }; 108 109 /* 110 * private functions 111 */ 112 113 /* mii operations */ 114 static uint16_t udmf_mii_read(struct usbgem_dev *, uint_t, int *errp); 115 static void udmf_mii_write(struct usbgem_dev *, uint_t, uint16_t, int *errp); 116 117 /* nic operations */ 118 static int udmf_reset_chip(struct usbgem_dev *); 119 static int udmf_init_chip(struct usbgem_dev *); 120 static int udmf_start_chip(struct usbgem_dev *); 121 static int udmf_stop_chip(struct usbgem_dev *); 122 static int udmf_set_media(struct usbgem_dev *); 123 static int udmf_set_rx_filter(struct usbgem_dev *); 124 static int udmf_get_stats(struct usbgem_dev *); 125 static void udmf_interrupt(struct usbgem_dev *, mblk_t *); 126 127 /* packet operations */ 128 static mblk_t *udmf_tx_make_packet(struct usbgem_dev *, mblk_t *); 129 static mblk_t *udmf_rx_make_packet(struct usbgem_dev *, mblk_t *); 130 131 /* =============================================================== */ 132 /* 133 * I/O functions 134 */ 135 /* =============================================================== */ 136 #define OUT(dp, ix, len, buf, errp, label) \ 137 if ((*(errp) = usbgem_ctrl_out((dp), \ 138 /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \ 139 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 140 /* bRequest */ 1, \ 141 /* wValue */ 0, \ 142 /* wIndex */ (ix), \ 143 /* wLength */ (len), \ 144 /* value */ (buf), \ 145 /* size */ (len))) != USB_SUCCESS) goto label 146 147 #define OUTB(dp, ix, val, errp, label) \ 148 if ((*(errp) = usbgem_ctrl_out((dp), \ 149 /* bmRequestType */ USB_DEV_REQ_HOST_TO_DEV \ 150 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 151 /* bRequest */ 3, \ 152 /* wValue */ (val), \ 153 /* wIndex */ (ix), \ 154 /* wLength */ 0, \ 155 /* value */ NULL, \ 156 /* size */ 0)) != USB_SUCCESS) goto label 157 158 #define IN(dp, ix, len, buf, errp, label) \ 159 if ((*(errp) = usbgem_ctrl_in((dp), \ 160 /* bmRequestType */ USB_DEV_REQ_DEV_TO_HOST \ 161 | USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_RCPT_DEV, \ 162 /* bRequest */ 0, \ 163 /* wValue */ 0, \ 164 /* wIndex */ (ix), \ 165 /* wLength */ (len), \ 166 /* valuep */ (buf), \ 167 /* size */ (len))) != USB_SUCCESS) goto label 168 169 /* =============================================================== */ 170 /* 171 * Hardware manupilation 172 */ 173 /* =============================================================== */ 174 static void 175 udmf_enable_phy(struct usbgem_dev *dp) 176 { 177 int err = USB_SUCCESS; 178 179 /* de-assert reset signal to phy */ 180 OUTB(dp, GPCR, GPCR_OUT(0), &err, usberr); 181 OUTB(dp, GPR, 0, &err, usberr); 182 usberr: 183 ; 184 } 185 186 static int 187 udmf_reset_chip(struct usbgem_dev *dp) 188 { 189 int err = USB_SUCCESS; 190 191 DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 192 193 OUTB(dp, NCR, NCR_LBK_NORMAL | NCR_RST, &err, usberr); 194 drv_usecwait(100); 195 usberr: 196 return (err); 197 } 198 199 /* 200 * Setup dm9601 201 */ 202 static int 203 udmf_init_chip(struct usbgem_dev *dp) 204 { 205 int i; 206 uint32_t val; 207 int err = USB_SUCCESS; 208 uint16_t reg; 209 uint8_t buf[2]; 210 struct udmf_dev *lp = dp->private; 211 212 DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 213 214 OUTB(dp, NCR, NCR_LBK_NORMAL, &err, usberr); 215 216 /* tx control regiser: enable padding and crc generation */ 217 OUTB(dp, TCR, 0, &err, usberr); 218 219 /* rx control register: will be set later by udmf_set_rx_filer() */ 220 lp->rcr = RCR_RUNT; 221 222 /* back pressure threshold: */ 223 OUTB(dp, BPTR, (2 << BPTR_BPHW_SHIFT) | BPTR_JPT_200us, 224 &err, usberr); 225 226 /* flow control threshold: same as default */ 227 OUTB(dp, FCTR, (3 << FCTR_HWOT_SHIFT) | (8 << FCTR_LWOT_SHIFT), 228 &err, usberr); 229 230 /* usb control register */ 231 OUTB(dp, USBC, USBC_EP3ACK | 0x06, &err, usberr); 232 233 /* flow control: will be set later by udmf_set_media() */ 234 235 /* wake up control register: */ 236 OUTB(dp, WCR, 0, &err, usberr); 237 238 usberr: 239 DPRINTF(2, (CE_CONT, "!%s: %s: end err:%d(%s)", 240 dp->name, __func__, 241 err, err == USB_SUCCESS ? "success" : "error")); 242 return (err); 243 } 244 245 static int 246 udmf_start_chip(struct usbgem_dev *dp) 247 { 248 int err = USB_SUCCESS; 249 struct udmf_dev *lp = dp->private; 250 251 /* enable Rx */ 252 lp->rcr |= RCR_RXEN; 253 OUTB(dp, RCR, lp->rcr, &err, usberr); 254 255 usberr: 256 DPRINTF(2, (CE_CONT, "!%s: %s: end err:%d(%s)", 257 dp->name, __func__, 258 err, err == USB_SUCCESS ? "success" : "error")); 259 return (err); 260 } 261 262 static int 263 udmf_stop_chip(struct usbgem_dev *dp) 264 { 265 int err = USB_SUCCESS; 266 struct udmf_dev *lp = dp->private; 267 268 /* disable rx */ 269 lp->rcr &= ~RCR_RXEN; 270 OUTB(dp, RCR, lp->rcr, &err, usberr); 271 272 usberr: 273 DPRINTF(2, (CE_CONT, "!%s: %s: end err:%d(%s)", 274 dp->name, __func__, 275 err, err == USB_SUCCESS ? "success" : "error")); 276 return (err); 277 } 278 279 static int 280 udmf_get_stats(struct usbgem_dev *dp) 281 { 282 /* empty */ 283 return (USB_SUCCESS); 284 } 285 286 static uint_t 287 udmf_mcast_hash(struct usbgem_dev *dp, const uint8_t *addr) 288 { 289 return (usbgem_ether_crc_le(addr) & 0x3f); 290 } 291 292 static int 293 udmf_set_rx_filter(struct usbgem_dev *dp) 294 { 295 int i; 296 uint8_t rcr; 297 uint8_t mode; 298 uint8_t mhash[8]; 299 uint8_t *mac; 300 uint_t h; 301 int err = USB_SUCCESS; 302 struct udmf_dev *lp = dp->private; 303 static uint8_t invalid_mac[ETHERADDRL] = {0, 0, 0, 0, 0, 0}; 304 305 DPRINTF(2, (CE_CONT, "!%s: %s: called, rxmode:%x", 306 dp->name, __func__, dp->rxmode)); 307 308 if (lp->rcr & RCR_RXEN) { 309 /* set promiscuous mode before changing rx filter mode */ 310 OUTB(dp, RCR, lp->rcr | RCR_PRMSC, &err, usberr); 311 } 312 313 lp->rcr &= ~(RCR_ALL | RCR_PRMSC); 314 mode = 0; 315 bzero(mhash, sizeof (mhash)); 316 mac = dp->cur_addr.ether_addr_octet; 317 318 if ((dp->rxmode & RXMODE_ENABLE) == 0) { 319 mac = invalid_mac; 320 } else if (dp->rxmode & RXMODE_PROMISC) { 321 /* promiscious mode implies all multicast and all physical */ 322 mode |= RCR_PRMSC; 323 } else if ((dp->rxmode & RXMODE_ALLMULTI) || dp->mc_count > 32) { 324 /* accept all multicast packets */ 325 mode |= RCR_ALL; 326 } else if (dp->mc_count > 0) { 327 /* 328 * make hash table to select interresting 329 * multicast address only. 330 */ 331 for (i = 0; i < dp->mc_count; i++) { 332 /* hash table is 64 = 2^6 bit width */ 333 h = dp->mc_list[i].hash; 334 mhash[h / 8] |= 1 << (h % 8); 335 } 336 } 337 338 /* set node address */ 339 if (bcmp(mac, lp->mac_addr, ETHERADDRL) != 0) { 340 OUT(dp, PAR, ETHERADDRL, dp->cur_addr.ether_addr_octet, 341 &err, usberr); 342 bcopy(mac, lp->mac_addr, ETHERADDRL); 343 } 344 345 /* set multicast hash table */ 346 OUT(dp, MAR, sizeof (mhash), &mhash[0], &err, usberr); 347 348 /* update rcr */ 349 lp->rcr |= mode; 350 OUTB(dp, RCR, lp->rcr, &err, usberr); 351 352 #if DEBUG_LEVEL > 1 353 /* verify rcr */ 354 IN(dp, RCR, 1, &rcr, &err, usberr); 355 cmn_err(CE_CONT, "!%s: %s: rcr:%b returned", 356 dp->name, __func__, rcr, RCR_BITS); 357 #endif 358 usberr: 359 DPRINTF(2, (CE_CONT, "!%s: %s: end err:%d(%s)", 360 dp->name, __func__, 361 err, err == USB_SUCCESS ? "success" : "error")); 362 return (err); 363 } 364 365 static int 366 udmf_set_media(struct usbgem_dev *dp) 367 { 368 int err = USB_SUCCESS; 369 uint8_t fcr; 370 struct udmf_dev *lp = dp->private; 371 372 DPRINTF(0, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 373 374 /* setup flow control */ 375 fcr = 0; 376 if (dp->full_duplex) { 377 /* select flow control */ 378 switch (dp->flow_control) { 379 case FLOW_CONTROL_RX_PAUSE: 380 fcr |= FCR_FLCE; 381 break; 382 383 case FLOW_CONTROL_TX_PAUSE: 384 fcr |= FCR_TXPEN; 385 break; 386 387 case FLOW_CONTROL_SYMMETRIC: 388 fcr |= FCR_FLCE | FCR_TXPEN; 389 break; 390 } 391 } 392 393 /* update flow control register */ 394 OUTB(dp, FCR, fcr, &err, usberr); 395 396 usberr: 397 DPRINTF(2, (CE_CONT, "!%s: %s: end err:%d(%s)", 398 dp->name, __func__, 399 err, err == USB_SUCCESS ? "success" : "error")); 400 return (err); 401 } 402 403 /* 404 * send/receive packet check 405 */ 406 static mblk_t * 407 udmf_tx_make_packet(struct usbgem_dev *dp, mblk_t *mp) 408 { 409 int n; 410 size_t pkt_size; 411 mblk_t *new; 412 mblk_t *tp; 413 uint8_t *bp; 414 uint8_t *last_pos; 415 uint_t align_mask; 416 417 pkt_size = msgdsize(mp); 418 align_mask = 63; 419 420 /* 421 * re-allocate the mp 422 */ 423 424 /* minimum ethernet packet size of ETHERMIN */ 425 pkt_size = max(pkt_size, ETHERMIN); 426 427 #if 0 /* CONFIG_ADD_TX_DELIMITOR_ALWAYS */ 428 pkt_size += TX_HEADER_SIZE; 429 #endif 430 if (((pkt_size + TX_HEADER_SIZE) & align_mask) == 0) { 431 /* padding is required in usb communication */ 432 pkt_size += TX_HEADER_SIZE; 433 } 434 435 if ((new = allocb(TX_HEADER_SIZE + pkt_size, 0)) == NULL) { 436 return (NULL); 437 } 438 new->b_wptr = new->b_rptr + TX_HEADER_SIZE + pkt_size; 439 440 /* add a header */ 441 bp = new->b_rptr; 442 bp[0] = (uint8_t)pkt_size; 443 bp[1] = (uint8_t)(pkt_size >> 8); 444 bp += TX_HEADER_SIZE; 445 446 /* copy contents of the buffer */ 447 for (tp = mp; tp; tp = tp->b_cont) { 448 n = MBLKL(tp); 449 bcopy(tp->b_rptr, bp, n); 450 bp += n; 451 } 452 453 /* clear the rest including the next zero length header */ 454 last_pos = new->b_wptr; 455 while (bp < last_pos) { 456 *bp++ = 0; 457 } 458 459 return (new); 460 } 461 462 static void 463 udmf_dump_packet(struct usbgem_dev *dp, uint8_t *bp, int n) 464 { 465 int i; 466 467 for (i = 0; i < n; i += 8, bp += 8) { 468 cmn_err(CE_CONT, "%02x %02x %02x %02x %02x %02x %02x %02x", 469 bp[0], bp[1], bp[2], bp[3], bp[4], bp[5], bp[6], bp[7]); 470 } 471 } 472 473 static mblk_t * 474 udmf_rx_make_packet(struct usbgem_dev *dp, mblk_t *mp) 475 { 476 size_t len; 477 uint8_t rx_stat; 478 479 len = MBLKL(mp); 480 481 if (len <= RX_HEADER_SIZE) { 482 /* 483 * the usb bulk-in frame doesn't include a valid 484 * ethernet packet. 485 */ 486 return (NULL); 487 } 488 489 /* remove rx header */ 490 rx_stat = mp->b_rptr[0]; 491 if (rx_stat & (RSR_RF | RSR_LCS | RSR_RWTO | 492 RSR_PLE | RSR_AE | RSR_CE | RSR_FOE)) { 493 if (rx_stat & RSR_RF) { 494 dp->stats.runt++; 495 } 496 if (rx_stat & RSR_LCS) { 497 /* late collision */ 498 dp->stats.rcv_internal_err++; 499 } 500 if (rx_stat & RSR_RWTO) { 501 /* rx timeout */ 502 dp->stats.rcv_internal_err++; 503 } 504 if (rx_stat & RSR_PLE) { 505 /* physical layer error */ 506 dp->stats.rcv_internal_err++; 507 } 508 if (rx_stat & RSR_AE) { 509 /* alignment error */ 510 dp->stats.frame++; 511 } 512 if (rx_stat & RSR_CE) { 513 /* crc error */ 514 dp->stats.crc++; 515 } 516 if (rx_stat & RSR_FOE) { 517 /* fifo overflow error */ 518 dp->stats.overflow++; 519 } 520 dp->stats.errrcv++; 521 } 522 len = LE16P(&mp->b_rptr[1]); 523 if (len >= ETHERFCSL) { 524 len -= ETHERFCSL; 525 } 526 mp->b_rptr += RX_HEADER_SIZE; 527 mp->b_wptr = mp->b_rptr + len; 528 529 return (mp); 530 } 531 532 /* 533 * MII Interfaces 534 */ 535 static uint16_t 536 udmf_ep_read(struct usbgem_dev *dp, uint_t which, uint_t addr, int *errp) 537 { 538 int i; 539 uint8_t epcr; 540 uint16_t val; 541 542 DPRINTF(4, (CE_CONT, "!%s: %s: called, ix:%d", 543 dp->name, __func__, addr)); 544 545 OUTB(dp, EPAR, addr, errp, usberr); 546 OUTB(dp, EPCR, which | EPCR_ERPRR, errp, usberr); 547 548 for (i = 0; i < 100; i++) { 549 IN(dp, EPCR, sizeof (epcr), &epcr, errp, usberr); 550 if ((epcr & EPCR_ERRE) == 0) { 551 /* done */ 552 IN(dp, EPDR, sizeof (val), &val, errp, usberr); 553 val = LE_16(val); 554 goto done; 555 } 556 drv_usecwait(10); 557 } 558 /* timeout */ 559 cmn_err(CE_WARN, "!%s: %s: timeout", dp->name, __func__); 560 val = 0; 561 done: 562 OUTB(dp, EPCR, 0, errp, usberr); 563 return (val); 564 565 usberr: 566 DPRINTF(2, (CE_CONT, "!%s: %s: end err:%d(%s)", 567 dp->name, __func__, 568 *errp, *errp == USB_SUCCESS ? "success" : "error")); 569 return (0); 570 } 571 572 static void 573 udmf_ep_write(struct usbgem_dev *dp, uint_t which, uint_t addr, 574 uint16_t val, int *errp) 575 { 576 int i; 577 uint8_t epcr; 578 579 DPRINTF(5, (CE_CONT, "!%s: %s called", dp->name, __func__)); 580 581 val = LE_16(val); 582 OUT(dp, EPDR, sizeof (val), &val, errp, usberr); 583 584 OUTB(dp, EPAR, addr, errp, usberr); 585 586 OUTB(dp, EPCR, which | EPCR_WEP | EPCR_ERPRW, errp, usberr); 587 588 for (i = 0; i < 100; i++) { 589 IN(dp, EPCR, 1, &epcr, errp, usberr); 590 if ((epcr & EPCR_ERRE) == 0) { 591 /* done */ 592 goto done; 593 } 594 drv_usecwait(10); 595 } 596 /* timeout */ 597 cmn_err(CE_WARN, "!%s: %s: timeout", dp->name, __func__); 598 done: 599 OUTB(dp, EPCR, 0, errp, usberr); 600 return; 601 602 usberr: 603 DPRINTF(2, (CE_CONT, "!%s: %s: end err:%d(%s)", 604 dp->name, __func__, 605 *errp, *errp == USB_SUCCESS ? "success" : "error")); 606 } 607 608 static uint16_t 609 udmf_mii_read(struct usbgem_dev *dp, uint_t index, int *errp) 610 { 611 uint16_t val; 612 613 val = udmf_ep_read(dp, EPCR_EPOS, 614 (dp->mii_phy_addr << EPAR_PHYADR_SHIFT) | index, errp); 615 616 return (val); 617 } 618 619 static void 620 udmf_mii_write(struct usbgem_dev *dp, uint_t index, uint16_t val, int *errp) 621 { 622 udmf_ep_write(dp, EPCR_EPOS, 623 (dp->mii_phy_addr << EPAR_PHYADR_SHIFT) | index, val, errp); 624 } 625 626 static void 627 udmf_interrupt(struct usbgem_dev *dp, mblk_t *mp) 628 { 629 struct intr_msg *imp; 630 struct udmf_dev *lp = dp->private; 631 632 imp = (struct intr_msg *)&mp->b_rptr[0]; 633 634 DPRINTF(4, (CE_CONT, 635 "!%s: %s: size:%d, nsr:%b tsr1:%b tsr2:%b" 636 " rsr:%b rocr:%b rxc:%02x txc:%b gpr:%b", 637 dp->name, __func__, mp->b_wptr - mp->b_rptr, 638 imp->im_nsr, NSR_BITS, 639 imp->im_tsr1, TSR_BITS, 640 imp->im_tsr2, TSR_BITS, 641 imp->im_rsr, RSR_BITS, 642 imp->im_rocr, ROCR_BITS, 643 imp->im_rxc, 644 imp->im_txc, TUSR_BITS, 645 imp->im_gpr, GPR_BITS)); 646 647 if ((lp->last_nsr ^ imp->im_nsr) & NSR_LINKST) { 648 usbgem_mii_update_link(dp); 649 } 650 651 lp->last_nsr = imp->im_nsr; 652 } 653 654 /* ======================================================== */ 655 /* 656 * OS depend (device driver DKI) routine 657 */ 658 /* ======================================================== */ 659 static uint16_t 660 udmf_eeprom_read(struct usbgem_dev *dp, uint_t index, int *errp) 661 { 662 uint16_t val; 663 664 val = udmf_ep_read(dp, 0, index, errp); 665 666 return (val); 667 } 668 669 #ifdef DEBUG_LEVEL 670 static void 671 udmf_eeprom_dump(struct usbgem_dev *dp, int size) 672 { 673 int i; 674 int err; 675 uint16_t w0, w1, w2, w3; 676 677 cmn_err(CE_CONT, "!%s: eeprom dump:", dp->name); 678 679 err = USB_SUCCESS; 680 681 for (i = 0; i < size; i += 4) { 682 w0 = udmf_eeprom_read(dp, i + 0, &err); 683 w1 = udmf_eeprom_read(dp, i + 1, &err); 684 w2 = udmf_eeprom_read(dp, i + 2, &err); 685 w3 = udmf_eeprom_read(dp, i + 3, &err); 686 cmn_err(CE_CONT, "!0x%02x: 0x%04x 0x%04x 0x%04x 0x%04x", 687 i, w0, w1, w2, w3); 688 } 689 usberr: 690 ; 691 } 692 #endif 693 694 static int 695 udmf_attach_chip(struct usbgem_dev *dp) 696 { 697 int i; 698 uint_t val; 699 uint8_t *m; 700 int err; 701 struct udmf_dev *lp = dp->private; 702 703 DPRINTF(0, (CE_CONT, "!%s: %s enter", dp->name, __func__)); 704 705 /* 706 * get mac address from EEPROM 707 */ 708 m = dp->dev_addr.ether_addr_octet; 709 for (i = 0; i < ETHERADDRL; i += 2) { 710 val = udmf_eeprom_read(dp, i/2, &err); 711 m[i + 0] = (uint8_t)val; 712 m[i + 1] = (uint8_t)(val >> 8); 713 } 714 715 /* invalidate a private cache for mac addr */ 716 bzero(lp->mac_addr, sizeof (lp->mac_addr)); 717 #ifdef CONFIG_VLAN 718 dp->misc_flag = USBGEM_VLAN; 719 #endif 720 #if DEBUG_LEVEL > 0 721 udmf_eeprom_dump(dp, /* 0x3f + 1 */ 128); 722 #endif 723 { 724 static uint8_t bcst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 725 DPRINTF(0, (CE_CONT, "!%s: %s: hash of bcast:%x", 726 dp->name, __func__, usbgem_ether_crc_be(bcst))); 727 } 728 return (USB_SUCCESS); 729 730 usberr: 731 cmn_err(CE_WARN, "%s: %s: usb error detected (%d)", 732 dp->name, __func__, err); 733 return (USB_FAILURE); 734 } 735 736 static int 737 udmf_mii_probe(struct usbgem_dev *dp) 738 { 739 DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 740 741 udmf_enable_phy(dp); 742 return (usbgem_mii_probe_default(dp)); 743 } 744 745 static int 746 udmf_mii_init(struct usbgem_dev *dp) 747 { 748 DPRINTF(2, (CE_CONT, "!%s: %s: called", dp->name, __func__)); 749 udmf_enable_phy(dp); 750 return (USB_SUCCESS); 751 } 752 753 static int 754 udmfattach(dev_info_t *dip, ddi_attach_cmd_t cmd) 755 { 756 int i; 757 ddi_iblock_cookie_t c; 758 int ret; 759 int revid; 760 int unit; 761 int len; 762 const char *drv_name; 763 struct usbgem_dev *dp; 764 void *base; 765 struct usbgem_conf *ugcp; 766 struct udmf_dev *lp; 767 768 unit = ddi_get_instance(dip); 769 drv_name = ddi_driver_name(dip); 770 771 DPRINTF(3, (CE_CONT, "!%s%d: %s: called, cmd:%d", 772 drv_name, unit, __func__, cmd)); 773 774 if (cmd == DDI_ATTACH) { 775 /* 776 * construct usbgem configration 777 */ 778 ugcp = kmem_zalloc(sizeof (*ugcp), KM_SLEEP); 779 780 /* name */ 781 /* 782 * softmac requires that ppa is the instance number 783 * of the device, otherwise it hangs in seaching the device. 784 */ 785 (void) sprintf(ugcp->usbgc_name, "%s%d", drv_name, unit); 786 ugcp->usbgc_ppa = unit; 787 788 ugcp->usbgc_ifnum = 0; 789 ugcp->usbgc_alt = 0; 790 791 ugcp->usbgc_tx_list_max = 64; 792 793 ugcp->usbgc_rx_header_len = RX_HEADER_SIZE; 794 ugcp->usbgc_rx_list_max = 64; 795 796 /* time out parameters */ 797 ugcp->usbgc_tx_timeout = USBGEM_TX_TIMEOUT; 798 ugcp->usbgc_tx_timeout_interval = USBGEM_TX_TIMEOUT_INTERVAL; 799 #if 1 800 /* flow control */ 801 ugcp->usbgc_flow_control = FLOW_CONTROL_RX_PAUSE; 802 #else 803 /* 804 * XXX - flow control caused link down frequently under 805 * heavy traffic 806 */ 807 ugcp->usbgc_flow_control = FLOW_CONTROL_NONE; 808 #endif 809 /* MII timeout parameters */ 810 ugcp->usbgc_mii_link_watch_interval = 811 USBGEM_LINK_WATCH_INTERVAL; 812 ugcp->usbgc_mii_an_watch_interval = 813 USBGEM_LINK_WATCH_INTERVAL/5; 814 ugcp->usbgc_mii_reset_timeout = MII_RESET_TIMEOUT; /* 1 sec */ 815 ugcp->usbgc_mii_an_timeout = MII_AN_TIMEOUT; /* 5 sec */ 816 ugcp->usbgc_mii_an_wait = (25*ONESEC)/10; 817 ugcp->usbgc_mii_linkdown_timeout = MII_LINKDOWN_TIMEOUT; 818 819 ugcp->usbgc_mii_an_delay = ONESEC/10; 820 ugcp->usbgc_mii_linkdown_action = MII_ACTION_RSA; 821 ugcp->usbgc_mii_linkdown_timeout_action = MII_ACTION_RESET; 822 ugcp->usbgc_mii_dont_reset = B_FALSE; 823 ugcp->usbgc_mii_hw_link_detection = B_TRUE; 824 825 /* I/O methods */ 826 827 /* mac operation */ 828 ugcp->usbgc_attach_chip = &udmf_attach_chip; 829 ugcp->usbgc_reset_chip = &udmf_reset_chip; 830 ugcp->usbgc_init_chip = &udmf_init_chip; 831 ugcp->usbgc_start_chip = &udmf_start_chip; 832 ugcp->usbgc_stop_chip = &udmf_stop_chip; 833 ugcp->usbgc_multicast_hash = &udmf_mcast_hash; 834 835 ugcp->usbgc_set_rx_filter = &udmf_set_rx_filter; 836 ugcp->usbgc_set_media = &udmf_set_media; 837 ugcp->usbgc_get_stats = &udmf_get_stats; 838 ugcp->usbgc_interrupt = &udmf_interrupt; 839 840 /* packet operation */ 841 ugcp->usbgc_tx_make_packet = &udmf_tx_make_packet; 842 ugcp->usbgc_rx_make_packet = &udmf_rx_make_packet; 843 844 /* mii operations */ 845 ugcp->usbgc_mii_probe = &udmf_mii_probe; 846 ugcp->usbgc_mii_init = &udmf_mii_init; 847 ugcp->usbgc_mii_config = &usbgem_mii_config_default; 848 ugcp->usbgc_mii_read = &udmf_mii_read; 849 ugcp->usbgc_mii_write = &udmf_mii_write; 850 ugcp->usbgc_mii_addr_min = 1; 851 852 /* mtu */ 853 ugcp->usbgc_min_mtu = ETHERMTU; 854 ugcp->usbgc_max_mtu = ETHERMTU; 855 ugcp->usbgc_default_mtu = ETHERMTU; 856 857 lp = kmem_zalloc(sizeof (struct udmf_dev), KM_SLEEP); 858 859 ddi_set_driver_private(dip, NULL); 860 861 dp = usbgem_do_attach(dip, ugcp, lp, sizeof (struct udmf_dev)); 862 863 kmem_free(ugcp, sizeof (*ugcp)); 864 865 if (dp != NULL) { 866 return (DDI_SUCCESS); 867 } 868 869 err_free_mem: 870 kmem_free(lp, sizeof (struct udmf_dev)); 871 err_close_pipe: 872 err: 873 return (DDI_FAILURE); 874 } 875 876 if (cmd == DDI_RESUME) { 877 return (usbgem_resume(dip)); 878 } 879 880 return (DDI_FAILURE); 881 } 882 883 static int 884 udmfdetach(dev_info_t *dip, ddi_detach_cmd_t cmd) 885 { 886 int ret; 887 888 if (cmd == DDI_DETACH) { 889 ret = usbgem_do_detach(dip); 890 if (ret != DDI_SUCCESS) { 891 return (DDI_FAILURE); 892 } 893 return (DDI_SUCCESS); 894 } 895 if (cmd == DDI_SUSPEND) { 896 return (usbgem_suspend(dip)); 897 } 898 return (DDI_FAILURE); 899 } 900 901 /* ======================================================== */ 902 /* 903 * OS depend (loadable streams driver) routine 904 */ 905 /* ======================================================== */ 906 #ifdef USBGEM_CONFIG_GLDv3 907 USBGEM_STREAM_OPS(udmf_ops, udmfattach, udmfdetach); 908 #else 909 static struct module_info udmfminfo = { 910 0, /* mi_idnum */ 911 "udmf", /* mi_idname */ 912 0, /* mi_minpsz */ 913 ETHERMTU, /* mi_maxpsz */ 914 ETHERMTU*128, /* mi_hiwat */ 915 1, /* mi_lowat */ 916 }; 917 918 static struct qinit udmfrinit = { 919 (int (*)()) NULL, /* qi_putp */ 920 usbgem_rsrv, /* qi_srvp */ 921 usbgem_open, /* qi_qopen */ 922 usbgem_close, /* qi_qclose */ 923 (int (*)()) NULL, /* qi_qadmin */ 924 &udmfminfo, /* qi_minfo */ 925 NULL /* qi_mstat */ 926 }; 927 928 static struct qinit udmfwinit = { 929 usbgem_wput, /* qi_putp */ 930 usbgem_wsrv, /* qi_srvp */ 931 (int (*)()) NULL, /* qi_qopen */ 932 (int (*)()) NULL, /* qi_qclose */ 933 (int (*)()) NULL, /* qi_qadmin */ 934 &udmfminfo, /* qi_minfo */ 935 NULL /* qi_mstat */ 936 }; 937 938 static struct streamtab udmf_info = { 939 &udmfrinit, /* st_rdinit */ 940 &udmfwinit, /* st_wrinit */ 941 NULL, /* st_muxrinit */ 942 NULL /* st_muxwrinit */ 943 }; 944 945 static struct cb_ops cb_udmf_ops = { 946 nulldev, /* cb_open */ 947 nulldev, /* cb_close */ 948 nodev, /* cb_strategy */ 949 nodev, /* cb_print */ 950 nodev, /* cb_dump */ 951 nodev, /* cb_read */ 952 nodev, /* cb_write */ 953 nodev, /* cb_ioctl */ 954 nodev, /* cb_devmap */ 955 nodev, /* cb_mmap */ 956 nodev, /* cb_segmap */ 957 nochpoll, /* cb_chpoll */ 958 ddi_prop_op, /* cb_prop_op */ 959 &udmf_info, /* cb_stream */ 960 D_NEW|D_MP /* cb_flag */ 961 }; 962 963 static struct dev_ops udmf_ops = { 964 DEVO_REV, /* devo_rev */ 965 0, /* devo_refcnt */ 966 usbgem_getinfo, /* devo_getinfo */ 967 nulldev, /* devo_identify */ 968 nulldev, /* devo_probe */ 969 udmfattach, /* devo_attach */ 970 udmfdetach, /* devo_detach */ 971 nodev, /* devo_reset */ 972 &cb_udmf_ops, /* devo_cb_ops */ 973 NULL, /* devo_bus_ops */ 974 usbgem_power, /* devo_power */ 975 #if DEVO_REV >= 4 976 usbgem_quiesce, /* devo_quiesce */ 977 #endif 978 }; 979 #endif 980 981 static struct modldrv modldrv = { 982 &mod_driverops, /* Type of module. This one is a driver */ 983 ident, 984 &udmf_ops, /* driver ops */ 985 }; 986 987 static struct modlinkage modlinkage = { 988 MODREV_1, &modldrv, NULL 989 }; 990 991 /* ======================================================== */ 992 /* 993 * _init : done 994 */ 995 /* ======================================================== */ 996 int 997 _init(void) 998 { 999 int status; 1000 1001 DPRINTF(2, (CE_CONT, "!udmf: _init: called")); 1002 1003 status = usbgem_mod_init(&udmf_ops, "udmf"); 1004 if (status != DDI_SUCCESS) { 1005 return (status); 1006 } 1007 status = mod_install(&modlinkage); 1008 if (status != DDI_SUCCESS) { 1009 usbgem_mod_fini(&udmf_ops); 1010 } 1011 return (status); 1012 } 1013 1014 /* 1015 * _fini : done 1016 */ 1017 int 1018 _fini(void) 1019 { 1020 int status; 1021 1022 DPRINTF(2, (CE_CONT, "!udmf: _fini: called")); 1023 status = mod_remove(&modlinkage); 1024 if (status == DDI_SUCCESS) { 1025 usbgem_mod_fini(&udmf_ops); 1026 } 1027 return (status); 1028 } 1029 1030 int 1031 _info(struct modinfo *modinfop) 1032 { 1033 return (mod_info(&modlinkage, modinfop)); 1034 } 1035