summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/mac.h
blob: e90df8746c8e2b8aa01dc1e319775429dff42bfd (plain)
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
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
/*
 * 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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 * Copyright 2018 Joyent, Inc.
 * Copyright (c) 2015 Garrett D'Amore <garrett@damore.org>
 * Copyright 2020 RackTop Systems, Inc.
 */

#ifndef	_SYS_MAC_H
#define	_SYS_MAC_H

#include <sys/types.h>
#ifdef	_KERNEL
#include <sys/sunddi.h>
#endif

/*
 * MAC Services Module
 */

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * MAC Information (text emitted by modinfo(1m))
 */
#define	MAC_INFO	"MAC Services"

/*
 * MAC-Type version identifier.  This is used by mactype_alloc() and
 * mactype_register() to verify that incompatible MAC-Type plugins don't
 * register.
 */
#define	MACTYPE_VERSION	0x1

/*
 * Opaque handle types
 */
typedef struct __mac_handle		*mac_handle_t;
typedef struct __mac_resource_handle	*mac_resource_handle_t;
typedef struct __mac_notify_handle	*mac_notify_handle_t;
typedef struct __mac_tx_notify_handle	*mac_tx_notify_handle_t;
typedef	struct __mac_intr_handle	*mac_intr_handle_t;
typedef	struct __mac_ring_handle	*mac_ring_handle_t;
typedef	struct __mac_group_handle	*mac_group_handle_t;

#define	DATALINK_INVALID_LINKID	0
#define	DATALINK_ALL_LINKID	0
#define	DATALINK_MAX_LINKID	0xffffffff

typedef enum {
	LINK_STATE_UNKNOWN = -1,
	LINK_STATE_DOWN,
	LINK_STATE_UP
} link_state_t;

typedef enum {
	LINK_DUPLEX_UNKNOWN = 0,
	LINK_DUPLEX_HALF,
	LINK_DUPLEX_FULL
} link_duplex_t;

typedef enum {
	LINK_FLOWCTRL_NONE = 0,
	LINK_FLOWCTRL_RX,
	LINK_FLOWCTRL_TX,
	LINK_FLOWCTRL_BI
} link_flowctrl_t;

typedef enum {
	LINK_FEC_NONE		= 1 << 0,
	LINK_FEC_AUTO		= 1 << 1,
	LINK_FEC_RS		= 1 << 2,
	LINK_FEC_BASE_R		= 1 << 3
} link_fec_t;

typedef enum {
	LINK_TAGMODE_VLANONLY = 0,
	LINK_TAGMODE_NORMAL
} link_tagmode_t;

/*
 * Defines range of uint32_t values
 */
typedef struct mac_propval_uint32_range_s {
	uint32_t mpur_min;
	uint32_t mpur_max;
} mac_propval_uint32_range_t;

/*
 * Data type of property values.
 */
typedef enum {
	MAC_PROPVAL_UINT8,
	MAC_PROPVAL_UINT32,
	MAC_PROPVAL_STR
} mac_propval_type_t;

/*
 * Captures possible values for a given property. A property can have
 * range of values (int32, int64, uint32, uint64, et al) or collection/
 * enumeration of values (strings).
 * Can be used as a value-result parameter.
 */
typedef struct mac_propval_range_s {
	uint_t mpr_count;			/* count of ranges */
	mac_propval_type_t mpr_type;		/* type of value */
	union {
		mac_propval_uint32_range_t mpr_uint32[1];
	} u;
} mac_propval_range_t;

#define	mpr_range_uint32	u.mpr_uint32

/*
 * Maximum MAC address length
 */
#define	MAXMACADDRLEN		20

#define	MPT_MAXMACADDR		32

typedef struct mac_secondary_addr_s {
	uint32_t	ms_addrcnt;
	uint8_t		ms_addrs[MPT_MAXMACADDR][MAXMACADDRLEN];
} mac_secondary_addr_t;

typedef enum {
	MAC_LOGTYPE_LINK = 1,
	MAC_LOGTYPE_FLOW
} mac_logtype_t;

#define	MAXLINKPROPNAME		256		/* max property name len */

