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