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 2008 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 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #include <sys/types.h> 34 #include <sys/stream.h> 35 #include <sys/strsun.h> 36 #include <sys/stat.h> 37 #include <sys/pci.h> 38 #include <sys/note.h> 39 #include <sys/modctl.h> 40 #include <sys/kstat.h> 41 #include <sys/ethernet.h> 42 #include <sys/devops.h> 43 #include <sys/debug.h> 44 #include <sys/conf.h> 45 46 #include <inet/common.h> 47 #include <inet/nd.h> 48 #include <inet/mi.h> 49 50 #include <sys/vlan.h> 51 52 #include <sys/dditypes.h> 53 #include <sys/ddi.h> 54 #include <sys/sunddi.h> 55 56 #include <sys/miiregs.h> 57 #include <sys/mac_provider.h> 58 #include <sys/mac_ether.h> 59 #include "dmfe.h" 60 61 #define DMFE_MAX_PKT_SIZE (VLAN_TAGSZ + ETHERMAX + ETHERFCSL) 62 63 64 #define DRIVER_NAME "dmfe" 65 66 /* 67 * Describes the identity of a specific chip 68 */ 69 typedef struct { 70 uint16_t vendor; 71 uint16_t device; 72 uint8_t revision; 73 uint8_t spare; 74 } chip_id_t; 75 76 /* 77 * Describes the state of a descriptor ring 78 * 79 * NOTE: n_free and next_busy are only used for the Tx descriptors 80 * and are not valid on the receive side. 81 */ 82 typedef struct { 83 uint32_t n_desc; /* # of descriptors */ 84 uint32_t n_free; /* # of free descriptors */ 85 uint32_t next_free; /* next index to use/check */ 86 uint32_t next_busy; /* next index to reclaim */ 87 } desc_state_t; 88 89 /* 90 * Describes one chunk of allocated DMA-able memory 91 */ 92 typedef struct { 93 ddi_dma_handle_t dma_hdl; 94 ddi_acc_handle_t acc_hdl; 95 size_t alength; /* allocated size */ 96 caddr_t mem_va; /* CPU VA of memory */ 97 uint32_t spare1; 98 uint32_t mem_dvma; /* DVMA addr of memory */ 99 caddr_t setup_va; 100 uint32_t spare2; 101 uint32_t setup_dvma; 102 int spare3; 103 int ncookies; 104 } dma_area_t; 105 106 /* 107 * Named Data (ND) Parameter Management Structure 108 */ 109 typedef struct { 110 uint32_t ndp_info; 111 uint32_t ndp_min; 112 uint32_t ndp_max; 113 uint32_t ndp_val; 114 char *ndp_name; 115 struct dmfe *ndp_dmfe; 116 } nd_param_t; 117 118 /* 119 * NDD parameter indexes, divided into: 120 * 121 * read-only parameters describing the link state 122 * read-write parameters controlling the advertised link capabilities 123 * read-only parameters describing the device link capabilities 124 * read-only parameters describing the link-partner's link capabilities 125 */ 126 enum { 127 PARAM_LINK_STATUS, 128 PARAM_LINK_SPEED, 129 PARAM_LINK_MODE, 130 131 PARAM_ADV_AUTONEG_CAP, 132 PARAM_ADV_100T4_CAP, 133 PARAM_ADV_100FDX_CAP, 134 PARAM_ADV_100HDX_CAP, 135 PARAM_ADV_10FDX_CAP, 136 PARAM_ADV_10HDX_CAP, 137 PARAM_ADV_REMFAULT, 138 139 PARAM_BMSR_AUTONEG_CAP, 140 PARAM_BMSR_100T4_CAP, 141 PARAM_BMSR_100FDX_CAP, 142 PARAM_BMSR_100HDX_CAP, 143 PARAM_BMSR_10FDX_CAP, 144 PARAM_BMSR_10HDX_CAP, 145 PARAM_BMSR_REMFAULT, 146 147 PARAM_LP_AUTONEG_CAP, 148 PARAM_LP_100T4_CAP, 149 PARAM_LP_100FDX_CAP, 150 PARAM_LP_100HDX_CAP, 151 PARAM_LP_10FDX_CAP, 152 PARAM_LP_10HDX_CAP, 153 PARAM_LP_REMFAULT, 154 155 PARAM_COUNT 156 }; 157 158 /* 159 * Indexes into the driver-specific kstats, divided into: 160 * 161 * cyclic activity 162 * reasons for waking the factotum 163 * the factotum's activities 164 * link state updates 165 * MII-level register values 166 */ 167 enum { 168 KS_CYCLIC_RUN, 169 170 KS_TICK_LINK_STATE, 171 KS_TICK_LINK_POLL, 172 KS_INTERRUPT, 173 KS_TX_STALL, 174 KS_CHIP_ERROR, 175 176 KS_FACTOTUM_RUN, 177 KS_RECOVERY, 178 KS_LINK_CHECK, 179 180 KS_LINK_UP_CNT, 181 KS_LINK_DROP_CNT, 182 183 KS_MIIREG_BMSR, 184 KS_MIIREG_ANAR, 185 KS_MIIREG_ANLPAR, 186 KS_MIIREG_ANER, 187 KS_MIIREG_DSCSR, 188 189 KS_DRV_COUNT 190 }; 191 192 /* 193 * Actual state of the DM9102A chip 194 */ 195 enum chip_state { 196 CHIP_ERROR = -1, /* error, need reset */ 197 CHIP_UNKNOWN, /* Initial state only */ 198 CHIP_RESET, /* reset, need init */ 199 CHIP_STOPPED, /* Tx/Rx stopped */ 200 CHIP_TX_ONLY, /* Tx (re)started */ 201 CHIP_TX_RX, /* Tx & Rx (re)started */ 202 CHIP_RUNNING /* with interrupts */ 203 }; 204 205 /* 206 * Required state according to MAC 207 */ 208 enum mac_state { 209 DMFE_MAC_UNKNOWN, 210 DMFE_MAC_RESET, 211 DMFE_MAC_STOPPED, 212 DMFE_MAC_STARTED 213 }; 214 215 /* 216 * (Internal) return values from ioctl subroutines 217 */ 218 enum ioc_reply { 219 IOC_INVAL = -1, /* bad, NAK with EINVAL */ 220 IOC_DONE, /* OK, reply sent */ 221 IOC_REPLY, /* OK, just send reply */ 222 IOC_ACK, /* OK, just send ACK */ 223 IOC_RESTART, /* OK, restart & reply */ 224 IOC_RESTART_ACK /* OK, restart & ACK */ 225 }; 226 227 /* 228 * Per-instance soft-state structure 229 */ 230 typedef struct dmfe { 231 /* 232 * These fields are set by attach() and unchanged thereafter ... 233 */ 234 dev_info_t *devinfo; /* device instance */ 235 mac_handle_t mh; /* MAC instance data */ 236 ddi_acc_handle_t io_handle; /* DDI I/O handle */ 237 caddr_t io_reg; /* mapped registers */ 238 239 uint32_t debug; /* per-instance debug */ 240 uint32_t progress; /* attach tracking */ 241 chip_id_t chipid; 242 uint8_t vendor_addr[ETHERADDRL]; 243 char ifname[12]; /* "dmfeXXXX" */ 244 245 dma_area_t tx_desc; /* transmit descriptors */ 246 dma_area_t tx_buff; /* transmit buffers */ 247 dma_area_t rx_desc; /* receive descriptors */ 248 dma_area_t rx_buff; /* receive buffers */ 249 250 ddi_periodic_t cycid; /* periodical callback */ 251 ddi_softintr_t factotum_id; /* identity of factotum */ 252 ddi_iblock_cookie_t iblk; 253 254 /* 255 * Locks: 256 * 257 * <milock> is used only by the MII (PHY) level code, to ensure 258 * exclusive access during the bit-twiddling needed to send 259 * signals along the MII serial bus. These operations are 260 * --S--L--O--W-- so we keep this lock separate, so that 261 * faster operations (e.g. interrupts) aren't delayed by 262 * waiting for it. 263 * 264 * <oplock> is a general "outer" lock, protecting most r/w data 265 * and chip state. It is also acquired by the interrupt 266 * handler. 267 * 268 * <rxlock> is used to protect the Rx-side buffers, descriptors, 269 * and statistics during a single call to dmfe_getp(). 270 * This is called from inside the interrupt handler, but 271 * <oplock> is not held across this call. 272 * 273 * <txlock> is an "inner" lock, and protects only the Tx-side 274 * data below and in the ring buffers/descriptors. The 275 * Tx-side code uses only this lock, avoiding contention 276 * with the receive-side code. 277 * 278 * Any of the locks can be acquired singly, but where multiple 279 * locks are acquired, they *must* be in the order: 280 * 281 * milock >>> oplock >>> rxlock >>> txlock. 282 * 283 * *None* of these locks may be held across calls out to the 284 * MAC routines mac_rx() or mac_tx_notify(); MAC locks must 285 * be regarded as *outermost* locks in all cases, as they will 286 * already be held before calling the ioctl() or get_stats() 287 * entry points - which then have to acquire multiple locks, in 288 * the order described here. 289 */ 290 kmutex_t milock[1]; 291 kmutex_t oplock[1]; 292 kmutex_t rxlock[1]; 293 kmutex_t txlock[1]; 294 295 /* 296 * DMFE Extended kstats, protected by <oplock> 297 */ 298 kstat_t *ksp_drv; 299 kstat_named_t *knp_drv; 300 301 /* 302 * GLD statistics; the prefix tells which lock each is protected by. 303 */ 304 uint64_t op_stats_speed; 305 uint64_t op_stats_duplex; 306 307 uint64_t rx_stats_ipackets; 308 uint64_t rx_stats_multi; 309 uint64_t rx_stats_bcast; 310 uint64_t rx_stats_ierrors; 311 uint64_t rx_stats_norcvbuf; 312 uint64_t rx_stats_rbytes; 313 uint64_t rx_stats_missed; 314 uint64_t rx_stats_align; 315 uint64_t rx_stats_fcs; 316 uint64_t rx_stats_toolong; 317 uint64_t rx_stats_macrcv_errors; 318 uint64_t rx_stats_overflow; 319 uint64_t rx_stats_short; 320 321 uint64_t tx_stats_oerrors; 322 uint64_t tx_stats_opackets; 323 uint64_t tx_stats_multi; 324 uint64_t tx_stats_bcast; 325 uint64_t tx_stats_obytes; 326 uint64_t tx_stats_collisions; 327 uint64_t tx_stats_nocarrier; 328 uint64_t tx_stats_xmtlatecoll; 329 uint64_t tx_stats_excoll; 330 uint64_t tx_stats_macxmt_errors; 331 uint64_t tx_stats_jabber; 332 uint64_t tx_stats_defer; 333 uint64_t tx_stats_first_coll; 334 uint64_t tx_stats_multi_coll; 335 uint64_t tx_stats_underflow; 336 337 /* 338 * These two sets of desciptors are manipulated during 339 * packet receive/transmit respectively. 340 */ 341 desc_state_t rx; /* describes Rx ring */ 342 desc_state_t tx; /* describes Tx ring */ 343 344 /* 345 * Miscellaneous Tx-side variables (protected by txlock) 346 */ 347 uint32_t tx_pending_tix; /* tix since reclaim */ 348 uint8_t *tx_mcast; /* bitmask: pkt is mcast */ 349 uint8_t *tx_bcast; /* bitmask: pkt is bcast */ 350 351 /* 352 * Miscellaneous operating variables (protected by oplock) 353 */ 354 uint32_t link_poll_tix; /* tix until link poll */ 355 uint16_t factotum_flag; /* callback pending */ 356 uint16_t need_setup; /* send-setup pending */ 357 uint32_t opmode; /* operating mode shadow */ 358 uint32_t imask; /* interrupt mask shadow */ 359 enum mac_state mac_state; /* RESET/STOPPED/STARTED */ 360 enum chip_state chip_state; /* see above */ 361 boolean_t link_reset; /* ndd needs link reset */ 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)) != 0) 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 void dmfe_read_eeprom(dmfe_t *dmfep, uint16_t addr, uint8_t *ptr, int cnt); 615 boolean_t dmfe_init_phy(dmfe_t *dmfep); 616 void dmfe_update_phy(dmfe_t *dmfep); 617 boolean_t dmfe_check_link(dmfe_t *dmfep); 618 void dmfe_recheck_link(dmfe_t *dmfep, boolean_t ioctl); 619 620 /* dmfe_ndd.c */ 621 int dmfe_nd_init(dmfe_t *dmfep); 622 enum ioc_reply dmfe_nd_ioctl(dmfe_t *dmfep, queue_t *wq, mblk_t *mp, int cmd); 623 void dmfe_nd_cleanup(dmfe_t *dmfep); 624 625 #ifdef __cplusplus 626 } 627 #endif 628 629 #endif /* _SYS_DMFE_IMPL_H */ 630