/*
 * Public properties.
 *
 * Note that there are 2 sets of parameters: the *_EN_* values are
 * those that the Administrator configures for autonegotiation. The
 * _ADV_* values are those that are currently exposed over the wire.
 *
 * Please append properties to the end of this list. Do not reorder the list.
 */
typedef enum {
	MAC_PROP_PRIVATE = -1,
	MAC_PROP_DUPLEX = 0x00000001,
	MAC_PROP_SPEED,
	MAC_PROP_STATUS,
	MAC_PROP_AUTONEG,
	MAC_PROP_EN_AUTONEG,
	MAC_PROP_MTU,
	MAC_PROP_ZONE,
	MAC_PROP_AUTOPUSH,
	MAC_PROP_FLOWCTRL,
	MAC_PROP_ADV_1000FDX_CAP,
	MAC_PROP_EN_1000FDX_CAP,
	MAC_PROP_ADV_1000HDX_CAP,
	MAC_PROP_EN_1000HDX_CAP,
	MAC_PROP_ADV_100FDX_CAP,
	MAC_PROP_EN_100FDX_CAP,
	MAC_PROP_ADV_100HDX_CAP,
	MAC_PROP_EN_100HDX_CAP,
	MAC_PROP_ADV_10FDX_CAP,
	MAC_PROP_EN_10FDX_CAP,
	MAC_PROP_ADV_10HDX_CAP,
	MAC_PROP_EN_10HDX_CAP,
	MAC_PROP_ADV_100T4_CAP,
	MAC_PROP_EN_100T4_CAP,
	MAC_PROP_IPTUN_HOPLIMIT,
	MAC_PROP_IPTUN_ENCAPLIMIT,
	MAC_PROP_WL_ESSID,
	MAC_PROP_WL_BSSID,
	MAC_PROP_WL_BSSTYPE,
	MAC_PROP_WL_LINKSTATUS,
	MAC_PROP_WL_DESIRED_RATES,
	MAC_PROP_WL_SUPPORTED_RATES,
	MAC_PROP_WL_AUTH_MODE,
	MAC_PROP_WL_ENCRYPTION,
	MAC_PROP_WL_RSSI,
	MAC_PROP_WL_PHY_CONFIG,
	MAC_PROP_WL_CAPABILITY,
	MAC_PROP_WL_WPA,
	MAC_PROP_WL_SCANRESULTS,
	MAC_PROP_WL_POWER_MODE,
	MAC_PROP_WL_RADIO,
	MAC_PROP_WL_ESS_LIST,
	MAC_PROP_WL_KEY_TAB,
	MAC_PROP_WL_CREATE_IBSS,
	MAC_PROP_WL_SETOPTIE,
	MAC_PROP_WL_DELKEY,
	MAC_PROP_WL_KEY,
	MAC_PROP_WL_MLME,
	MAC_PROP_TAGMODE,
	MAC_PROP_ADV_10GFDX_CAP,
	MAC_PROP_EN_10GFDX_CAP,
	MAC_PROP_PVID,
	MAC_PROP_LLIMIT,
	MAC_PROP_LDECAY,
	MAC_PROP_RESOURCE,
	MAC_PROP_RESOURCE_EFF,
	MAC_PROP_RXRINGSRANGE,
	MAC_PROP_TXRINGSRANGE,
	MAC_PROP_MAX_TX_RINGS_AVAIL,
	MAC_PROP_MAX_RX_RINGS_AVAIL,
	MAC_PROP_MAX_RXHWCLNT_AVAIL,
	MAC_PROP_MAX_TXHWCLNT_AVAIL,
	MAC_PROP_IB_LINKMODE,
	MAC_PROP_VN_PROMISC_FILTERED,
	MAC_PROP_SECONDARY_ADDRS,
	MAC_PROP_ADV_40GFDX_CAP,
	MAC_PROP_EN_40GFDX_CAP,
	MAC_PROP_ADV_100GFDX_CAP,
	MAC_PROP_EN_100GFDX_CAP,
	MAC_PROP_ADV_2500FDX_CAP,
	MAC_PROP_EN_2500FDX_CAP,
	MAC_PROP_ADV_5000FDX_CAP,
	MAC_PROP_EN_5000FDX_CAP,
	MAC_PROP_ADV_25GFDX_CAP,
	MAC_PROP_EN_25GFDX_CAP,
	MAC_PROP_ADV_50GFDX_CAP,
	MAC_PROP_EN_50GFDX_CAP,
	MAC_PROP_EN_FEC_CAP,
	MAC_PROP_ADV_FEC_CAP
} mac_prop_id_t;

