1 /* 2 * Copyright (c) 2010 Steven Stallion. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following 12 * disclaimer in the documentation and/or other materials provided 13 * with the distribution. 14 * 3. Neither the name of the copyright owner nor the names of any 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/byteorder.h> 32 #include <sys/types.h> 33 #include <sys/errno.h> 34 #include <sys/varargs.h> 35 #include <sys/cmn_err.h> 36 #include <sys/note.h> 37 #include <sys/kmem.h> 38 #include <sys/conf.h> 39 #include <sys/devops.h> 40 #include <sys/modctl.h> 41 #include <sys/sysmacros.h> 42 #include <sys/ddi.h> 43 #include <sys/ddi_intr.h> 44 #include <sys/sunddi.h> 45 #include <sys/stream.h> 46 #include <sys/strsun.h> 47 #include <sys/pci.h> 48 #include <sys/ethernet.h> 49 #include <sys/vlan.h> 50 #include <sys/crc32.h> 51 #include <sys/mii.h> 52 #include <sys/mac.h> 53 #include <sys/mac_ether.h> 54 #include <sys/mac_provider.h> 55 56 #include "efe.h" 57 58 /* Autoconfiguration entry points */ 59 static int efe_attach(dev_info_t *, ddi_attach_cmd_t); 60 static int efe_detach(dev_info_t *, ddi_detach_cmd_t); 61 static int efe_quiesce(dev_info_t *); 62 63 /* MII entry points */ 64 static uint16_t efe_mii_read(void *, uint8_t, uint8_t); 65 static void efe_mii_write(void *, uint8_t, uint8_t, uint16_t); 66 static void efe_mii_notify(void *, link_state_t); 67 68 /* MAC entry points */ 69 static int efe_m_getstat(void *, uint_t, uint64_t *); 70 static int efe_m_start(void *); 71 static void efe_m_stop(void *); 72 static int efe_m_setpromisc(void *, boolean_t); 73 static int efe_m_multicst(void *, boolean_t, const uint8_t *); 74 static int efe_m_unicst(void *, const uint8_t *); 75 static mblk_t *efe_m_tx(void *, mblk_t *); 76 static int efe_m_setprop(void *, const char *, mac_prop_id_t, uint_t, 77 const void *); 78 static int efe_m_getprop(void *, const char *, mac_prop_id_t, uint_t, 79 void *); 80 static void efe_m_propinfo(void *, const char *, mac_prop_id_t, 81 mac_prop_info_handle_t); 82 83 /* ISR/periodic callbacks */ 84 static uint_t efe_intr(caddr_t, caddr_t); 85 86 /* Support functions */ 87 static void efe_init(efe_t *); 88 static void efe_init_rx_ring(efe_t *); 89 static void efe_init_tx_ring(efe_t *); 90 static void efe_reset(efe_t *); 91 static void efe_start(efe_t *); 92 static void efe_stop(efe_t *); 93 static void efe_stop_dma(efe_t *); 94 static inline void efe_restart(efe_t *); 95 static int efe_suspend(efe_t *); 96 static int efe_resume(efe_t *); 97 98 static efe_ring_t *efe_ring_alloc(dev_info_t *, size_t); 99 static void efe_ring_free(efe_ring_t **); 100 static efe_buf_t *efe_buf_alloc(dev_info_t *, size_t); 101 static void efe_buf_free(efe_buf_t **); 102 103 static void efe_intr_enable(efe_t *); 104 static void efe_intr_disable(efe_t *); 105 106 static mblk_t *efe_recv(efe_t *); 107 static mblk_t *efe_recv_pkt(efe_t *, efe_desc_t *); 108 109 static int efe_send(efe_t *, mblk_t *); 110 static void efe_send_done(efe_t *); 111 112 static void efe_getaddr(efe_t *, uint8_t *); 113 static void efe_setaddr(efe_t *, uint8_t *); 114 static void efe_setmchash(efe_t *, uint16_t *); 115 116 static void efe_eeprom_read(efe_t *, uint8_t *, size_t, uint8_t); 117 static uint16_t efe_eeprom_readw(efe_t *, int, uint8_t); 118 static inline int efe_eeprom_readbit(efe_t *); 119 static inline void efe_eeprom_writebit(efe_t *, int); 120 121 static void efe_dprintf(dev_info_t *, int, const char *, ...); 122 123 #ifdef DEBUG 124 #define efe_debug(dip, ...) \ 125 efe_dprintf((dip), CE_CONT, __VA_ARGS__) 126 #else 127 #define efe_debug(dip, ...) /*EMPTY*/ 128 #endif 129 130 #define efe_error(dip, ...) \ 131 efe_dprintf((dip), CE_WARN, __VA_ARGS__) 132 133 extern struct mod_ops mod_driverops; 134 135 DDI_DEFINE_STREAM_OPS(efe_dev_ops, nulldev, nulldev, efe_attach, efe_detach, 136 nodev, NULL, D_MP, NULL, efe_quiesce); 137 138 static struct modldrv modldrv = { 139 &mod_driverops, /* drv_modops */ 140 "EPIC/100 Fast Ethernet", /* drv_linkinfo */ 141 &efe_dev_ops /* drv_dev_ops */ 142 }; 143 144 static struct modlinkage modlinkage = { 145 MODREV_1, /* ml_rev */ 146 { &modldrv, NULL } /* ml_linkage */ 147 }; 148 149 static ddi_device_acc_attr_t efe_regs_acc_attr = { 150 DDI_DEVICE_ATTR_V0, /* devacc_attr_version */ 151 DDI_STRUCTURE_LE_ACC, /* devacc_attr_endian_flags */ 152 DDI_STRICTORDER_ACC /* devacc_attr_dataorder */ 153 }; 154 155 static ddi_device_acc_attr_t efe_buf_acc_attr = { 156 DDI_DEVICE_ATTR_V0, /* devacc_attr_version */ 157 DDI_NEVERSWAP_ACC, /* devacc_attr_endian_flags */ 158 DDI_STRICTORDER_ACC /* devacc_attr_dataorder */ 159 }; 160 161 static ddi_dma_attr_t efe_dma_attr = { 162 DMA_ATTR_V0, /* dma_attr_version */ 163 0, /* dma_attr_addr_lo */ 164 0xFFFFFFFFUL, /* dma_attr_addr_hi */ 165 0x7FFFFFFFUL, /* dma_attr_count_max */ 166 4, /* dma_attr_align */ 167 0x7F, /* dma_attr_burstsizes */ 168 1, /* dma_attr_minxfer */ 169 0xFFFFFFFFUL, /* dma_attr_maxxfer */ 170 0xFFFFFFFFUL, /* dma_attr_seg */ 171 1, /* dma_attr_sgllen */ 172 1, /* dma_attr_granular */ 173 0 /* dma_attr_flags */ 174 }; 175 176 static mii_ops_t efe_mii_ops = { 177 MII_OPS_VERSION, /* mii_version */ 178 efe_mii_read, /* mii_read */ 179 efe_mii_write, /* mii_write */ 180 efe_mii_notify /* mii_notify */ 181 }; 182 183 static mac_callbacks_t efe_m_callbacks = { 184 MC_SETPROP | MC_GETPROP, /* mc_callbacks */ 185 efe_m_getstat, /* mc_getstat */ 186 efe_m_start, /* mc_start */ 187 efe_m_stop, /* mc_stop */ 188 efe_m_setpromisc, /* mc_setpromisc */ 189 efe_m_multicst, /* mc_multicst */ 190 efe_m_unicst, /* mc_unicst */ 191 efe_m_tx, /* mc_tx */ 192 NULL, /* mc_reserved */ 193 NULL, /* mc_ioctl */ 194 NULL, /* mc_getcapab */ 195 NULL, /* mc_open */ 196 NULL, /* mc_close */ 197 efe_m_setprop, /* mc_setprop */ 198 efe_m_getprop, /* mc_getprop */ 199 efe_m_propinfo /* mc_propinfo */ 200 }; 201 202 static uint8_t efe_broadcast[] = { 203 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 204 }; 205 206 static uint16_t efe_mchash_promisc[] = { 207 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF 208 }; 209 210 /* 211 * Loadable module entry points. 212 */ 213 int 214 _init(void) 215 { 216 int error; 217 218 mac_init_ops(&efe_dev_ops, "efe"); 219 if ((error = mod_install(&modlinkage)) != DDI_SUCCESS) { 220 mac_fini_ops(&efe_dev_ops); 221 } 222 223 return (error); 224 } 225 226 int 227 _fini(void) 228 { 229 int error; 230 231 if ((error = mod_remove(&modlinkage)) == DDI_SUCCESS) { 232 mac_fini_ops(&efe_dev_ops); 233 } 234 235 return (error); 236 } 237 238 int 239 _info(struct modinfo *modinfop) 240 { 241 return (mod_info(&modlinkage, modinfop)); 242 } 243 244 /* 245 * Autoconfiguration entry points. 246 */ 247 int 248 efe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 249 { 250 ddi_acc_handle_t pci; 251 int types; 252 int count; 253 int actual; 254 uint_t pri; 255 efe_t *efep; 256 mac_register_t *macp; 257 258 switch (cmd) { 259 case DDI_ATTACH: 260 break; 261 262 case DDI_RESUME: 263 efep = ddi_get_driver_private(dip); 264 return (efe_resume(efep)); 265 266 default: 267 return (DDI_FAILURE); 268 } 269 270 /* 271 * PCI configuration. 272 */ 273 if (pci_config_setup(dip, &pci) != DDI_SUCCESS) { 274 efe_error(dip, "unable to setup PCI configuration!"); 275 return (DDI_FAILURE); 276 } 277 278 pci_config_put16(pci, PCI_CONF_COMM, 279 pci_config_get16(pci, PCI_CONF_COMM) | PCI_COMM_MAE | PCI_COMM_ME); 280 281 pci_config_teardown(&pci); 282 283 if (ddi_intr_get_supported_types(dip, &types) 284 != DDI_SUCCESS || !(types & DDI_INTR_TYPE_FIXED)) { 285 efe_error(dip, "fixed interrupts not supported!"); 286 return (DDI_FAILURE); 287 } 288 289 if (ddi_intr_get_nintrs(dip, DDI_INTR_TYPE_FIXED, &count) 290 != DDI_SUCCESS || count != 1) { 291 efe_error(dip, "no fixed interrupts available!"); 292 return (DDI_FAILURE); 293 } 294 295 /* 296 * Initialize soft state. 297 */ 298 efep = kmem_zalloc(sizeof (efe_t), KM_SLEEP); 299 ddi_set_driver_private(dip, efep); 300 301 efep->efe_dip = dip; 302 303 if (ddi_regs_map_setup(dip, 1, (caddr_t *)&efep->efe_regs, 0, 0, 304 &efe_regs_acc_attr, &efep->efe_regs_acch) != DDI_SUCCESS) { 305 efe_error(dip, "unable to setup register mapping!"); 306 goto failure; 307 } 308 309 efep->efe_rx_ring = efe_ring_alloc(efep->efe_dip, RXDESCL); 310 if (efep->efe_rx_ring == NULL) { 311 efe_error(efep->efe_dip, "unable to allocate rx ring!"); 312 goto failure; 313 } 314 315 efep->efe_tx_ring = efe_ring_alloc(efep->efe_dip, TXDESCL); 316 if (efep->efe_tx_ring == NULL) { 317 efe_error(efep->efe_dip, "unable to allocate tx ring!"); 318 goto failure; 319 } 320 321 if (ddi_intr_alloc(dip, &efep->efe_intrh, DDI_INTR_TYPE_FIXED, 0, 322 count, &actual, DDI_INTR_ALLOC_STRICT) != DDI_SUCCESS || 323 actual != count) { 324 efe_error(dip, "unable to allocate fixed interrupt!"); 325 goto failure; 326 } 327 328 if (ddi_intr_get_pri(efep->efe_intrh, &pri) != DDI_SUCCESS || 329 pri >= ddi_intr_get_hilevel_pri()) { 330 efe_error(dip, "unable to get valid interrupt priority!"); 331 goto failure; 332 } 333 334 mutex_init(&efep->efe_intrlock, NULL, MUTEX_DRIVER, 335 DDI_INTR_PRI(pri)); 336 337 mutex_init(&efep->efe_txlock, NULL, MUTEX_DRIVER, 338 DDI_INTR_PRI(pri)); 339 340 /* 341 * Initialize device. 342 */ 343 mutex_enter(&efep->efe_intrlock); 344 mutex_enter(&efep->efe_txlock); 345 346 efe_reset(efep); 347 348 mutex_exit(&efep->efe_txlock); 349 mutex_exit(&efep->efe_intrlock); 350 351 /* Use factory address as default */ 352 efe_getaddr(efep, efep->efe_macaddr); 353 354 /* 355 * Enable the ISR. 356 */ 357 if (ddi_intr_add_handler(efep->efe_intrh, efe_intr, efep, NULL) 358 != DDI_SUCCESS) { 359 efe_error(dip, "unable to add interrupt handler!"); 360 goto failure; 361 } 362 363 if (ddi_intr_enable(efep->efe_intrh) != DDI_SUCCESS) { 364 efe_error(dip, "unable to enable interrupt!"); 365 goto failure; 366 } 367 368 /* 369 * Allocate MII resources. 370 */ 371 if ((efep->efe_miih = mii_alloc(efep, dip, &efe_mii_ops)) == NULL) { 372 efe_error(dip, "unable to allocate mii resources!"); 373 goto failure; 374 } 375 376 /* 377 * Allocate MAC resources. 378 */ 379 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 380 efe_error(dip, "unable to allocate mac resources!"); 381 goto failure; 382 } 383 384 macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 385 macp->m_driver = efep; 386 macp->m_dip = dip; 387 macp->m_src_addr = efep->efe_macaddr; 388 macp->m_callbacks = &efe_m_callbacks; 389 macp->m_min_sdu = 0; 390 macp->m_max_sdu = ETHERMTU; 391 macp->m_margin = VLAN_TAGSZ; 392 393 if (mac_register(macp, &efep->efe_mh) != 0) { 394 efe_error(dip, "unable to register with mac!"); 395 goto failure; 396 } 397 mac_free(macp); 398 399 ddi_report_dev(dip); 400 401 return (DDI_SUCCESS); 402 403 failure: 404 if (macp != NULL) { 405 mac_free(macp); 406 } 407 408 if (efep->efe_miih != NULL) { 409 mii_free(efep->efe_miih); 410 } 411 412 if (efep->efe_intrh != NULL) { 413 (void) ddi_intr_disable(efep->efe_intrh); 414 (void) ddi_intr_remove_handler(efep->efe_intrh); 415 (void) ddi_intr_free(efep->efe_intrh); 416 } 417 418 mutex_destroy(&efep->efe_txlock); 419 mutex_destroy(&efep->efe_intrlock); 420 421 if (efep->efe_tx_ring != NULL) { 422 efe_ring_free(&efep->efe_tx_ring); 423 } 424 if (efep->efe_rx_ring != NULL) { 425 efe_ring_free(&efep->efe_rx_ring); 426 } 427 428 if (efep->efe_regs_acch != NULL) { 429 ddi_regs_map_free(&efep->efe_regs_acch); 430 } 431 432 kmem_free(efep, sizeof (efe_t)); 433 434 return (DDI_FAILURE); 435 } 436 437 int 438 efe_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 439 { 440 efe_t *efep = ddi_get_driver_private(dip); 441 442 switch (cmd) { 443 case DDI_DETACH: 444 break; 445 446 case DDI_SUSPEND: 447 return (efe_suspend(efep)); 448 449 default: 450 return (DDI_FAILURE); 451 } 452 453 if (mac_unregister(efep->efe_mh) != 0) { 454 efe_error(dip, "unable to unregister from mac!"); 455 return (DDI_FAILURE); 456 } 457 458 mii_free(efep->efe_miih); 459 460 (void) ddi_intr_disable(efep->efe_intrh); 461 (void) ddi_intr_remove_handler(efep->efe_intrh); 462 (void) ddi_intr_free(efep->efe_intrh); 463 464 mutex_destroy(&efep->efe_txlock); 465 mutex_destroy(&efep->efe_intrlock); 466 467 if (efep->efe_tx_ring != NULL) { 468 efe_ring_free(&efep->efe_tx_ring); 469 } 470 if (efep->efe_rx_ring != NULL) { 471 efe_ring_free(&efep->efe_rx_ring); 472 } 473 474 ddi_regs_map_free(&efep->efe_regs_acch); 475 476 kmem_free(efep, sizeof (efe_t)); 477 478 return (DDI_SUCCESS); 479 } 480 481 int 482 efe_quiesce(dev_info_t *dip) 483 { 484 efe_t *efep = ddi_get_driver_private(dip); 485 486 PUTCSR(efep, CSR_GENCTL, GENCTL_RESET); 487 drv_usecwait(RESET_DELAY); 488 489 PUTCSR(efep, CSR_GENCTL, GENCTL_PWRDWN); 490 491 return (DDI_SUCCESS); 492 } 493 494 /* 495 * MII entry points. 496 */ 497 uint16_t 498 efe_mii_read(void *arg, uint8_t phy, uint8_t reg) 499 { 500 efe_t *efep = arg; 501 502 PUTCSR(efep, CSR_MMCTL, MMCTL_READ | 503 reg << MMCTL_PHYREG | phy << MMCTL_PHYADDR); 504 505 for (int i = 0; i < MII_DELAY_CYCLES; ++i) { 506 if (!(GETCSR(efep, CSR_MMCTL) & MMCTL_READ)) { 507 return ((uint16_t)GETCSR(efep, CSR_MMDATA)); 508 } 509 drv_usecwait(MII_DELAY); 510 } 511 efe_error(efep->efe_dip, "timed out reading from MII!"); 512 513 return (0); 514 } 515 516 void 517 efe_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t data) 518 { 519 efe_t *efep = arg; 520 521 PUTCSR(efep, CSR_MMDATA, data); 522 523 PUTCSR(efep, CSR_MMCTL, MMCTL_WRITE | 524 reg << MMCTL_PHYREG | phy << MMCTL_PHYADDR); 525 526 for (int i = 0; i < MII_DELAY_CYCLES; ++i) { 527 if (!(GETCSR(efep, CSR_MMCTL) & MMCTL_WRITE)) { 528 return; 529 } 530 drv_usecwait(MII_DELAY); 531 } 532 efe_error(efep->efe_dip, "timed out writing to MII!"); 533 } 534 535 void 536 efe_mii_notify(void *arg, link_state_t link) 537 { 538 efe_t *efep = arg; 539 540 mac_link_update(efep->efe_mh, link); 541 } 542 543 /* 544 * MAC entry points. 545 */ 546 int 547 efe_m_getstat(void *arg, uint_t stat, uint64_t *val) 548 { 549 efe_t *efep = arg; 550 551 if (mii_m_getstat(efep->efe_miih, stat, val) == 0) { 552 return (0); 553 } 554 555 switch (stat) { 556 case MAC_STAT_MULTIRCV: 557 *val = efep->efe_multircv; 558 break; 559 560 case MAC_STAT_BRDCSTRCV: 561 *val = efep->efe_brdcstrcv; 562 break; 563 564 case MAC_STAT_MULTIXMT: 565 *val = efep->efe_multixmt; 566 break; 567 568 case MAC_STAT_BRDCSTXMT: 569 *val = efep->efe_brdcstxmt; 570 break; 571 572 case MAC_STAT_NORCVBUF: 573 *val = efep->efe_norcvbuf; 574 break; 575 576 case MAC_STAT_IERRORS: 577 *val = efep->efe_ierrors; 578 break; 579 580 case MAC_STAT_NOXMTBUF: 581 *val = efep->efe_noxmtbuf; 582 break; 583 584 case MAC_STAT_OERRORS: 585 *val = efep->efe_oerrors; 586 break; 587 588 case MAC_STAT_COLLISIONS: 589 *val = efep->efe_collisions; 590 break; 591 592 case MAC_STAT_RBYTES: 593 *val = efep->efe_rbytes; 594 break; 595 596 case MAC_STAT_IPACKETS: 597 *val = efep->efe_ipackets; 598 break; 599 600 case MAC_STAT_OBYTES: 601 *val = efep->efe_obytes; 602 break; 603 604 case MAC_STAT_OPACKETS: 605 *val = efep->efe_opackets; 606 break; 607 608 case MAC_STAT_UNDERFLOWS: 609 *val = efep->efe_uflo; 610 break; 611 612 case MAC_STAT_OVERFLOWS: 613 *val = efep->efe_oflo; 614 break; 615 616 case ETHER_STAT_ALIGN_ERRORS: 617 *val = efep->efe_align_errors; 618 break; 619 620 case ETHER_STAT_FCS_ERRORS: 621 *val = efep->efe_fcs_errors; 622 break; 623 624 case ETHER_STAT_FIRST_COLLISIONS: 625 *val = efep->efe_first_collisions; 626 break; 627 628 case ETHER_STAT_TX_LATE_COLLISIONS: 629 *val = efep->efe_tx_late_collisions; 630 break; 631 632 case ETHER_STAT_DEFER_XMTS: 633 *val = efep->efe_defer_xmts; 634 break; 635 636 case ETHER_STAT_EX_COLLISIONS: 637 *val = efep->efe_ex_collisions; 638 break; 639 640 case ETHER_STAT_MACXMT_ERRORS: 641 *val = efep->efe_macxmt_errors; 642 break; 643 644 case ETHER_STAT_CARRIER_ERRORS: 645 *val = efep->efe_carrier_errors; 646 break; 647 648 case ETHER_STAT_TOOLONG_ERRORS: 649 *val = efep->efe_toolong_errors; 650 break; 651 652 case ETHER_STAT_MACRCV_ERRORS: 653 *val = efep->efe_macrcv_errors; 654 break; 655 656 case ETHER_STAT_TOOSHORT_ERRORS: 657 *val = efep->efe_runt_errors; 658 break; 659 660 case ETHER_STAT_JABBER_ERRORS: 661 *val = efep->efe_jabber_errors; 662 break; 663 664 default: 665 return (ENOTSUP); 666 } 667 668 return (0); 669 } 670 671 int 672 efe_m_start(void *arg) 673 { 674 efe_t *efep = arg; 675 676 mutex_enter(&efep->efe_intrlock); 677 mutex_enter(&efep->efe_txlock); 678 679 efe_start(efep); 680 efep->efe_flags |= FLAG_RUNNING; 681 682 mutex_exit(&efep->efe_txlock); 683 mutex_exit(&efep->efe_intrlock); 684 685 mii_start(efep->efe_miih); 686 687 return (0); 688 } 689 690 void 691 efe_m_stop(void *arg) 692 { 693 efe_t *efep = arg; 694 695 mutex_enter(&efep->efe_intrlock); 696 mutex_enter(&efep->efe_txlock); 697 698 efe_stop(efep); 699 efep->efe_flags &= ~FLAG_RUNNING; 700 701 mutex_exit(&efep->efe_txlock); 702 mutex_exit(&efep->efe_intrlock); 703 704 mii_stop(efep->efe_miih); 705 } 706 707 int 708 efe_m_setpromisc(void *arg, boolean_t on) 709 { 710 efe_t *efep = arg; 711 712 mutex_enter(&efep->efe_intrlock); 713 mutex_enter(&efep->efe_txlock); 714 715 if (efep->efe_flags & FLAG_SUSPENDED) { 716 mutex_exit(&efep->efe_txlock); 717 mutex_exit(&efep->efe_intrlock); 718 return (0); 719 } 720 721 efep->efe_promisc = on; 722 723 if (efep->efe_flags & FLAG_RUNNING) { 724 efe_restart(efep); 725 } 726 727 mutex_exit(&efep->efe_txlock); 728 mutex_exit(&efep->efe_intrlock); 729 730 return (0); 731 } 732 733 int 734 efe_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr) 735 { 736 efe_t *efep = arg; 737 uint32_t val; 738 int index; 739 int bit; 740 boolean_t restart = B_FALSE; 741 742 mutex_enter(&efep->efe_intrlock); 743 mutex_enter(&efep->efe_txlock); 744 745 if (efep->efe_flags & FLAG_SUSPENDED) { 746 mutex_exit(&efep->efe_txlock); 747 mutex_exit(&efep->efe_intrlock); 748 return (0); 749 } 750 751 CRC32(val, macaddr, ETHERADDRL, -1U, crc32_table); 752 val %= MCHASHL; 753 754 index = val / MCHASHSZ; 755 bit = 1U << (val % MCHASHSZ); 756 757 if (add) { 758 efep->efe_mccount[val]++; 759 if (efep->efe_mccount[val] == 1) { 760 efep->efe_mchash[index] |= bit; 761 restart = B_TRUE; 762 } 763 764 } else { 765 efep->efe_mccount[val]--; 766 if (efep->efe_mccount[val] == 0) { 767 efep->efe_mchash[index] &= ~bit; 768 restart = B_TRUE; 769 } 770 } 771 772 if (restart && efep->efe_flags & FLAG_RUNNING) { 773 efe_restart(efep); 774 } 775 776 mutex_exit(&efep->efe_txlock); 777 mutex_exit(&efep->efe_intrlock); 778 779 return (0); 780 } 781 782 int 783 efe_m_unicst(void *arg, const uint8_t *macaddr) 784 { 785 efe_t *efep = arg; 786 787 mutex_enter(&efep->efe_intrlock); 788 mutex_enter(&efep->efe_txlock); 789 790 if (efep->efe_flags & FLAG_SUSPENDED) { 791 mutex_exit(&efep->efe_txlock); 792 mutex_exit(&efep->efe_intrlock); 793 return (0); 794 } 795 796 bcopy(macaddr, efep->efe_macaddr, ETHERADDRL); 797 798 if (efep->efe_flags & FLAG_RUNNING) { 799 efe_restart(efep); 800 } 801 802 mutex_exit(&efep->efe_txlock); 803 mutex_exit(&efep->efe_intrlock); 804 805 return (0); 806 } 807 808 mblk_t * 809 efe_m_tx(void *arg, mblk_t *mp) 810 { 811 efe_t *efep = arg; 812 813 mutex_enter(&efep->efe_txlock); 814 815 if (efep->efe_flags & FLAG_SUSPENDED) { 816 mutex_exit(&efep->efe_txlock); 817 return (mp); 818 } 819 820 while (mp != NULL) { 821 mblk_t *tmp = mp->b_next; 822 mp->b_next = NULL; 823 824 if (efe_send(efep, mp) != DDI_SUCCESS) { 825 mp->b_next = tmp; 826 break; 827 } 828 mp = tmp; 829 } 830 831 /* Kick the transmitter */ 832 PUTCSR(efep, CSR_COMMAND, COMMAND_TXQUEUED); 833 834 mutex_exit(&efep->efe_txlock); 835 836 return (mp); 837 } 838 839 int 840 efe_m_setprop(void *arg, const char *name, mac_prop_id_t id, 841 uint_t valsize, const void *val) 842 { 843 efe_t *efep = arg; 844 845 return (mii_m_setprop(efep->efe_miih, name, id, valsize, val)); 846 } 847 848 int 849 efe_m_getprop(void *arg, const char *name, mac_prop_id_t id, 850 uint_t valsize, void *val) 851 { 852 efe_t *efep = arg; 853 854 return (mii_m_getprop(efep->efe_miih, name, id, valsize, val)); 855 } 856 857 void 858 efe_m_propinfo(void *arg, const char *name, mac_prop_id_t id, 859 mac_prop_info_handle_t state) 860 { 861 efe_t *efep = arg; 862 863 mii_m_propinfo(efep->efe_miih, name, id, state); 864 } 865 866 /* 867 * ISR/periodic callbacks. 868 */ 869 uint_t 870 efe_intr(caddr_t arg1, caddr_t arg2) 871 { 872 efe_t *efep = (void *)arg1; 873 uint32_t status; 874 mblk_t *mp = NULL; 875 876 _NOTE(ARGUNUSED(arg2)); 877 878 mutex_enter(&efep->efe_intrlock); 879 880 if (efep->efe_flags & FLAG_SUSPENDED) { 881 mutex_exit(&efep->efe_intrlock); 882 return (DDI_INTR_UNCLAIMED); 883 } 884 885 status = GETCSR(efep, CSR_INTSTAT); 886 if (!(status & INTSTAT_ACTV)) { 887 mutex_exit(&efep->efe_intrlock); 888 return (DDI_INTR_UNCLAIMED); 889 } 890 PUTCSR(efep, CSR_INTSTAT, status); 891 892 if (status & INTSTAT_RCC) { 893 mp = efe_recv(efep); 894 } 895 896 if (status & INTSTAT_RQE) { 897 efep->efe_ierrors++; 898 efep->efe_macrcv_errors++; 899 900 /* Kick the receiver */ 901 PUTCSR(efep, CSR_COMMAND, COMMAND_RXQUEUED); 902 } 903 904 if (status & INTSTAT_TXC) { 905 mutex_enter(&efep->efe_txlock); 906 907 efe_send_done(efep); 908 909 mutex_exit(&efep->efe_txlock); 910 } 911 912 if (status & INTSTAT_FATAL) { 913 mutex_enter(&efep->efe_txlock); 914 915 efe_error(efep->efe_dip, "bus error; resetting!"); 916 efe_restart(efep); 917 918 mutex_exit(&efep->efe_txlock); 919 } 920 921 mutex_exit(&efep->efe_intrlock); 922 923 if (mp != NULL) { 924 mac_rx(efep->efe_mh, NULL, mp); 925 } 926 927 if (status & INTSTAT_TXC) { 928 mac_tx_update(efep->efe_mh); 929 } 930 931 if (status & INTSTAT_FATAL) { 932 mii_reset(efep->efe_miih); 933 } 934 935 return (DDI_INTR_CLAIMED); 936 } 937 938 /* 939 * Support functions. 940 */ 941 void 942 efe_init(efe_t *efep) 943 { 944 uint32_t val; 945 946 ASSERT(mutex_owned(&efep->efe_intrlock)); 947 ASSERT(mutex_owned(&efep->efe_txlock)); 948 949 efe_reset(efep); 950 951 val = GENCTL_ONECOPY | GENCTL_RFT_128 | GENCTL_MRM; 952 #ifdef _BIG_ENDIAN 953 val |= GENCTL_BE; 954 #endif /* _BIG_ENDIAN */ 955 956 PUTCSR(efep, CSR_GENCTL, val); 957 PUTCSR(efep, CSR_PBLCNT, BURSTLEN); 958 959 efe_init_rx_ring(efep); 960 efe_init_tx_ring(efep); 961 962 efe_setaddr(efep, efep->efe_macaddr); 963 964 if (efep->efe_promisc) { 965 efe_setmchash(efep, efe_mchash_promisc); 966 } else { 967 efe_setmchash(efep, efep->efe_mchash); 968 } 969 } 970 971 void 972 efe_init_rx_ring(efe_t *efep) 973 { 974 efe_ring_t *rp; 975 976 ASSERT(mutex_owned(&efep->efe_intrlock)); 977 978 rp = efep->efe_rx_ring; 979 980 for (int i = 0; i < DESCLEN(rp); ++i) { 981 efe_desc_t *dp = GETDESC(rp, i); 982 efe_buf_t *bp = GETBUF(rp, i); 983 984 PUTDESC16(rp, &dp->d_status, RXSTAT_OWNER); 985 PUTDESC16(rp, &dp->d_len, 0); 986 PUTDESC32(rp, &dp->d_bufaddr, BUFADDR(bp)); 987 PUTDESC16(rp, &dp->d_buflen, BUFLEN(bp)); 988 PUTDESC16(rp, &dp->d_control, 0); 989 PUTDESC32(rp, &dp->d_next, NEXTDESCADDR(rp, i)); 990 991 SYNCDESC(rp, i, DDI_DMA_SYNC_FORDEV); 992 } 993 994 efep->efe_rx_desc = 0; 995 996 PUTCSR(efep, CSR_PRCDAR, DESCADDR(rp, 0)); 997 } 998 999 void 1000 efe_init_tx_ring(efe_t *efep) 1001 { 1002 efe_ring_t *rp; 1003 1004 ASSERT(mutex_owned(&efep->efe_txlock)); 1005 1006 rp = efep->efe_tx_ring; 1007 1008 for (int i = 0; i < DESCLEN(rp); ++i) { 1009 efe_desc_t *dp = GETDESC(rp, i); 1010 efe_buf_t *bp = GETBUF(rp, i); 1011 1012 PUTDESC16(rp, &dp->d_status, 0); 1013 PUTDESC16(rp, &dp->d_len, 0); 1014 PUTDESC32(rp, &dp->d_bufaddr, BUFADDR(bp)); 1015 PUTDESC16(rp, &dp->d_buflen, BUFLEN(bp)); 1016 PUTDESC16(rp, &dp->d_control, 0); 1017 PUTDESC32(rp, &dp->d_next, NEXTDESCADDR(rp, i)); 1018 1019 SYNCDESC(rp, i, DDI_DMA_SYNC_FORDEV); 1020 } 1021 1022 efep->efe_tx_desc = 0; 1023 efep->efe_tx_sent = 0; 1024 1025 PUTCSR(efep, CSR_PTCDAR, DESCADDR(rp, 0)); 1026 } 1027 1028 void 1029 efe_reset(efe_t *efep) 1030 { 1031 ASSERT(mutex_owned(&efep->efe_intrlock)); 1032 ASSERT(mutex_owned(&efep->efe_txlock)); 1033 1034 PUTCSR(efep, CSR_GENCTL, GENCTL_RESET); 1035 drv_usecwait(RESET_DELAY); 1036 1037 /* Assert internal clock source (AN 7.15) */ 1038 for (int i = 0; i < RESET_TEST_CYCLES; ++i) { 1039 PUTCSR(efep, CSR_TEST, TEST_CLOCK); 1040 } 1041 } 1042 1043 void 1044 efe_start(efe_t *efep) 1045 { 1046 ASSERT(mutex_owned(&efep->efe_intrlock)); 1047 ASSERT(mutex_owned(&efep->efe_txlock)); 1048 1049 efe_init(efep); 1050 1051 PUTCSR(efep, CSR_RXCON, 1052 RXCON_SEP | RXCON_RRF | RXCON_RBF | RXCON_RMF | 1053 (efep->efe_promisc ? RXCON_PROMISC : 0)); 1054 1055 PUTCSR(efep, CSR_TXCON, TXCON_LB_3); 1056 1057 efe_intr_enable(efep); 1058 1059 SETBIT(efep, CSR_COMMAND, 1060 COMMAND_START_RX | COMMAND_RXQUEUED); 1061 } 1062 1063 void 1064 efe_stop(efe_t *efep) 1065 { 1066 ASSERT(mutex_owned(&efep->efe_intrlock)); 1067 ASSERT(mutex_owned(&efep->efe_txlock)); 1068 1069 efe_intr_disable(efep); 1070 1071 PUTCSR(efep, CSR_COMMAND, COMMAND_STOP_RX); 1072 1073 efe_stop_dma(efep); 1074 1075 PUTCSR(efep, CSR_GENCTL, GENCTL_RESET); 1076 drv_usecwait(RESET_DELAY); 1077 1078 PUTCSR(efep, CSR_GENCTL, GENCTL_PWRDWN); 1079 } 1080 1081 void 1082 efe_stop_dma(efe_t *efep) 1083 { 1084 ASSERT(mutex_owned(&efep->efe_intrlock)); 1085 ASSERT(mutex_owned(&efep->efe_txlock)); 1086 1087 PUTCSR(efep, CSR_COMMAND, 1088 COMMAND_STOP_RDMA | COMMAND_STOP_TDMA); 1089 1090 for (int i = 0; i < STOP_DELAY_CYCLES; ++i) { 1091 uint32_t status = GETCSR(efep, CSR_INTSTAT); 1092 if (status & INTSTAT_RXIDLE && 1093 status & INTSTAT_TXIDLE) { 1094 return; 1095 } 1096 drv_usecwait(STOP_DELAY); 1097 } 1098 efe_error(efep->efe_dip, "timed out stopping DMA engine!"); 1099 } 1100 1101 static inline void 1102 efe_restart(efe_t *efep) 1103 { 1104 efe_stop(efep); 1105 efe_start(efep); 1106 } 1107 1108 int 1109 efe_suspend(efe_t *efep) 1110 { 1111 mutex_enter(&efep->efe_intrlock); 1112 mutex_enter(&efep->efe_txlock); 1113 1114 if (efep->efe_flags & FLAG_RUNNING) { 1115 efe_stop(efep); 1116 } 1117 efep->efe_flags |= FLAG_SUSPENDED; 1118 1119 mutex_exit(&efep->efe_txlock); 1120 mutex_exit(&efep->efe_intrlock); 1121 1122 mii_suspend(efep->efe_miih); 1123 1124 return (DDI_SUCCESS); 1125 } 1126 1127 int 1128 efe_resume(efe_t *efep) 1129 { 1130 mutex_enter(&efep->efe_intrlock); 1131 mutex_enter(&efep->efe_txlock); 1132 1133 if (efep->efe_flags & FLAG_RUNNING) { 1134 efe_start(efep); 1135 } 1136 efep->efe_flags &= ~FLAG_SUSPENDED; 1137 1138 mutex_exit(&efep->efe_txlock); 1139 mutex_exit(&efep->efe_intrlock); 1140 1141 mii_resume(efep->efe_miih); 1142 1143 return (DDI_SUCCESS); 1144 } 1145 1146 efe_ring_t * 1147 efe_ring_alloc(dev_info_t *dip, size_t len) 1148 { 1149 efe_ring_t *rp; 1150 size_t rlen; 1151 uint_t ccount; 1152 1153 ASSERT(len > 1); 1154 1155 rp = kmem_zalloc(sizeof (efe_ring_t), KM_SLEEP); 1156 rp->r_len = len; 1157 1158 if (ddi_dma_alloc_handle(dip, &efe_dma_attr, DDI_DMA_SLEEP, NULL, 1159 &rp->r_dmah) != DDI_SUCCESS) { 1160 efe_error(dip, "unable to allocate DMA handle!"); 1161 goto failure; 1162 } 1163 1164 if (ddi_dma_mem_alloc(rp->r_dmah, DESCSZ(len), &efe_buf_acc_attr, 1165 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, (caddr_t *)&rp->r_descp, 1166 &rlen, &rp->r_acch) != DDI_SUCCESS) { 1167 efe_error(dip, "unable to allocate descriptors!"); 1168 goto failure; 1169 } 1170 1171 if (ddi_dma_addr_bind_handle(rp->r_dmah, NULL, (caddr_t)rp->r_descp, 1172 DESCSZ(len), DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, 1173 NULL, &rp->r_dmac, &ccount) != DDI_DMA_MAPPED) { 1174 efe_error(dip, "unable to bind DMA handle to descriptors!"); 1175 goto failure; 1176 } 1177 1178 rp->r_bufpp = kmem_zalloc(BUFPSZ(len), KM_SLEEP); 1179 1180 for (int i = 0; i < len; ++i) { 1181 efe_buf_t *bp = efe_buf_alloc(dip, BUFSZ); 1182 if (bp == NULL) { 1183 goto failure; 1184 } 1185 rp->r_bufpp[i] = bp; 1186 } 1187 1188 return (rp); 1189 1190 failure: 1191 efe_ring_free(&rp); 1192 1193 return (NULL); 1194 } 1195 1196 void 1197 efe_ring_free(efe_ring_t **rpp) 1198 { 1199 efe_ring_t *rp = *rpp; 1200 1201 ASSERT(rp != NULL); 1202 1203 for (int i = 0; i < DESCLEN(rp); ++i) { 1204 efe_buf_t *bp = GETBUF(rp, i); 1205 if (bp != NULL) { 1206 efe_buf_free(&bp); 1207 } 1208 } 1209 kmem_free(rp->r_bufpp, BUFPSZ(DESCLEN(rp))); 1210 1211 if (rp->r_descp != NULL) { 1212 (void) ddi_dma_unbind_handle(rp->r_dmah); 1213 } 1214 if (rp->r_acch != NULL) { 1215 ddi_dma_mem_free(&rp->r_acch); 1216 } 1217 if (rp->r_dmah != NULL) { 1218 ddi_dma_free_handle(&rp->r_dmah); 1219 } 1220 kmem_free(rp, sizeof (efe_ring_t)); 1221 1222 *rpp = NULL; 1223 } 1224 1225 efe_buf_t * 1226 efe_buf_alloc(dev_info_t *dip, size_t len) 1227 { 1228 efe_buf_t *bp; 1229 size_t rlen; 1230 uint_t ccount; 1231 1232 bp = kmem_zalloc(sizeof (efe_buf_t), KM_SLEEP); 1233 bp->b_len = len; 1234 1235 if (ddi_dma_alloc_handle(dip, &efe_dma_attr, DDI_DMA_SLEEP, NULL, 1236 &bp->b_dmah) != DDI_SUCCESS) { 1237 efe_error(dip, "unable to allocate DMA handle!"); 1238 goto failure; 1239 } 1240 1241 if (ddi_dma_mem_alloc(bp->b_dmah, len, &efe_buf_acc_attr, 1242 DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, &bp->b_kaddr, &rlen, 1243 &bp->b_acch) != DDI_SUCCESS) { 1244 efe_error(dip, "unable to allocate buffer!"); 1245 goto failure; 1246 } 1247 1248 if (ddi_dma_addr_bind_handle(bp->b_dmah, NULL, bp->b_kaddr, 1249 len, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, 1250 &bp->b_dmac, &ccount) != DDI_DMA_MAPPED) { 1251 efe_error(dip, "unable to bind DMA handle to buffer!"); 1252 goto failure; 1253 } 1254 1255 return (bp); 1256 1257 failure: 1258 efe_buf_free(&bp); 1259 1260 return (NULL); 1261 } 1262 1263 void 1264 efe_buf_free(efe_buf_t **bpp) 1265 { 1266 efe_buf_t *bp = *bpp; 1267 1268 ASSERT(bp != NULL); 1269 1270 if (bp->b_kaddr != NULL) { 1271 (void) ddi_dma_unbind_handle(bp->b_dmah); 1272 } 1273 if (bp->b_acch != NULL) { 1274 ddi_dma_mem_free(&bp->b_acch); 1275 } 1276 if (bp->b_dmah != NULL) { 1277 ddi_dma_free_handle(&bp->b_dmah); 1278 } 1279 kmem_free(bp, sizeof (efe_buf_t)); 1280 1281 *bpp = NULL; 1282 } 1283 1284 void 1285 efe_intr_enable(efe_t *efep) 1286 { 1287 PUTCSR(efep, CSR_INTMASK, 1288 INTMASK_RCC | INTMASK_RQE | INTMASK_TXC | INTMASK_FATAL); 1289 1290 SETBIT(efep, CSR_GENCTL, GENCTL_INT); 1291 } 1292 1293 void 1294 efe_intr_disable(efe_t *efep) 1295 { 1296 PUTCSR(efep, CSR_INTMASK, 0); 1297 1298 CLRBIT(efep, CSR_GENCTL, GENCTL_INT); 1299 } 1300 1301 mblk_t * 1302 efe_recv(efe_t *efep) 1303 { 1304 efe_ring_t *rp; 1305 mblk_t *mp = NULL; 1306 mblk_t **mpp = ∓ 1307 1308 ASSERT(mutex_owned(&efep->efe_intrlock)); 1309 1310 rp = efep->efe_rx_ring; 1311 1312 for (;;) { 1313 efe_desc_t *dp; 1314 uint16_t status; 1315 1316 dp = GETDESC(rp, efep->efe_rx_desc); 1317 SYNCDESC(rp, efep->efe_rx_desc, DDI_DMA_SYNC_FORKERNEL); 1318 1319 status = GETDESC16(rp, &dp->d_status); 1320 1321 /* Stop if device owns descriptor */ 1322 if (status & RXSTAT_OWNER) { 1323 break; 1324 } 1325 1326 if (status & RXSTAT_PRI) { 1327 mblk_t *tmp = efe_recv_pkt(efep, dp); 1328 if (tmp != NULL) { 1329 *mpp = tmp; 1330 mpp = &tmp->b_next; 1331 } 1332 1333 } else { 1334 efep->efe_ierrors++; 1335 1336 if (status & RXSTAT_FAE) { 1337 efep->efe_align_errors++; 1338 } 1339 if (status & RXSTAT_CRC) { 1340 efep->efe_fcs_errors++; 1341 } 1342 if (status & RXSTAT_MP) { 1343 efep->efe_oflo++; 1344 } 1345 } 1346 1347 /* Release ownership to device */ 1348 PUTDESC16(rp, &dp->d_status, RXSTAT_OWNER); 1349 1350 SYNCDESC(rp, efep->efe_rx_desc, DDI_DMA_SYNC_FORDEV); 1351 1352 efep->efe_rx_desc = NEXTDESC(rp, efep->efe_rx_desc); 1353 } 1354 1355 return (mp); 1356 } 1357 1358 mblk_t * 1359 efe_recv_pkt(efe_t *efep, efe_desc_t *dp) 1360 { 1361 efe_ring_t *rp; 1362 efe_buf_t *bp; 1363 uint16_t len; 1364 mblk_t *mp; 1365 uint16_t status; 1366 1367 ASSERT(mutex_owned(&efep->efe_intrlock)); 1368 1369 rp = efep->efe_rx_ring; 1370 1371 len = GETDESC16(rp, &dp->d_len) - ETHERFCSL; 1372 1373 if (len < ETHERMIN) { 1374 efep->efe_ierrors++; 1375 efep->efe_runt_errors++; 1376 return (NULL); 1377 } 1378 1379 if (len > ETHERMAX + VLAN_TAGSZ) { 1380 efep->efe_ierrors++; 1381 efep->efe_toolong_errors++; 1382 return (NULL); 1383 } 1384 1385 mp = allocb(len, 0); 1386 if (mp == NULL) { 1387 efep->efe_ierrors++; 1388 efep->efe_norcvbuf++; 1389 return (NULL); 1390 } 1391 mp->b_wptr = mp->b_rptr + len; 1392 1393 bp = GETBUF(rp, efep->efe_rx_desc); 1394 SYNCBUF(bp, DDI_DMA_SYNC_FORKERNEL); 1395 1396 bcopy(bp->b_kaddr, mp->b_rptr, len); 1397 1398 efep->efe_ipackets++; 1399 efep->efe_rbytes += len; 1400 1401 status = GETDESC16(rp, &dp->d_status); 1402 1403 if (status & RXSTAT_BAR) { 1404 efep->efe_brdcstrcv++; 1405 1406 } else if (status & RXSTAT_MAR) { 1407 efep->efe_multircv++; 1408 } 1409 1410 return (mp); 1411 } 1412 1413 int 1414 efe_send(efe_t *efep, mblk_t *mp) 1415 { 1416 efe_ring_t *rp; 1417 uint16_t len; 1418 efe_desc_t *dp; 1419 uint16_t status; 1420 efe_buf_t *bp; 1421 1422 ASSERT(mutex_owned(&efep->efe_txlock)); 1423 1424 rp = efep->efe_tx_ring; 1425 1426 len = msgsize(mp); 1427 1428 if (len > ETHERMAX + VLAN_TAGSZ) { 1429 efep->efe_oerrors++; 1430 efep->efe_macxmt_errors++; 1431 freemsg(mp); 1432 return (DDI_SUCCESS); 1433 } 1434 1435 dp = GETDESC(rp, efep->efe_tx_desc); 1436 SYNCDESC(rp, efep->efe_tx_desc, DDI_DMA_SYNC_FORKERNEL); 1437 1438 status = GETDESC16(efep->efe_tx_ring, &dp->d_status); 1439 1440 /* Stop if device owns descriptor */ 1441 if (status & TXSTAT_OWNER) { 1442 return (DDI_FAILURE); 1443 } 1444 1445 bp = GETBUF(rp, efep->efe_tx_desc); 1446 1447 mcopymsg(mp, bp->b_kaddr); 1448 1449 /* 1450 * Packets must contain at least ETHERMIN octets. 1451 * Padded octets are zeroed out prior to sending. 1452 */ 1453 if (len < ETHERMIN) { 1454 bzero(bp->b_kaddr + len, ETHERMIN - len); 1455 len = ETHERMIN; 1456 } 1457 1458 SYNCBUF(bp, DDI_DMA_SYNC_FORDEV); 1459 1460 PUTDESC16(rp, &dp->d_status, TXSTAT_OWNER); 1461 PUTDESC16(rp, &dp->d_len, len); 1462 PUTDESC16(rp, &dp->d_control, TXCTL_LASTDESCR); 1463 1464 SYNCDESC(rp, efep->efe_tx_desc, DDI_DMA_SYNC_FORDEV); 1465 1466 efep->efe_opackets++; 1467 efep->efe_obytes += len; 1468 1469 if (*bp->b_kaddr & 0x01) { 1470 if (bcmp(bp->b_kaddr, efe_broadcast, ETHERADDRL) == 0) { 1471 efep->efe_brdcstxmt++; 1472 } else { 1473 efep->efe_multixmt++; 1474 } 1475 } 1476 1477 efep->efe_tx_desc = NEXTDESC(rp, efep->efe_tx_desc); 1478 1479 return (DDI_SUCCESS); 1480 } 1481 1482 void 1483 efe_send_done(efe_t *efep) 1484 { 1485 efe_ring_t *rp; 1486 1487 ASSERT(mutex_owned(&efep->efe_txlock)); 1488 1489 rp = efep->efe_tx_ring; 1490 1491 for (;;) { 1492 efe_desc_t *dp; 1493 uint16_t status; 1494 1495 dp = GETDESC(rp, efep->efe_tx_sent); 1496 SYNCDESC(rp, efep->efe_tx_sent, DDI_DMA_SYNC_FORKERNEL); 1497 1498 status = GETDESC16(rp, &dp->d_status); 1499 1500 /* Stop if device owns descriptor */ 1501 if (status & TXSTAT_OWNER) { 1502 break; 1503 } 1504 1505 if (status & TXSTAT_PTX) { 1506 if (!(status & TXSTAT_ND)) { 1507 efep->efe_defer_xmts++; 1508 } 1509 if (status & TXSTAT_COLL) { 1510 efep->efe_first_collisions++; 1511 } 1512 1513 } else { 1514 efep->efe_oerrors++; 1515 1516 if (status & TXSTAT_CSL) { 1517 efep->efe_carrier_errors++; 1518 } 1519 if (status & TXSTAT_UFLO) { 1520 efep->efe_uflo++; 1521 } 1522 if (status & TXSTAT_OWC) { 1523 efep->efe_tx_late_collisions++; 1524 } 1525 if (status & TXSTAT_DEFER) { 1526 efep->efe_jabber_errors++; 1527 } 1528 if (status & TXSTAT_EXCOLL) { 1529 efep->efe_ex_collisions++; 1530 } 1531 } 1532 1533 efep->efe_collisions += 1534 (status >> TXSTAT_CCNT) & TXSTAT_CCNTMASK; 1535 1536 efep->efe_tx_sent = NEXTDESC(rp, efep->efe_tx_sent); 1537 } 1538 } 1539 1540 void 1541 efe_getaddr(efe_t *efep, uint8_t *macaddr) 1542 { 1543 efe_eeprom_read(efep, macaddr, ETHERADDRL, 0x0); 1544 1545 efe_debug(efep->efe_dip, 1546 "factory address is %02x:%02x:%02x:%02x:%02x:%02x\n", 1547 macaddr[0], macaddr[1], macaddr[2], macaddr[3], 1548 macaddr[4], macaddr[5]); 1549 } 1550 1551 void 1552 efe_setaddr(efe_t *efep, uint8_t *macaddr) 1553 { 1554 uint16_t val; 1555 1556 bcopy(macaddr, &val, sizeof (uint16_t)); 1557 PUTCSR(efep, CSR_LAN0, val); 1558 macaddr += sizeof (uint16_t); 1559 1560 bcopy(macaddr, &val, sizeof (uint16_t)); 1561 PUTCSR(efep, CSR_LAN1, val); 1562 macaddr += sizeof (uint16_t); 1563 1564 bcopy(macaddr, &val, sizeof (uint16_t)); 1565 PUTCSR(efep, CSR_LAN2, val); 1566 } 1567 1568 void 1569 efe_setmchash(efe_t *efep, uint16_t *mchash) 1570 { 1571 PUTCSR(efep, CSR_MC0, mchash[0]); 1572 PUTCSR(efep, CSR_MC1, mchash[1]); 1573 PUTCSR(efep, CSR_MC2, mchash[2]); 1574 PUTCSR(efep, CSR_MC3, mchash[3]); 1575 } 1576 1577 void 1578 efe_eeprom_read(efe_t *efep, uint8_t *buf, size_t len, uint8_t addr) 1579 { 1580 int addrlen; 1581 1582 ASSERT(len & ~0x1); /* non-zero; word-aligned */ 1583 1584 PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS); 1585 drv_usecwait(EEPROM_DELAY); 1586 1587 addrlen = (GETCSR(efep, CSR_EECTL) & EECTL_SIZE ? 1588 AT93C46_ADDRLEN : AT93C56_ADDRLEN); 1589 1590 for (int i = 0; i < len / sizeof (uint16_t); ++i) { 1591 uint16_t val = efe_eeprom_readw(efep, addrlen, addr + i); 1592 bcopy(&val, buf, sizeof (uint16_t)); 1593 buf += sizeof (uint16_t); 1594 } 1595 } 1596 1597 uint16_t 1598 efe_eeprom_readw(efe_t *efep, int addrlen, uint8_t addr) 1599 { 1600 uint16_t val = 0; 1601 1602 ASSERT(addrlen > 0); 1603 1604 /* Write Start Bit (SB) */ 1605 efe_eeprom_writebit(efep, 1); 1606 1607 /* Write READ instruction */ 1608 efe_eeprom_writebit(efep, 1); 1609 efe_eeprom_writebit(efep, 0); 1610 1611 /* Write EEPROM address */ 1612 for (int i = addrlen - 1; i >= 0; --i) { 1613 efe_eeprom_writebit(efep, addr & 1U << i); 1614 } 1615 1616 /* Read EEPROM word */ 1617 for (int i = EEPROM_WORDSZ - 1; i >= 0; --i) { 1618 val |= efe_eeprom_readbit(efep) << i; 1619 } 1620 1621 PUTCSR(efep, CSR_EECTL, EECTL_ENABLE); 1622 drv_usecwait(EEPROM_DELAY); 1623 1624 return (val); 1625 } 1626 1627 inline int 1628 efe_eeprom_readbit(efe_t *efep) 1629 { 1630 PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS); 1631 drv_usecwait(EEPROM_DELAY); 1632 1633 PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS | 1634 EECTL_EESK); 1635 drv_usecwait(EEPROM_DELAY); 1636 1637 PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS); 1638 drv_usecwait(EEPROM_DELAY); 1639 1640 return (!!(GETCSR(efep, CSR_EECTL) & EECTL_EEDO)); 1641 } 1642 1643 inline void 1644 efe_eeprom_writebit(efe_t *efep, int bit) 1645 { 1646 PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS); 1647 drv_usecwait(EEPROM_DELAY); 1648 1649 PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS | 1650 EECTL_EESK | (bit ? EECTL_EEDI : 0)); 1651 drv_usecwait(EEPROM_DELAY); 1652 1653 PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS); 1654 drv_usecwait(EEPROM_DELAY); 1655 } 1656 1657 void 1658 efe_dprintf(dev_info_t *dip, int level, const char *format, ...) 1659 { 1660 va_list ap; 1661 char buf[255]; 1662 1663 va_start(ap, format); 1664 1665 (void) vsnprintf(buf, sizeof (buf), format, ap); 1666 1667 cmn_err(level, "?%s%d %s", ddi_driver_name(dip), 1668 ddi_get_instance(dip), buf); 1669 1670 va_end(ap); 1671 } 1672