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