/*
 * Flags to figure out r/w status of legacy ndd props.
 */
#define	MAC_PROP_PERM_READ		0x0001
#define	MAC_PROP_PERM_WRITE		0x0010
#define	MAC_PROP_MAP_KSTAT		0x0100
#define	MAC_PROP_PERM_RW		(MAC_PROP_PERM_READ|MAC_PROP_PERM_WRITE)
#define	MAC_PROP_FLAGS_RK		(MAC_PROP_PERM_READ|MAC_PROP_MAP_KSTAT)

/*
 * Valid LED mode bits
 */
typedef enum mac_led_mode {
	MAC_LED_DEFAULT	= (1 << 0),
	MAC_LED_OFF	= (1 << 1),
	MAC_LED_IDENT	= (1 << 2),
	MAC_LED_ON	= (1 << 3)
} mac_led_mode_t;


#ifdef	_KERNEL

/*
 * There are three ranges of statistics values.  0 to 1 - MAC_STAT_MIN are
 * interface statistics maintained by the mac module.  MAC_STAT_MIN to 1 -
 * MACTYPE_STAT_MIN are common MAC statistics defined by the mac module and
 * maintained by each driver.  MACTYPE_STAT_MIN and above are statistics
 * defined by MAC-Type plugins and maintained by each driver.
 */
#define	MAC_STAT_MIN		1000
#define	MACTYPE_STAT_MIN	2000

#define	IS_MAC_STAT(stat)	\
	(stat >= MAC_STAT_MIN && stat < MACTYPE_STAT_MIN)
#define	IS_MACTYPE_STAT(stat)	(stat >= MACTYPE_STAT_MIN)

/*
 * Statistics maintained by the mac module, and possibly populated as link
 * statistics.
 */
enum mac_mod_stat {
	MAC_STAT_LINK_STATE,
	MAC_STAT_LINK_UP,
	MAC_STAT_PROMISC,
	MAC_STAT_LOWLINK_STATE,
	MAC_STAT_HDROPS
};

/*
 * Do not reorder, and add only to the end of this list.
 */
enum mac_driver_stat {
	/* MIB-II stats (RFC 1213 and RFC 1573) */
	MAC_STAT_IFSPEED = MAC_STAT_MIN,
	MAC_STAT_MULTIRCV,
	MAC_STAT_BRDCSTRCV,
	MAC_STAT_MULTIXMT,
	MAC_STAT_BRDCSTXMT,
	MAC_STAT_NORCVBUF,
	MAC_STAT_IERRORS,
	MAC_STAT_UNKNOWNS,
	MAC_STAT_NOXMTBUF,
	MAC_STAT_OERRORS,
	MAC_STAT_COLLISIONS,
	MAC_STAT_RBYTES,
	MAC_STAT_IPACKETS,
	MAC_STAT_OBYTES,
	MAC_STAT_OPACKETS,
	MAC_STAT_UNDERFLOWS,
	MAC_STAT_OVERFLOWS
};

#define	MAC_NSTAT	(MAC_STAT_OVERFLOWS - MAC_STAT_IFSPEED + 1)

#define	MAC_STAT_ISACOUNTER(_stat) (		\
	    (_stat) == MAC_STAT_MULTIRCV ||	\
	    (_stat) == MAC_STAT_BRDCSTRCV ||	\
	    (_stat) == MAC_STAT_MULTIXMT ||	\
	    (_stat) == MAC_STAT_BRDCSTXMT ||	\
	    (_stat) == MAC_STAT_NORCVBUF ||	\
	    (_stat) == MAC_STAT_IERRORS ||	\
	    (_stat) == MAC_STAT_UNKNOWNS ||	\
	    (_stat) == MAC_STAT_NOXMTBUF ||	\
	    (_stat) == MAC_STAT_OERRORS ||	\
	    (_stat) == MAC_STAT_COLLISIONS ||	\
	    (_stat) == MAC_STAT_RBYTES ||	\
	    (_stat) == MAC_STAT_IPACKETS ||	\
	    (_stat) == MAC_STAT_OBYTES ||	\
	    (_stat) == MAC_STAT_OPACKETS ||	\
	    (_stat) == MAC_STAT_UNDERFLOWS ||	\
	    (_stat) == MAC_STAT_OVERFLOWS)

