1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_DMFE_IMPL_H 27 #define _SYS_DMFE_IMPL_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <sys/types.h> 36 #include <sys/stream.h> 37 #include <sys/strsun.h> 38 #include <sys/stat.h> 39 #include <sys/pci.h> 40 #include <sys/note.h> 41 #include <sys/modctl.h> 42 #include <sys/kstat.h> 43 #include <sys/ethernet.h> 44 #include <sys/devops.h> 45 #include <sys/debug.h> 46 #include <sys/conf.h> 47 48 #include <inet/common.h> 49 #include <inet/nd.h> 50 #include <inet/mi.h> 51 52 #include <sys/vlan.h> 53 54 #include <sys/dditypes.h> 55 #include <sys/ddi.h> 56 #include <sys/sunddi.h> 57 58 #include <sys/miiregs.h> 59 #include <sys/dmfe.h> 60 #include <sys/mac.h> 61 #include <sys/mac_ether.h> 62 63 #define DMFE_MAX_PKT_SIZE (VLAN_TAGSZ + ETHERMAX + ETHERFCSL) 64 65 66 #define DRIVER_NAME "dmfe" 67 68 /* 69 * Describes the identity of a specific chip 70 */ 71 typedef struct { 72 uint16_t vendor; 73 uint16_t device; 74 uint8_t revision; 75 uint8_t spare; 76 } chip_id_t; 77 78 /* 79 * Describes the state of a descriptor ring 80 * 81 * NOTE: n_free and next_busy are only used for the Tx descriptors 82 * and are not valid on the receive side. 83 */ 84 typedef struct { 85 uint32_t n_desc; /* # of descriptors */ 86 uint32_t n_free; /* # of free descriptors */ 87 uint32_t next_free; /* next index to use/check */ 88 uint32_t next_busy; /* next index to reclaim */ 89 } desc_state_t; 90 91 /* 92 * Describes one chunk of allocated DMA-able memory 93 */ 94 typedef struct { 95 ddi_dma_handle_t dma_hdl; 96 ddi_acc_handle_t acc_hdl; 97 size_t alength; /* allocated size */ 98 caddr_t mem_va; /* CPU VA of memory */ 99 uint32_t spare1; 100 uint32_t mem_dvma; /* DVMA addr of memory */ 101 caddr_t setup_va; 102 uint32_t spare2; 103 uint32_t setup_dvma; 104 int spare3; 105 int ncookies; 106 } dma_area_t; 107 108 /* 109 * Named Data (ND) Parameter Management Structure 110 */ 111 typedef struct { 112 uint32_t ndp_info; 113 uint32_t ndp_min; 114 uint32_t ndp_max; 115 uint32_t ndp_val; 116 char *ndp_name; 117 } nd_param_t; 118 119 /* 120 * NDD parameter indexes, divided into: 121 * 122 * read-only parameters describing the link state 123 * read-write parameters controlling the advertised link capabilities 124 * read-only parameters describing the device link capabilities 125 * read-only parameters describing the link-partner's link capabilities 126 */ 127 enum { 128 PARAM_LINK_STATUS, 129 PARAM_LINK_SPEED, 130 PARAM_LINK_MODE, 131 132 PARAM_ADV_AUTONEG_CAP, 133 PARAM_ADV_100T4_CAP, 134 PARAM_ADV_100FDX_CAP, 135 PARAM_ADV_100HDX_CAP, 136 PARAM_ADV_10FDX_CAP, 137 PARAM_ADV_10HDX_CAP, 138 PARAM_ADV_REMFAULT, 139 140 PARAM_BMSR_AUTONEG_CAP, 141 PARAM_BMSR_100T4_CAP, 142 PARAM_BMSR_100FDX_CAP, 143 PARAM_BMSR_100HDX_CAP, 144 PARAM_BMSR_10FDX_CAP, 145 PARAM_BMSR_10HDX_CAP, 146 PARAM_BMSR_REMFAULT, 147 148 PARAM_LP_AUTONEG_CAP, 149 PARAM_LP_100T4_CAP, 150 PARAM_LP_100FDX_CAP, 151 PARAM_LP_100HDX_CAP, 152 PARAM_LP_10FDX_CAP, 153 PARAM_LP_10HDX_CAP, 154 PARAM_LP_REMFAULT, 155 156 PARAM_COUNT 157 }; 158 159 /* 160 * Indexes into the driver-specific kstats, divided into: 161 * 162 * cyclic activity 163 * reasons for waking the factotum 164 * the factotum's activities 165 * link state updates 166 * MII-level register values 167 */ 168 enum { 169 KS_CYCLIC_RUN, 170 171 KS_TICK_LINK_STATE, 172 KS_TICK_LINK_POLL, 173 KS_INTERRUPT, 174 KS_TX_STALL, 175 KS_CHIP_ERROR, 176 177 KS_FACTOTUM_RUN, 178 KS_RECOVERY, 179 KS_LINK_CHECK, 180 181 KS_LINK_UP_CNT, 182 KS_LINK_DROP_CNT, 183 184 KS_MIIREG_BMSR, 185 KS_MIIREG_ANAR, 186 KS_MIIREG_ANLPAR, 187 KS_MIIREG_ANER, 188 KS_MIIREG_DSCSR, 189 190 KS_DRV_COUNT 191 }; 192 193 /* 194 * Actual state of the DM9102A chip 195 */ 196 enum chip_state { 197 CHIP_ERROR = -1, /* error, need reset */ 198 CHIP_UNKNOWN, /* Initial state only */ 199 CHIP_RESET, /* reset, need init */ 200 CHIP_STOPPED, /* Tx/Rx stopped */ 201 CHIP_TX_ONLY, /* Tx (re)started */ 202 CHIP_TX_RX, /* Tx & Rx (re)started */ 203 CHIP_RUNNING /* with interrupts */ 204 }; 205 206 /* 207 * Required state according to MAC 208 */ 209 enum mac_state { 210 DMFE_MAC_UNKNOWN, 211 DMFE_MAC_RESET, 212 DMFE_MAC_STOPPED, 213 DMFE_MAC_STARTED 214 }; 215 216 /* 217 * (Internal) return values from ioctl subroutines 218 */ 219 enum ioc_reply { 220 IOC_INVAL = -1, /* bad, NAK with EINVAL */ 221 IOC_DONE, /* OK, reply sent */ 222 IOC_REPLY, /* OK, just send reply */ 223 IOC_ACK, /* OK, just send ACK */ 224 IOC_RESTART, /* OK, restart & reply */ 225 IOC_RESTART_ACK /* OK, restart & ACK */ 226 }; 227 228 /* 229 * Per-instance soft-state structure 230 */ 231 typedef struct { 232 /* 233 * These fields are set by attach() and unchanged thereafter ... 234 */ 235 dev_info_t *devinfo; /* device instance */ 236 mac_handle_t mh; /* MAC instance data */ 237 ddi_acc_handle_t io_handle; /* DDI I/O handle */ 238 caddr_t io_reg; /* mapped registers */ 239 240 uint32_t debug; /* per-instance debug */ 241 uint32_t progress; /* attach tracking */ 242 chip_id_t chipid; 243 uint8_t vendor_addr[ETHERADDRL]; 244 char ifname[12]; /* "dmfeXXXX" */ 245 246 dma_area_t tx_desc; /* transmit descriptors */ 247 dma_area_t tx_buff; /* transmit buffers */ 248 dma_area_t rx_desc; /* receive descriptors */ 249 dma_area_t rx_buff; /* receive buffers */ 250 251 ddi_periodic_t cycid; /* periodical callback */ 252 ddi_softintr_t factotum_id; /* identity of factotum */ 253 ddi_iblock_cookie_t iblk; 254 255 /* 256 * Locks: 257 * 258 * <milock> is used only by the MII (PHY) level code, to ensure 259 * exclusive access during the bit-twiddling needed to send 260 * signals along the MII serial bus. These operations are 261 * --S--L--O--W-- so we keep this lock separate, so that 262 * faster operations (e.g. interrupts) aren't delayed by 263 * waiting for it. 264 * 265 * <oplock> is a general "outer" lock, protecting most r/w data 266 * and chip state. It is also acquired by the interrupt 267 * handler. 268 * 269 * <rxlock> is used to protect the Rx-side buffers, descriptors, 270 * and statistics during a single call to dmfe_getp(). 271 * This is called from inside the interrupt handler, but 272 * <oplock> is not held across this call. 273 * 274 * <txlock> is an "inner" lock, and protects only the Tx-side 275 * data below and in the ring buffers/descriptors. The 276 * Tx-side code uses only this lock, avoiding contention 277 * with the receive-side code. 278 * 279 * Any of the locks can be acquired singly, but where multiple 280 * locks are acquired, they *must* be in the order: 281 * 282 * milock >>> oplock >>> rxlock >>> txlock. 283 * 284 * *None* of these locks may be held across calls out to the 285 * MAC routines mac_rx() or mac_tx_notify(); MAC locks must 286 * be regarded as *outermost* locks in all cases, as they will 287 * already be held before calling the ioctl() or get_stats() 288 * entry points - which then have to acquire multiple locks, in 289 * the order described here. 290 */ 291 kmutex_t milock[1]; 292 kmutex_t oplock[1]; 293 kmutex_t rxlock[1]; 294 kmutex_t txlock[1]; 295 296 /* 297 * DMFE Extended kstats, protected by <oplock> 298 */ 299 kstat_t *ksp_drv; 300 kstat_named_t *knp_drv; 301 302 /* 303 * GLD statistics; the prefix tells which lock each is protected by. 304 */ 305 uint64_t op_stats_speed; 306 uint64_t op_stats_duplex; 307 308 uint64_t rx_stats_ipackets; 309 uint64_t rx_stats_multi; 310 uint64_t rx_stats_bcast; 311 uint64_t rx_stats_ierrors; 312 uint64_t rx_stats_norcvbuf; 313 uint64_t rx_stats_rbytes; 314 uint64_t rx_stats_missed; 315 uint64_t rx_stats_align; 316 uint64_t rx_stats_fcs; 317 uint64_t rx_stats_toolong; 318 uint64_t rx_stats_macrcv_errors; 319 uint64_t rx_stats_overflow; 320 uint64_t rx_stats_short; 321 322 uint64_t tx_stats_oerrors; 323 uint64_t tx_stats_opackets; 324 uint64_t tx_stats_multi; 325 uint64_t tx_stats_bcast; 326 uint64_t tx_stats_obytes; 327 uint64_t tx_stats_collisions; 328 uint64_t tx_stats_nocarrier; 329 uint64_t tx_stats_xmtlatecoll; 330 uint64_t tx_stats_excoll; 331 uint64_t tx_stats_macxmt_errors; 332 uint64_t tx_stats_jabber; 333 uint64_t tx_stats_defer; 334 uint64_t tx_stats_first_coll; 335 uint64_t tx_stats_multi_coll; 336 uint64_t tx_stats_underflow; 337 338 /* 339 * These two sets of desciptors are manipulated during 340 * packet receive/transmit respectively. 341 */ 342 desc_state_t rx; /* describes Rx ring */ 343 desc_state_t tx; /* describes Tx ring */ 344 345 /* 346 * Miscellaneous Tx-side variables (protected by txlock) 347 */ 348 uint32_t tx_pending_tix; /* tix since reclaim */ 349 uint8_t *tx_mcast; /* bitmask: pkt is mcast */ 350 uint8_t *tx_bcast; /* bitmask: pkt is bcast */ 351 352 /* 353 * Miscellaneous operating variables (protected by oplock) 354 */ 355 uint32_t link_poll_tix; /* tix until link poll */ 356 uint16_t factotum_flag; /* callback pending */ 357 uint16_t need_setup; /* send-setup pending */ 358 uint32_t opmode; /* operating mode shadow */ 359 uint32_t imask; /* interrupt mask shadow */ 360 enum mac_state mac_state; /* RESET/STOPPED/STARTED */ 361 enum chip_state chip_state; /* see above */ 362 363 /* 364 * Physical link state data (protected by oplock) 365 */ 366 link_state_t link_state; /* See above */ 367 368 /* 369 * PHYceiver state data (protected by milock) 370 */ 371 int phy_inuse; 372 int phy_addr; /* should be -1! */ 373 uint16_t phy_control; /* last value written */ 374 uint16_t phy_anar_w; /* last value written */ 375 uint16_t phy_anar_r; /* latest value read */ 376 uint16_t phy_anlpar; /* latest value read */ 377 uint16_t phy_aner; 378 uint16_t phy_dscsr; /* latest value read */ 379 uint16_t phy_bmsr; /* latest value read */ 380 uint16_t rsvd; /* reserved for future use */ 381 uint32_t phy_bmsr_lbolt; /* time of BMSR change */ 382 uint32_t phy_id; /* vendor+device (OUI) */ 383 384 /* 385 * Current Ethernet address & multicast map ... 386 */ 387 uint8_t curr_addr[ETHERADDRL]; 388 uint8_t mcast_refs[MCASTBUF_SIZE]; 389 boolean_t addr_set; 390 boolean_t update_phy; /* Need to update_phy? */ 391 392 /* 393 * NDD parameters 394 */ 395 caddr_t nd_data_p; 396 nd_param_t nd_params[PARAM_COUNT]; 397 398 /* 399 * Guard element used to check data integrity 400 */ 401 uint64_t dmfe_guard; 402 } dmfe_t; 403 404 /* 405 * 'Progress' bit flags ... 406 */ 407 #define PROGRESS_CONFIG 0x0001 /* config space initialised */ 408 #define PROGRESS_NDD 0x0002 /* NDD parameters set up */ 409 #define PROGRESS_REGS 0x0004 /* registers mapped */ 410 #define PROGRESS_BUFS 0x0008 /* buffers allocated */ 411 #define PROGRESS_SOFTINT 0x0010 /* softint registered */ 412 #define PROGRESS_HWINT 0x0020 /* h/w interrupt registered */ 413 414 /* 415 * Type of transceiver currently in use 416 */ 417 #define PHY_TYPE_UNDEFINED 0 418 #define PHY_TYPE_10BASE_MNCHSTR 2 419 #define PHY_TYPE_100BASE_X 4 420 421 /* 422 * Shorthand for the NDD parameters 423 */ 424 #define param_linkup nd_params[PARAM_LINK_STATUS].ndp_val 425 #define param_speed nd_params[PARAM_LINK_SPEED].ndp_val 426 #define param_duplex nd_params[PARAM_LINK_MODE].ndp_val 427 #define param_autoneg nd_params[PARAM_ADV_AUTONEG_CAP].ndp_val 428 #define param_anar_100T4 nd_params[PARAM_ADV_100T4_CAP].ndp_val 429 #define param_anar_100fdx nd_params[PARAM_ADV_100FDX_CAP].ndp_val 430 #define param_anar_100hdx nd_params[PARAM_ADV_100HDX_CAP].ndp_val 431 #define param_anar_10fdx nd_params[PARAM_ADV_10FDX_CAP].ndp_val 432 #define param_anar_10hdx nd_params[PARAM_ADV_10HDX_CAP].ndp_val 433 #define param_anar_remfault nd_params[PARAM_ADV_REMFAULT].ndp_val 434 #define param_bmsr_autoneg nd_params[PARAM_BMSR_AUTONEG_CAP].ndp_val 435 #define param_bmsr_100T4 nd_params[PARAM_BMSR_100T4_CAP].ndp_val 436 #define param_bmsr_100fdx nd_params[PARAM_BMSR_100FDX_CAP].ndp_val 437 #define param_bmsr_100hdx nd_params[PARAM_BMSR_100HDX_CAP].ndp_val 438 #define param_bmsr_10fdx nd_params[PARAM_BMSR_10FDX_CAP].ndp_val 439 #define param_bmsr_10hdx nd_params[PARAM_BMSR_10HDX_CAP].ndp_val 440 #define param_bmsr_remfault nd_params[PARAM_BMSR_REMFAULT].ndp_val 441 #define param_lp_autoneg nd_params[PARAM_LP_AUTONEG_CAP].ndp_val 442 #define param_lp_100T4 nd_params[PARAM_LP_100T4_CAP].ndp_val 443 #define param_lp_100fdx nd_params[PARAM_LP_100FDX_CAP].ndp_val 444 #define param_lp_100hdx nd_params[PARAM_LP_100HDX_CAP].ndp_val 445 #define param_lp_10fdx nd_params[PARAM_LP_10FDX_CAP].ndp_val 446 #define param_lp_10hdx nd_params[PARAM_LP_10HDX_CAP].ndp_val 447 #define param_lp_remfault nd_params[PARAM_LP_REMFAULT].ndp_val 448 449 /* 450 * Sync a DMA area described by a dma_area_t 451 */ 452 #define DMA_SYNC(descp, flag) ((void) ddi_dma_sync((descp)->dma_hdl, \ 453 0, (descp)->alength, flag)) 454 455 /* 456 * Next value of a cyclic index 457 */ 458 #define NEXT(index, limit) ((index)+1 < (limit) ? (index)+1 : 0); 459 460 /* 461 * Utility Macros 462 */ 463 #define U32TOPTR(x) ((void *)(uintptr_t)(uint32_t)(x)) 464 #define PTRTOU32(x) ((uint32_t)(uintptr_t)(void *)(x)) 465 466 /* 467 * Copy an ethernet address 468 */ 469 #define ethaddr_copy(src, dst) bcopy((src), (dst), ETHERADDRL) 470 #define MII_KS_GET(dmfep, id) \ 471 (((dmfep)->knp_mii) ? ((dmfep)->knp_mii)[id].value.ui32 : 0) 472 473 #define MII_KS_SET(dmfep, id, val) \ 474 do { \ 475 if ((dmfep)->knp_mii != NULL) \ 476 ((dmfep)->knp_mii)[id].value.ui32 = (val); \ 477 _NOTE(CONSTANTCONDITION) \ 478 } while (0) 479 480 #define MII_KS_INC(dmfep, id) \ 481 do { \ 482 if ((dmfep)->knp_mii != NULL) \ 483 ((dmfep)->knp_mii)[id].value.ui32 += 1; \ 484 _NOTE(CONSTANTCONDITION) \ 485 } while (0) 486 487 /* 488 * Get/set/increment a (64-bit) driver-private kstat 489 */ 490 #define DRV_KS_GET(dmfep, id) \ 491 (((dmfep)->knp_drv) ? ((dmfep)->knp_drv)[id].value.ui64 : 0) 492 493 #define DRV_KS_SET(dmfep, id, val) \ 494 do { \ 495 if ((dmfep)->knp_drv) \ 496 ((dmfep)->knp_drv)[id].value.ui64 = (val); \ 497 _NOTE(CONSTANTCONDITION) \ 498 } while (0) 499 500 #define DRV_KS_INC(dmfep, id) \ 501 do { \ 502 if ((dmfep)->knp_drv) \ 503 ((dmfep)->knp_drv)[id].value.ui64 += 1; \ 504 _NOTE(CONSTANTCONDITION) \ 505 } while (0) 506 507 /* 508 * Bit test macros, returning boolean_t values 509 */ 510 #define BIS(w, b) ((w) & (b)) 511 #define BIC(w, b) !BIS(w, b) 512 513 #define DMFE_GUARD 0x1919603003090218 514 515 /* 516 * 'Debug' bit flags ... 517 */ 518 #define DMFE_DBG_TRACE 0x0001 /* general flow tracing */ 519 #define DMFE_DBG_REGS 0x0002 /* low-level accesses */ 520 #define DMFE_DBG_RECV 0x0004 /* receive-side code */ 521 #define DMFE_DBG_SEND 0x0008 /* packet-send code */ 522 #define DMFE_DBG_ADDR 0x0010 /* address-setting code */ 523 #define DMFE_DBG_GLD 0x0020 /* GLD entry points */ 524 #define DMFE_DBG_FACT 0x0040 /* factotum (softint) */ 525 #define DMFE_DBG_TICK 0x0080 /* GPT ticker */ 526 #define DMFE_DBG_INT 0x0100 /* interrupt handler */ 527 #define DMFE_DBG_STATS 0x0200 /* statistics */ 528 #define DMFE_DBG_IOCTL 0x0400 /* ioctl/loopback code */ 529 #define DMFE_DBG_INIT 0x0800 /* initialisation */ 530 #define DMFE_DBG_MII 0x1000 /* low-level MII/PHY */ 531 #define DMFE_DBG_LINK 0x2000 /* Link status check */ 532 #define DMFE_DBG_NDD 0x4000 /* NDD parameters */ 533 534 /* 535 * Debugging ... 536 */ 537 #if defined(DEBUG) || defined(lint) 538 #define DMFEDEBUG 1 539 #else 540 #define DMFEDEBUG 0 541 #endif 542 543 #if DMFEDEBUG 544 545 extern uint32_t dmfe_debug; 546 extern void (*dmfe_gdb())(const char *fmt, ...); 547 extern void (*dmfe_db(dmfe_t *dmfep))(const char *fmt, ...); 548 549 /* 550 * Define DMFE_DBG to be the relevant flag from the set above before 551 * using the DMFE_GDEBUG() or DMFE_DEBUG() macros. The 'G' versions 552 * look at the Global debug flag word (dmfe_debug); the non-G versions 553 * look in the per-instance data (dmfep->debug) and so require a variable 554 * called 'dmfep' to be in scope (and initialised!) 555 * 556 * You could redefine DMFE_TRC too if you really need two different 557 * flavours of debugging output in the same area of code, but I don't 558 * really recommend it. 559 */ 560 561 #define DMFE_TRC DMFE_DBG_TRACE /* default 'trace' bit */ 562 563 #define DMFE_GDEBUG(args) do { \ 564 if (dmfe_debug & (DMFE_DBG)) \ 565 (*dmfe_gdb()) args; \ 566 _NOTE(CONSTANTCONDITION) \ 567 } while (0) 568 569 #define DMFE_GTRACE(args) do { \ 570 if (dmfe_debug & (DMFE_TRC)) \ 571 (*dmfe_gdb()) args; \ 572 _NOTE(CONSTANTCONDITION) \ 573 } while (0) 574 575 #define DMFE_DEBUG(args) do { \ 576 if (dmfep->debug & (DMFE_DBG)) \ 577 (*dmfe_db(dmfep)) args; \ 578 _NOTE(CONSTANTCONDITION) \ 579 } while (0) 580 581 #define DMFE_TRACE(args) do { \ 582 if (dmfep->debug & (DMFE_TRC)) \ 583 (*dmfe_db(dmfep)) args; \ 584 _NOTE(CONSTANTCONDITION) \ 585 } while (0) 586 587 #else 588 589 #define DMFE_DEBUG(args) do ; _NOTE(CONSTANTCONDITION) while (0) 590 #define DMFE_TRACE(args) do ; _NOTE(CONSTANTCONDITION) while (0) 591 #define DMFE_GDEBUG(args) do ; _NOTE(CONSTANTCONDITION) while (0) 592 #define DMFE_GTRACE(args) do ; _NOTE(CONSTANTCONDITION) while (0) 593 594 #endif /* DMFEDEBUG */ 595 596 597 /* 598 * Inter-source-file linkage ... 599 */ 600 601 /* dmfe_log.c */ 602 void dmfe_warning(dmfe_t *dmfep, const char *fmt, ...); 603 void dmfe_error(dmfe_t *dmfep, const char *fmt, ...); 604 void dmfe_notice(dmfe_t *dmfep, const char *fmt, ...); 605 void dmfe_log(dmfe_t *dmfep, const char *fmt, ...); 606 void dmfe_log_init(void); 607 void dmfe_log_fini(void); 608 609 /* dmfe_main.c */ 610 uint32_t dmfe_chip_get32(dmfe_t *dmfep, off_t offset); 611 void dmfe_chip_put32(dmfe_t *dmfep, off_t offset, uint32_t value); 612 613 /* dmfe_mii.c */ 614 boolean_t dmfe_init_phy(dmfe_t *dmfep); 615 void dmfe_update_phy(dmfe_t *dmfep); 616 boolean_t dmfe_check_link(dmfe_t *dmfep); 617 void dmfe_recheck_link(dmfe_t *dmfep, boolean_t ioctl); 618 619 /* dmfe_ndd.c */ 620 int dmfe_nd_init(dmfe_t *dmfep); 621 enum ioc_reply dmfe_nd_ioctl(dmfe_t *dmfep, queue_t *wq, mblk_t *mp, int cmd); 622 void dmfe_nd_cleanup(dmfe_t *dmfep); 623 624 #ifdef __cplusplus 625 } 626 #endif 627 628 #endif /* _SYS_DMFE_IMPL_H */ 629