/*
 * Immutable information. (This may not be modified after registration).
 */
typedef struct mac_info_s {
	uint_t		mi_media;
	uint_t		mi_nativemedia;
	uint_t		mi_addr_length;
	uint8_t		*mi_unicst_addr;
	uint8_t		*mi_brdcst_addr;
} mac_info_t;

/*
 * When VNICs are created on top of the NIC, there are two levels
 * of MAC layer, a lower MAC, which is the MAC layer at the level of the
 * physical NIC, and an upper MAC, which is the MAC layer at the level
 * of the VNIC. Each VNIC maps to a MAC client at the lower MAC, and
 * the SRS and classification is done at the lower MAC level. The upper
 * MAC is therefore for the most part pass-through, and therefore
 * special processing needs to be done at the upper MAC layer when
 * dealing with a VNIC.
 *
 * This capability allows the MAC layer to detect when a VNIC is being
 * access, and implement the required shortcuts.
 *
 * In addition, this capability is used to keep the VNIC's secondary
 * mac_clients in sync when the primary MAC is updated.
 */

typedef void *(*mac_client_handle_fn_t)(void *);
typedef void (*mac_client_update_fn_t)(void *);

typedef struct mac_capab_vnic_s {
	void			*mcv_arg;
	mac_client_handle_fn_t	mcv_mac_client_handle;
	mac_client_update_fn_t	mcv_mac_secondary_update;
} mac_capab_vnic_t;

typedef void (*mac_rename_fn_t)(const char *, void *);
typedef mblk_t *(*mac_tx_ring_fn_t)(void *, mblk_t *, uintptr_t,
    mac_ring_handle_t *);
typedef struct mac_capab_aggr_s {
	mac_rename_fn_t mca_rename_fn;
	int (*mca_unicst)(void *, const uint8_t *);
	mac_tx_ring_fn_t mca_find_tx_ring_fn;
	void *mca_arg;
} mac_capab_aggr_t;

/* Bridge transmit and receive function signatures */
typedef mblk_t *(*mac_bridge_tx_t)(mac_handle_t, mac_ring_handle_t, mblk_t *);
typedef void (*mac_bridge_rx_t)(mac_handle_t, mac_resource_handle_t, mblk_t *);
typedef void (*mac_bridge_ref_t)(mac_handle_t, boolean_t);
typedef link_state_t (*mac_bridge_ls_t)(mac_handle_t, link_state_t);

/* must change mac_notify_cb_list[] in mac_provider.c if this is changed */
typedef enum {
	MAC_NOTE_LINK,
	MAC_NOTE_UNICST,
	MAC_NOTE_TX,
	MAC_NOTE_DEVPROMISC,
	MAC_NOTE_FASTPATH_FLUSH,
	MAC_NOTE_SDU_SIZE,
	MAC_NOTE_DEST,
	MAC_NOTE_MARGIN,
	MAC_NOTE_CAPAB_CHG,
	MAC_NOTE_LOWLINK,
	MAC_NOTE_ALLOWED_IPS,
	MAC_NNOTE	/* must be the last entry */
} mac_notify_type_t;

typedef void		(*mac_notify_t)(void *, mac_notify_type_t);
typedef void		(*mac_rx_t)(void *, mac_resource_handle_t, mblk_t *,
			    boolean_t);
typedef	mblk_t		*(*mac_receive_t)(void *, size_t);

/*
 * MAC resource types
 */
typedef enum {
	MAC_RX_FIFO = 1
} mac_resource_type_t;

typedef	int	(*mac_intr_enable_t)(mac_intr_handle_t);
typedef	int	(*mac_intr_disable_t)(mac_intr_handle_t);

typedef	struct mac_intr_s {
	mac_intr_handle_t	mi_handle;
	mac_intr_enable_t	mi_enable;
	mac_intr_disable_t	mi_disable;
	ddi_intr_handle_t	mi_ddi_handle;
	boolean_t		mi_ddi_shared;
} mac_intr_t;

typedef struct mac_rx_fifo_s {
	mac_resource_type_t	mrf_type;	/* MAC_RX_FIFO */
	mac_intr_t		mrf_intr;
	mac_receive_t		mrf_receive;
	void			*mrf_rx_arg;
	uint32_t		mrf_flow_priority;
	/*
	 * The CPU this flow is to be processed on. With intrd and future
	 * things, we should know which CPU the flow needs to be processed
	 * and get a squeue assigned on that CPU.
	 */
	uint_t			mrf_cpu_id;
} mac_rx_fifo_t;

#define	mrf_intr_handle		mrf_intr.mi_handle
#define	mrf_intr_enable		mrf_intr.mi_enable
#define	mrf_intr_disable	mrf_intr.mi_disable

typedef union mac_resource_u {
	mac_resource_type_t	mr_type;
	mac_rx_fifo_t		mr_fifo;
} mac_resource_t;

typedef enum {
	MAC_ADDRTYPE_UNICAST,
	MAC_ADDRTYPE_MULTICAST,
	MAC_ADDRTYPE_BROADCAST
} mac_addrtype_t;

typedef struct mac_header_info_s {
	size_t		mhi_hdrsize;
	size_t		mhi_pktsize;
	const uint8_t	*mhi_daddr;
	const uint8_t	*mhi_saddr;
	uint32_t	mhi_origsap;
	uint32_t	mhi_bindsap;
	mac_addrtype_t	mhi_dsttype;
	uint16_t	mhi_tci;
	boolean_t	mhi_istagged;
	boolean_t	mhi_ispvid;
} mac_header_info_t;

/*
 * Function pointer to match dls client signature. Should be same as
 * dls_rx_t to allow a soft ring to bypass DLS layer and call a DLS
 * client directly.
 */
typedef	void		(*mac_direct_rx_t)(void *, mac_resource_handle_t,
				mblk_t *, mac_header_info_t *);

typedef mac_resource_handle_t	(*mac_resource_add_t)(void *, mac_resource_t *);
typedef int			(*mac_resource_bind_t)(void *,
    mac_resource_handle_t, processorid_t);
typedef void			(*mac_resource_remove_t)(void *, void *);
typedef void			(*mac_resource_quiesce_t)(void *, void *);
typedef void			(*mac_resource_restart_t)(void *, void *);
typedef int			(*mac_resource_modify_t)(void *, void *,
				    mac_resource_t *);
typedef	void			(*mac_change_upcall_t)(void *, mac_direct_rx_t,
    void *);

/*
 * MAC-Type plugin interfaces
 */

typedef int		(*mtops_addr_verify_t)(const void *, void *);
typedef boolean_t	(*mtops_sap_verify_t)(uint32_t, uint32_t *, void *);
typedef mblk_t		*(*mtops_header_t)(const void *, const void *,
    uint32_t, void *, mblk_t *, size_t);
typedef int		(*mtops_header_info_t)(mblk_t *, void *,
    mac_header_info_t *);
typedef boolean_t	(*mtops_pdata_verify_t)(void *, size_t);
typedef	mblk_t		*(*mtops_header_modify_t)(mblk_t *, void *);
typedef void		(*mtops_link_details_t)(char *, size_t, mac_handle_t,
    void *);

typedef struct mactype_ops_s {
	uint_t			mtops_ops;
	/*
	 * mtops_unicst_verify() returns 0 if the given address is a valid
	 * unicast address, or a non-zero errno otherwise.
	 */
	mtops_addr_verify_t	mtops_unicst_verify;
	/*
	 * mtops_multicst_verify() returns 0 if the given address is a
	 * valid multicast address, or a non-zero errno otherwise.  If the
	 * media doesn't support multicast, ENOTSUP should be returned (for
	 * example).
	 */
	mtops_addr_verify_t	mtops_multicst_verify;
	/*
	 * mtops_sap_verify() returns B_TRUE if the given SAP is a valid
	 * SAP value, or B_FALSE otherwise.
	 */
	mtops_sap_verify_t	mtops_sap_verify;
	/*
	 * mtops_header() is used to allocate and construct a MAC header.
	 */
	mtops_header_t		mtops_header;
	/*
	 * mtops_header_info() is used to gather information on a given MAC
	 * header.
	 */
	mtops_header_info_t	mtops_header_info;
	/*
	 * mtops_pdata_verify() is used to verify the validity of MAC
	 * plugin data.  It is called by mac_register() if the driver has
	 * supplied MAC plugin data, and also by mac_pdata_update() when
	 * drivers update the data.
	 */
	mtops_pdata_verify_t	mtops_pdata_verify;
	/*
	 * mtops_header_cook() is an optional callback that converts (or
	 * "cooks") the given raw header (as sent by a raw DLPI consumer)
	 * into one that is appropriate to send down to the MAC driver.
	 * Following the example above, an Ethernet header sent down by a
	 * DLPI consumer would be converted to whatever header the MAC
	 * driver expects.
	 */
	mtops_header_modify_t	mtops_header_cook;
	/*
	 * mtops_header_uncook() is an optional callback that does the
	 * opposite of mtops_header_cook().  It "uncooks" a given MAC
	 * header (as received from the driver) for consumption by raw DLPI
	 * consumers.  For example, for a non-Ethernet plugin that wants
	 * raw DLPI consumers to be fooled into thinking that the device
	 * provides Ethernet access, this callback would modify the given
	 * mblk_t such that the MAC header is converted to an Ethernet
	 * header.
	 */
	mtops_header_modify_t	mtops_header_uncook;
	/*
	 * mtops_link_details() is an optional callback that provides
	 * extended information about the link state.  Its primary purpose
	 * is to provide type-specific support for syslog contents on
	 * link up events.  If no implementation is provided, then a default
	 * implementation will be used.
	 */
	mtops_link_details_t	mtops_link_details;
} mactype_ops_t;

/*
 * mtops_ops exists for the plugin to enumerate the optional callback
 * entrypoints it has defined.  This allows the mac module to define
 * additional plugin entrypoints in mactype_ops_t without breaking backward
 * compatibility with old plugins.
 */
#define	MTOPS_PDATA_VERIFY	0x001
#define	MTOPS_HEADER_COOK	0x002
#define	MTOPS_HEADER_UNCOOK	0x004
#define	MTOPS_LINK_DETAILS	0x008

/*
 * Provide mapping for legacy ndd ioctls relevant to that mactype.
 * Note that the ndd ioctls are obsolete, and may be removed in a future
 * release of Solaris. The ndd ioctls are not typically used in legacy
 * ethernet drivers. New datalink drivers of all link-types should use
 * dladm(1m) interfaces for administering tunables and not have to provide
 * a mapping.
 */
typedef struct mac_ndd_mapping_s {
	char		*mp_name;
	union {
		mac_prop_id_t   u_id;
		uint_t		u_kstat;
	} u_mp_id;
	long		mp_minval;
	long		mp_maxval;
	size_t		mp_valsize;
	int		mp_flags;
} mac_ndd_mapping_t;

#define	mp_prop_id	u_mp_id.u_id
#define	mp_kstat	u_mp_id.u_kstat

typedef struct mac_stat_info_s {
	uint_t		msi_stat;
	char		*msi_name;
	uint_t		msi_type;	/* as defined in kstat_named_init(9F) */
	uint64_t	msi_default;
} mac_stat_info_t;

typedef struct mactype_register_s {
	uint_t		mtr_version;	/* set by mactype_alloc() */
	const char	*mtr_ident;
	mactype_ops_t	*mtr_ops;
	uint_t		mtr_mactype;
	uint_t		mtr_nativetype;
	uint_t		mtr_addrlen;
	uint8_t		*mtr_brdcst_addr;
	mac_stat_info_t	*mtr_stats;
	size_t		mtr_statcount;
	mac_ndd_mapping_t *mtr_mapping;
	size_t		mtr_mappingcount;
} mactype_register_t;

/*
 * Flags to describe the hardware emulation desired from a client when
 * calling mac_hw_emul().
 *
 * MAC_HWCKSUM_EMUL
 *
 *	If an mblk is marked with HCK_* flags, then calculate those
 *	checksums and update the checksum flags.
 *
 * MAC_IPCKSUM_EMUL
 *
 *	Like MAC_HWCKSUM_EMUL, except only calculate the IPv4 header
 *	checksum. We still update both the IPv4 and ULP checksum
 *	flags.
 *
 * MAC_LSO_EMUL
 *
 *	If an mblk is marked with HW_LSO, then segment the LSO mblk
 *	into a new chain of mblks which reference the original data
 *	block. This flag DOES NOT imply MAC_HWCKSUM_EMUL. If the
 *	caller needs both then it must set both.
 */
typedef enum mac_emul {
	MAC_HWCKSUM_EMUL = (1 << 0),
	MAC_IPCKSUM_EMUL = (1 << 1),
	MAC_LSO_EMUL = (1 << 2)
} mac_emul_t;

#define	MAC_HWCKSUM_EMULS	(MAC_HWCKSUM_EMUL | MAC_IPCKSUM_EMUL)
#define	MAC_ALL_EMULS		(MAC_HWCKSUM_EMUL | MAC_IPCKSUM_EMUL | \
				MAC_LSO_EMUL)

/*
 * Driver interface functions.
 */
extern int			mac_open_by_linkid(datalink_id_t,
				    mac_handle_t *);
extern int			mac_open_by_linkname(const char *,
				    mac_handle_t *);
extern const char		*mac_name(mac_handle_t);
extern minor_t			mac_minor(mac_handle_t);
extern minor_t			mac_minor_hold(boolean_t);
extern void			mac_minor_rele(minor_t);
extern void			mac_sdu_get(mac_handle_t, uint_t *, uint_t *);
extern void			mac_sdu_get2(mac_handle_t, uint_t *, uint_t *,
				    uint_t *);
extern int			mac_maxsdu_update(mac_handle_t, uint_t);
extern int			mac_maxsdu_update2(mac_handle_t, uint_t,
				    uint_t);
extern uint_t			mac_addr_len(mac_handle_t);
extern int			mac_type(mac_handle_t);
extern int			mac_nativetype(mac_handle_t);

extern void			mac_unicst_update(mac_handle_t,
				    const uint8_t *);
extern void			mac_capab_update(mac_handle_t);
extern int			mac_pdata_update(mac_handle_t, void *,
				    size_t);
extern boolean_t		mac_margin_update(mac_handle_t, uint32_t);
extern void			mac_margin_get(mac_handle_t, uint32_t *);
extern int			mac_margin_remove(mac_handle_t, uint32_t);
extern int			mac_margin_add(mac_handle_t, uint32_t *,
				    boolean_t);
extern int			mac_mtu_add(mac_handle_t, uint32_t *,
				    boolean_t);
extern int			mac_mtu_remove(mac_handle_t, uint32_t);
extern int			mac_fastpath_disable(mac_handle_t);
extern void			mac_fastpath_enable(mac_handle_t);
extern void			mac_no_active(mac_handle_t);

extern mactype_register_t	*mactype_alloc(uint_t);
extern void			mactype_free(mactype_register_t *);
extern int			mactype_register(mactype_register_t *);
extern int			mactype_unregister(const char *);

extern int			mac_start_logusage(mac_logtype_t, uint_t);
extern void			mac_stop_logusage(mac_logtype_t);

extern mac_handle_t		mac_get_lower_mac_handle(mac_handle_t);
extern boolean_t		mac_is_vnic_primary(mac_handle_t);

/*
 * Packet hashing for distribution to multiple ports and rings.
 */

#define	MAC_PKT_HASH_L2		0x01
#define	MAC_PKT_HASH_L3		0x02
#define	MAC_PKT_HASH_L4		0x04

extern uint64_t			mac_pkt_hash(uint_t, mblk_t *, uint8_t,
				    boolean_t);

/*
 * Bridging linkage
 */
extern void			mac_rx_common(mac_handle_t,
				    mac_resource_handle_t, mblk_t *);
extern int			mac_bridge_set(mac_handle_t, mac_handle_t);
extern void			mac_bridge_clear(mac_handle_t, mac_handle_t);
extern void			mac_bridge_vectors(mac_bridge_tx_t,
				    mac_bridge_rx_t, mac_bridge_ref_t,
				    mac_bridge_ls_t);

/* special case function for TRILL observability */
extern void			mac_trill_snoop(mac_handle_t, mblk_t *);

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif /* _SYS_MAC_H */