4245 boot_time kstat for zones should be epoch timestamp of zone boot, not "random...
[unleashed.git] / usr / src / uts / common / sys / mac_impl.h
blob8f9f23ff71639038f0e63fb08e8a3b2982bbdb3f
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
25 #ifndef _SYS_MAC_IMPL_H
26 #define _SYS_MAC_IMPL_H
28 #include <sys/cpupart.h>
29 #include <sys/modhash.h>
30 #include <sys/mac_client.h>
31 #include <sys/mac_provider.h>
32 #include <sys/note.h>
33 #include <sys/avl.h>
34 #include <net/if.h>
35 #include <sys/mac_flow_impl.h>
36 #include <netinet/ip6.h>
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
43 * This is the first minor number available for MAC provider private
44 * use. This makes it possible to deliver a driver that is both a MAC
45 * provider and a regular character/block device. See PSARC 2009/380
46 * for more detail about the construction of such devices. The value
47 * chosen leaves half of the 32-bit minor numbers (which are really
48 * only 18 bits wide) available for driver private use. Drivers can
49 * easily identify their private number by the presence of this value
50 * in the bits that make up the minor number, since its just the
51 * highest bit available for such minor numbers.
53 #define MAC_PRIVATE_MINOR ((MAXMIN32 + 1) / 2)
56 * The maximum minor number that corresponds to a real instance. This
57 * limits the number of physical ports that a mac provider can offer.
58 * Note that this macro must be synchronized with DLS_MAX_MINOR in
59 * <sys/dls.h>
61 #define MAC_MAX_MINOR 1000
63 typedef struct mac_margin_req_s mac_margin_req_t;
65 struct mac_margin_req_s {
66 mac_margin_req_t *mmr_nextp;
67 uint_t mmr_ref;
68 uint32_t mmr_margin;
71 /* Generic linked chain type */
72 typedef struct mac_chain_s {
73 struct mac_chain_s *next;
74 void *item;
75 } mac_chain_t;
78 * Generic mac callback list manipulation structures and macros. The mac_cb_t
79 * represents a general callback list element embedded in a particular
80 * data structure such as a mac_notify_cb_t or a mac_promisc_impl_t.
81 * The mac_cb_info_t represents general information about list walkers.
82 * Please see the comments above mac_callback_add for more information.
84 /* mcb_flags */
85 #define MCB_CONDEMNED 0x1 /* Logically deleted */
86 #define MCB_NOTIFY_CB_T 0x2
87 #define MCB_TX_NOTIFY_CB_T 0x4
89 extern boolean_t mac_tx_serialize;
91 typedef struct mac_cb_s {
92 struct mac_cb_s *mcb_nextp; /* Linked list of callbacks */
93 void *mcb_objp; /* Ptr to enclosing object */
94 size_t mcb_objsize; /* Sizeof the enclosing obj */
95 uint_t mcb_flags;
96 } mac_cb_t;
98 typedef struct mac_cb_info_s {
99 kmutex_t *mcbi_lockp;
100 kcondvar_t mcbi_cv;
101 uint_t mcbi_del_cnt; /* Deleted callback cnt */
102 uint_t mcbi_walker_cnt; /* List walker count */
103 } mac_cb_info_t;
105 typedef struct mac_notify_cb_s {
106 mac_cb_t mncb_link; /* Linked list of callbacks */
107 mac_notify_t mncb_fn; /* callback function */
108 void *mncb_arg; /* callback argument */
109 struct mac_impl_s *mncb_mip;
110 } mac_notify_cb_t;
113 * mac_callback_add(listinfo, listhead, listelement)
114 * mac_callback_remove(listinfo, listhead, listelement)
116 typedef boolean_t (*mcb_func_t)(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
118 #define MAC_CALLBACK_WALKER_INC(mcbi) { \
119 mutex_enter((mcbi)->mcbi_lockp); \
120 (mcbi)->mcbi_walker_cnt++; \
121 mutex_exit((mcbi)->mcbi_lockp); \
124 #define MAC_CALLBACK_WALKER_INC_HELD(mcbi) (mcbi)->mcbi_walker_cnt++;
126 #define MAC_CALLBACK_WALKER_DCR(mcbi, headp) { \
127 mac_cb_t *rmlist; \
129 mutex_enter((mcbi)->mcbi_lockp); \
130 if (--(mcbi)->mcbi_walker_cnt == 0 && (mcbi)->mcbi_del_cnt != 0) { \
131 rmlist = mac_callback_walker_cleanup((mcbi), headp); \
132 mac_callback_free(rmlist); \
133 cv_broadcast(&(mcbi)->mcbi_cv); \
135 mutex_exit((mcbi)->mcbi_lockp); \
138 #define MAC_PROMISC_WALKER_INC(mip) \
139 MAC_CALLBACK_WALKER_INC(&(mip)->mi_promisc_cb_info)
141 #define MAC_PROMISC_WALKER_DCR(mip) { \
142 mac_cb_info_t *mcbi; \
144 mcbi = &(mip)->mi_promisc_cb_info; \
145 mutex_enter(mcbi->mcbi_lockp); \
146 if (--mcbi->mcbi_walker_cnt == 0 && mcbi->mcbi_del_cnt != 0) { \
147 i_mac_promisc_walker_cleanup(mip); \
148 cv_broadcast(&mcbi->mcbi_cv); \
150 mutex_exit(mcbi->mcbi_lockp); \
153 typedef struct mactype_s {
154 const char *mt_ident;
155 uint32_t mt_ref;
156 uint_t mt_type;
157 uint_t mt_nativetype;
158 size_t mt_addr_length;
159 uint8_t *mt_brdcst_addr;
160 mactype_ops_t mt_ops;
161 mac_stat_info_t *mt_stats; /* array of mac_stat_info_t elements */
162 size_t mt_statcount; /* number of elements in mt_stats */
163 mac_ndd_mapping_t *mt_mapping;
164 size_t mt_mappingcount;
165 } mactype_t;
168 * Multiple rings implementation.
170 typedef enum {
171 MAC_GROUP_STATE_UNINIT = 0, /* initial state of data structure */
172 MAC_GROUP_STATE_REGISTERED, /* hooked with h/w group */
173 MAC_GROUP_STATE_RESERVED, /* group is reserved and opened */
174 MAC_GROUP_STATE_SHARED /* default group shared among */
175 /* multiple mac clients */
176 } mac_group_state_t;
178 typedef struct mac_ring_s mac_ring_t;
179 typedef struct mac_group_s mac_group_t;
182 * Ring data structure for ring control and management.
184 typedef enum {
185 MR_FREE, /* Available for assignment to flows */
186 MR_NEWLY_ADDED, /* Just assigned to another group */
187 MR_INUSE /* Assigned to an SRS */
188 } mac_ring_state_t;
190 /* mr_flag values */
191 #define MR_INCIPIENT 0x1
192 #define MR_CONDEMNED 0x2
193 #define MR_QUIESCE 0x4
195 typedef struct mac_impl_s mac_impl_t;
197 struct mac_ring_s {
198 int mr_index; /* index in the original list */
199 mac_ring_type_t mr_type; /* ring type */
200 mac_ring_t *mr_next; /* next ring in the chain */
201 mac_group_handle_t mr_gh; /* reference to group */
203 mac_classify_type_t mr_classify_type; /* HW vs SW */
204 struct mac_soft_ring_set_s *mr_srs; /* associated SRS */
205 mac_ring_handle_t mr_prh; /* associated pseudo ring hdl */
206 uint_t mr_refcnt; /* Ring references */
207 /* ring generation no. to guard against drivers using stale rings */
208 uint64_t mr_gen_num;
210 kstat_t *mr_ksp; /* ring kstats */
211 mac_impl_t *mr_mip; /* pointer to primary's mip */
213 kmutex_t mr_lock;
214 kcondvar_t mr_cv; /* mr_lock */
215 mac_ring_state_t mr_state; /* mr_lock */
216 uint_t mr_flag; /* mr_lock */
218 mac_ring_info_t mr_info; /* driver supplied info */
220 #define mr_driver mr_info.mri_driver
221 #define mr_start mr_info.mri_start
222 #define mr_stop mr_info.mri_stop
223 #define mr_stat mr_info.mri_stat
225 #define MAC_RING_MARK(mr, flag) \
226 (mr)->mr_flag |= flag;
228 #define MAC_RING_UNMARK(mr, flag) \
229 (mr)->mr_flag &= ~flag;
232 * Reference hold and release on mac_ring_t 'mr'
234 #define MR_REFHOLD_LOCKED(mr) { \
235 ASSERT(MUTEX_HELD(&mr->mr_lock)); \
236 (mr)->mr_refcnt++; \
239 #define MR_REFRELE(mr) { \
240 mutex_enter(&(mr)->mr_lock); \
241 ASSERT((mr)->mr_refcnt != 0); \
242 (mr)->mr_refcnt--; \
243 if ((mr)->mr_refcnt == 0 && \
244 ((mr)->mr_flag & (MR_CONDEMNED | MR_QUIESCE))) \
245 cv_signal(&(mr)->mr_cv); \
246 mutex_exit(&(mr)->mr_lock); \
250 * Per mac client flow information associated with a RX group.
251 * The entire structure is SL protected.
253 typedef struct mac_grp_client {
254 struct mac_grp_client *mgc_next;
255 struct mac_client_impl_s *mgc_client;
256 } mac_grp_client_t;
258 #define MAC_GROUP_NO_CLIENT(g) ((g)->mrg_clients == NULL)
260 #define MAC_GROUP_ONLY_CLIENT(g) \
261 ((((g)->mrg_clients != NULL) && \
262 ((g)->mrg_clients->mgc_next == NULL)) ? \
263 (g)->mrg_clients->mgc_client : NULL)
266 * Common ring group data structure for ring control and management.
267 * The entire structure is SL protected
269 struct mac_group_s {
270 int mrg_index; /* index in the list */
271 mac_ring_type_t mrg_type; /* ring type */
272 mac_group_state_t mrg_state; /* state of the group */
273 mac_group_t *mrg_next; /* next ring in the chain */
274 mac_handle_t mrg_mh; /* reference to MAC */
275 mac_ring_t *mrg_rings; /* grouped rings */
276 uint_t mrg_cur_count; /* actual size of group */
278 mac_grp_client_t *mrg_clients; /* clients list */
280 mac_group_info_t mrg_info; /* driver supplied info */
283 #define mrg_driver mrg_info.mgi_driver
284 #define mrg_start mrg_info.mgi_start
285 #define mrg_stop mrg_info.mgi_stop
287 #define GROUP_INTR_HANDLE(g) (g)->mrg_info.mgi_intr.mi_handle
288 #define GROUP_INTR_ENABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_enable
289 #define GROUP_INTR_DISABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_disable
291 #define MAC_RING_TX(mhp, rh, mp, rest) { \
292 mac_ring_handle_t mrh = rh; \
293 mac_impl_t *mimpl = (mac_impl_t *)mhp; \
294 /* \
295 * Send packets through a selected tx ring, or through the \
296 * default handler if there is no selected ring. \
297 */ \
298 if (mrh == NULL) \
299 mrh = mimpl->mi_default_tx_ring; \
300 if (mrh == NULL) { \
301 rest = mimpl->mi_tx(mimpl->mi_driver, mp); \
302 } else { \
303 rest = mac_hwring_tx(mrh, mp); \
308 * This is the final stop before reaching the underlying driver
309 * or aggregation, so this is where the bridging hook is implemented.
310 * Packets that are bridged will return through mac_bridge_tx(), with
311 * rh nulled out if the bridge chooses to send output on a different
312 * link due to forwarding.
314 #define MAC_TX(mip, rh, mp, src_mcip) { \
315 mac_ring_handle_t rhandle = (rh); \
316 /* \
317 * If there is a bound Hybrid I/O share, send packets through \
318 * the default tx ring. (When there's a bound Hybrid I/O share, \
319 * the tx rings of this client are mapped in the guest domain \
320 * and not accessible from here.) \
321 */ \
322 _NOTE(CONSTANTCONDITION) \
323 if ((src_mcip)->mci_state_flags & MCIS_SHARE_BOUND) \
324 rhandle = (mip)->mi_default_tx_ring; \
325 if (mip->mi_promisc_list != NULL) \
326 mac_promisc_dispatch(mip, mp, src_mcip); \
327 /* \
328 * Grab the proper transmit pointer and handle. Special \
329 * optimization: we can test mi_bridge_link itself atomically, \
330 * and if that indicates no bridge send packets through tx ring.\
331 */ \
332 if (mip->mi_bridge_link == NULL) { \
333 MAC_RING_TX(mip, rhandle, mp, mp); \
334 } else { \
335 mp = mac_bridge_tx(mip, rhandle, mp); \
339 /* mci_tx_flag */
340 #define MCI_TX_QUIESCE 0x1
342 typedef struct mac_factory_addr_s {
343 boolean_t mfa_in_use;
344 uint8_t mfa_addr[MAXMACADDRLEN];
345 struct mac_client_impl_s *mfa_client;
346 } mac_factory_addr_t;
348 typedef struct mac_mcast_addrs_s {
349 struct mac_mcast_addrs_s *mma_next;
350 uint8_t mma_addr[MAXMACADDRLEN];
351 int mma_ref;
352 } mac_mcast_addrs_t;
354 typedef enum {
355 MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED = 1, /* hardware steering */
356 MAC_ADDRESS_TYPE_UNICAST_PROMISC /* promiscuous mode */
357 } mac_address_type_t;
359 typedef struct mac_address_s {
360 mac_address_type_t ma_type; /* address type */
361 int ma_nusers; /* number of users */
362 /* of that address */
363 struct mac_address_s *ma_next; /* next address */
364 uint8_t ma_addr[MAXMACADDRLEN]; /* address value */
365 size_t ma_len; /* address length */
366 mac_group_t *ma_group; /* asscociated group */
367 mac_impl_t *ma_mip; /* MAC handle */
368 } mac_address_t;
370 extern krwlock_t i_mac_impl_lock;
371 extern mod_hash_t *i_mac_impl_hash;
372 extern kmem_cache_t *i_mac_impl_cachep;
373 extern uint_t i_mac_impl_count;
376 * Each registered MAC is associated with a mac_impl_t structure. The
377 * structure represents the undelying hardware, in terms of definition,
378 * resources (transmit, receive rings etc.), callback functions etc. It
379 * also holds the table of MAC clients that are configured on the device.
380 * The table is used for classifying incoming packets in software.
382 * The protection scheme uses 2 elements, a coarse serialization mechanism
383 * called perimeter and a finer traditional lock based scheme. More details
384 * can be found in the big block comment in mac.c.
386 * The protection scheme for each member of the mac_impl_t is described below.
388 * Write Once Only (WO): Typically these don't change for the lifetime of the
389 * data structure. For example something in mac_impl_t that stays the same
390 * from mac_register to mac_unregister, or something in a mac_client_impl_t
391 * that stays the same from mac_client_open to mac_client_close.
393 * Serializer (SL): Protected by the Serializer. All SLOP operations on a
394 * mac endpoint go through the serializer. MTOPs don't care about reading
395 * these fields atomically.
397 * Lock: Traditional mutex/rw lock. Modify operations still go through the
398 * mac serializer, the lock helps synchronize readers with writers.
400 struct mac_impl_s {
401 krwlock_t mi_rw_lock;
402 list_node_t mi_node;
403 char mi_name[LIFNAMSIZ]; /* WO */
404 uint32_t mi_state_flags;
405 void *mi_driver; /* Driver private, WO */
406 mac_info_t mi_info; /* WO */
407 mactype_t *mi_type; /* WO */
408 void *mi_pdata; /* WO */
409 size_t mi_pdata_size; /* WO */
410 mac_callbacks_t *mi_callbacks; /* WO */
411 dev_info_t *mi_dip; /* WO */
412 uint32_t mi_ref; /* i_mac_impl_lock */
413 uint_t mi_active; /* SL */
414 link_state_t mi_linkstate; /* none */
415 link_state_t mi_lowlinkstate; /* none */
416 link_state_t mi_lastlowlinkstate; /* none */
417 uint_t mi_devpromisc; /* SL */
418 uint8_t mi_addr[MAXMACADDRLEN]; /* mi_rw_lock */
419 uint8_t mi_dstaddr[MAXMACADDRLEN]; /* mi_rw_lock */
420 boolean_t mi_dstaddr_set;
423 * The mac perimeter. All client initiated create/modify operations
424 * on a mac end point go through this.
426 kmutex_t mi_perim_lock;
427 kthread_t *mi_perim_owner; /* mi_perim_lock */
428 uint_t mi_perim_ocnt; /* mi_perim_lock */
429 kcondvar_t mi_perim_cv; /* mi_perim_lock */
431 /* mac notification callbacks */
432 kmutex_t mi_notify_lock;
433 mac_cb_info_t mi_notify_cb_info; /* mi_notify_lock */
434 mac_cb_t *mi_notify_cb_list; /* mi_notify_lock */
435 kthread_t *mi_notify_thread; /* mi_notify_lock */
436 uint_t mi_notify_bits; /* mi_notify_lock */
438 uint32_t mi_v12n_level; /* Virt'ion readiness */
441 * RX groups, ring capability
442 * Fields of this block are SL protected.
444 mac_group_type_t mi_rx_group_type; /* grouping type */
445 uint_t mi_rx_group_count;
446 mac_group_t *mi_rx_groups;
447 mac_group_t *mi_rx_donor_grp;
448 uint_t mi_rxrings_rsvd;
449 uint_t mi_rxrings_avail;
450 uint_t mi_rxhwclnt_avail;
451 uint_t mi_rxhwclnt_used;
453 mac_capab_rings_t mi_rx_rings_cap;
456 * TX groups and ring capability, SL Protected.
458 mac_group_type_t mi_tx_group_type; /* grouping type */
459 uint_t mi_tx_group_count;
460 uint_t mi_tx_group_free;
461 mac_group_t *mi_tx_groups;
462 mac_capab_rings_t mi_tx_rings_cap;
463 uint_t mi_txrings_rsvd;
464 uint_t mi_txrings_avail;
465 uint_t mi_txhwclnt_avail;
466 uint_t mi_txhwclnt_used;
468 mac_ring_handle_t mi_default_tx_ring;
471 * MAC address list. SL protected.
473 mac_address_t *mi_addresses;
476 * This MAC's table of sub-flows
478 flow_tab_t *mi_flow_tab; /* WO */
480 kstat_t *mi_ksp; /* WO */
481 uint_t mi_kstat_count; /* WO */
482 uint_t mi_nactiveclients; /* SL */
484 /* for broadcast and multicast support */
485 struct mac_mcast_addrs_s *mi_mcast_addrs; /* mi_rw_lock */
486 struct mac_bcast_grp_s *mi_bcast_grp; /* mi_rw_lock */
487 uint_t mi_bcast_ngrps; /* mi_rw_lock */
489 /* list of MAC clients which opened this MAC */
490 struct mac_client_impl_s *mi_clients_list; /* mi_rw_lock */
491 uint_t mi_nclients; /* mi_rw_lock */
492 struct mac_client_impl_s *mi_single_active_client; /* mi_rw_lock */
494 uint32_t mi_margin; /* mi_rw_lock */
495 uint_t mi_sdu_min; /* mi_rw_lock */
496 uint_t mi_sdu_max; /* mi_rw_lock */
497 uint_t mi_sdu_multicast; /* mi_rw_lock */
500 * Cache of factory MAC addresses provided by the driver. If
501 * the driver doesn't provide multiple factory MAC addresses,
502 * the mi_factory_addr is set to NULL, and mi_factory_addr_num
503 * is set to zero.
505 mac_factory_addr_t *mi_factory_addr; /* mi_rw_lock */
506 uint_t mi_factory_addr_num; /* mi_rw_lock */
508 /* for promiscuous mode support */
509 kmutex_t mi_promisc_lock;
510 mac_cb_t *mi_promisc_list; /* mi_promisc_lock */
511 mac_cb_info_t mi_promisc_cb_info; /* mi_promisc_lock */
513 /* cache of rings over this mac_impl */
514 kmutex_t mi_ring_lock;
515 mac_ring_t *mi_ring_freelist; /* mi_ring_lock */
518 * These are used for caching the properties, if any, for the
519 * primary MAC client. If the MAC client is not yet in place
520 * when the properties are set then we cache them here to be
521 * applied to the MAC client when it is created.
523 mac_resource_props_t mi_resource_props; /* SL */
524 uint16_t mi_pvid; /* SL */
526 minor_t mi_minor; /* WO */
527 uint32_t mi_oref; /* SL */
528 mac_capab_legacy_t mi_capab_legacy; /* WO */
529 dev_t mi_phy_dev; /* WO */
532 * List of margin value requests added by mac clients. This list is
533 * sorted: the first one has the greatest value.
535 mac_margin_req_t *mi_mmrp;
536 char **mi_priv_prop;
537 uint_t mi_priv_prop_count;
540 * Hybrid I/O related definitions.
542 mac_capab_share_t mi_share_capab;
545 * Bridging hooks and limit values. Uses mutex and reference counts
546 * (bridging only) for data path. Limits need no synchronization.
548 mac_handle_t mi_bridge_link;
549 kmutex_t mi_bridge_lock;
550 uint32_t mi_llimit;
551 uint32_t mi_ldecay;
553 /* This should be the last block in this structure */
554 #ifdef DEBUG
555 #define MAC_PERIM_STACK_DEPTH 15
556 int mi_perim_stack_depth;
557 pc_t mi_perim_stack[MAC_PERIM_STACK_DEPTH];
558 #endif
562 * The default TX group is the last one in the list.
564 #define MAC_DEFAULT_TX_GROUP(mip) \
565 (mip)->mi_tx_groups + (mip)->mi_tx_group_count
568 * The default RX group is the first one in the list
570 #define MAC_DEFAULT_RX_GROUP(mip) (mip)->mi_rx_groups
572 /* Reserved RX rings */
573 #define MAC_RX_RING_RESERVED(m, cnt) { \
574 ASSERT((m)->mi_rxrings_avail >= (cnt)); \
575 (m)->mi_rxrings_rsvd += (cnt); \
576 (m)->mi_rxrings_avail -= (cnt); \
579 /* Released RX rings */
580 #define MAC_RX_RING_RELEASED(m, cnt) { \
581 ASSERT((m)->mi_rxrings_rsvd >= (cnt)); \
582 (m)->mi_rxrings_rsvd -= (cnt); \
583 (m)->mi_rxrings_avail += (cnt); \
586 /* Reserved a RX group */
587 #define MAC_RX_GRP_RESERVED(m) { \
588 ASSERT((m)->mi_rxhwclnt_avail > 0); \
589 (m)->mi_rxhwclnt_avail--; \
590 (m)->mi_rxhwclnt_used++; \
593 /* Released a RX group */
594 #define MAC_RX_GRP_RELEASED(m) { \
595 ASSERT((m)->mi_rxhwclnt_used > 0); \
596 (m)->mi_rxhwclnt_avail++; \
597 (m)->mi_rxhwclnt_used--; \
600 /* Reserved TX rings */
601 #define MAC_TX_RING_RESERVED(m, cnt) { \
602 ASSERT((m)->mi_txrings_avail >= (cnt)); \
603 (m)->mi_txrings_rsvd += (cnt); \
604 (m)->mi_txrings_avail -= (cnt); \
606 /* Released TX rings */
607 #define MAC_TX_RING_RELEASED(m, cnt) { \
608 ASSERT((m)->mi_txrings_rsvd >= (cnt)); \
609 (m)->mi_txrings_rsvd -= (cnt); \
610 (m)->mi_txrings_avail += (cnt); \
613 /* Reserved a TX group */
614 #define MAC_TX_GRP_RESERVED(m) { \
615 ASSERT((m)->mi_txhwclnt_avail > 0); \
616 (m)->mi_txhwclnt_avail--; \
617 (m)->mi_txhwclnt_used++; \
620 /* Released a TX group */
621 #define MAC_TX_GRP_RELEASED(m) { \
622 ASSERT((m)->mi_txhwclnt_used > 0); \
623 (m)->mi_txhwclnt_avail++; \
624 (m)->mi_txhwclnt_used--; \
627 /* for mi_state_flags */
628 #define MIS_DISABLED 0x0001
629 #define MIS_IS_VNIC 0x0002
630 #define MIS_IS_AGGR 0x0004
631 #define MIS_NOTIFY_DONE 0x0008
632 #define MIS_EXCLUSIVE 0x0010
633 #define MIS_EXCLUSIVE_HELD 0x0020
634 #define MIS_LEGACY 0x0040
635 #define MIS_NO_ACTIVE 0x0080
636 #define MIS_POLL_DISABLE 0x0100
638 #define mi_getstat mi_callbacks->mc_getstat
639 #define mi_start mi_callbacks->mc_start
640 #define mi_stop mi_callbacks->mc_stop
641 #define mi_open mi_callbacks->mc_open
642 #define mi_close mi_callbacks->mc_close
643 #define mi_setpromisc mi_callbacks->mc_setpromisc
644 #define mi_multicst mi_callbacks->mc_multicst
645 #define mi_unicst mi_callbacks->mc_unicst
646 #define mi_tx mi_callbacks->mc_tx
647 #define mi_ioctl mi_callbacks->mc_ioctl
648 #define mi_getcapab mi_callbacks->mc_getcapab
650 typedef struct mac_notify_task_arg {
651 mac_impl_t *mnt_mip;
652 mac_notify_type_t mnt_type;
653 mac_ring_t *mnt_ring;
654 } mac_notify_task_arg_t;
657 * XXX All MAC_DBG_PRTs must be replaced with call to dtrace probes. For now
658 * it may be easier to have these printfs for easier debugging
660 #ifdef DEBUG
661 extern int mac_dbg;
662 #define MAC_DBG_PRT(a) if (mac_dbg > 0) {(void) printf a; }
663 #else
664 #define MAC_DBG_PRT(a)
665 #endif
668 * The mac_perim_handle_t is an opaque type that encodes the 'mip' pointer
669 * and whether internally a mac_open was done when acquiring the perimeter.
671 #define MAC_ENCODE_MPH(mph, mh, need_close) \
672 (mph) = (mac_perim_handle_t)((uintptr_t)(mh) | need_close)
674 #define MAC_DECODE_MPH(mph, mip, need_close) { \
675 mip = (mac_impl_t *)(((uintptr_t)mph) & ~0x1); \
676 (need_close) = ((uintptr_t)mph & 0x1); \
680 * Type of property information that can be returned by a driver.
681 * Valid flags of the pr_flags of the mac_prop_info_t data structure.
683 #define MAC_PROP_INFO_DEFAULT 0x0001
684 #define MAC_PROP_INFO_RANGE 0x0002
685 #define MAC_PROP_INFO_PERM 0x0004
688 * Property information. pr_flags is a combination of one of the
689 * MAC_PROP_INFO_* flags, it is reset by the framework before invoking
690 * the driver's prefix_propinfo() entry point.
692 * Drivers should use MAC_PROP_INFO_SET_*() macros to provide
693 * information about a property.
695 typedef struct mac_prop_info_state_s {
696 uint8_t pr_flags;
697 uint8_t pr_perm;
698 uint8_t pr_errno;
699 void *pr_default;
700 size_t pr_default_size;
701 mac_propval_range_t *pr_range;
702 uint_t pr_range_cur_count;
703 } mac_prop_info_state_t;
705 #define MAC_PROTECT_ENABLED(mcip, type) \
706 (((mcip)->mci_flent-> \
707 fe_resource_props.mrp_mask & MRP_PROTECT) != 0 && \
708 ((mcip)->mci_flent-> \
709 fe_resource_props.mrp_protect.mp_types & (type)) != 0)
711 typedef struct mac_client_impl_s mac_client_impl_t;
713 extern void mac_init(void);
714 extern int mac_fini(void);
716 extern void mac_ndd_ioctl(mac_impl_t *, queue_t *, mblk_t *);
717 extern boolean_t mac_ip_hdr_length_v6(ip6_t *, uint8_t *, uint16_t *,
718 uint8_t *, ip6_frag_t **);
720 extern mblk_t *mac_copymsgchain_cksum(mblk_t *);
721 extern mblk_t *mac_fix_cksum(mblk_t *);
722 extern void mac_packet_print(mac_handle_t, mblk_t *);
723 extern void mac_rx_deliver(void *, mac_resource_handle_t, mblk_t *,
724 mac_header_info_t *);
725 extern void mac_tx_notify(mac_impl_t *);
727 extern boolean_t mac_callback_find(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
728 extern void mac_callback_add(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
729 extern boolean_t mac_callback_remove(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
730 extern void mac_callback_remove_wait(mac_cb_info_t *);
731 extern void mac_callback_free(mac_cb_t *);
732 extern mac_cb_t *mac_callback_walker_cleanup(mac_cb_info_t *, mac_cb_t **);
734 /* in mac_bcast.c */
735 extern void mac_bcast_init(void);
736 extern void mac_bcast_fini(void);
737 extern mac_impl_t *mac_bcast_grp_mip(void *);
738 extern int mac_bcast_add(mac_client_impl_t *, const uint8_t *, uint16_t,
739 mac_addrtype_t);
740 extern void mac_bcast_delete(mac_client_impl_t *, const uint8_t *, uint16_t);
741 extern void mac_bcast_send(void *, void *, mblk_t *, boolean_t);
742 extern void mac_bcast_grp_free(void *);
743 extern void mac_bcast_refresh(mac_impl_t *, mac_multicst_t, void *,
744 boolean_t);
745 extern void mac_client_bcast_refresh(mac_client_impl_t *, mac_multicst_t,
746 void *, boolean_t);
749 * Grouping functions are used internally by MAC layer.
751 extern int mac_group_addmac(mac_group_t *, const uint8_t *);
752 extern int mac_group_remmac(mac_group_t *, const uint8_t *);
753 extern int mac_rx_group_add_flow(mac_client_impl_t *, flow_entry_t *,
754 mac_group_t *);
755 extern mblk_t *mac_hwring_tx(mac_ring_handle_t, mblk_t *);
756 extern mblk_t *mac_bridge_tx(mac_impl_t *, mac_ring_handle_t, mblk_t *);
757 extern mac_group_t *mac_reserve_rx_group(mac_client_impl_t *, uint8_t *,
758 boolean_t);
759 extern void mac_release_rx_group(mac_client_impl_t *, mac_group_t *);
760 extern int mac_rx_switch_group(mac_client_impl_t *, mac_group_t *,
761 mac_group_t *);
762 extern mac_ring_t *mac_reserve_tx_ring(mac_impl_t *, mac_ring_t *);
763 extern mac_group_t *mac_reserve_tx_group(mac_client_impl_t *, boolean_t);
764 extern void mac_release_tx_group(mac_client_impl_t *, mac_group_t *);
765 extern void mac_tx_switch_group(mac_client_impl_t *, mac_group_t *,
766 mac_group_t *);
767 extern void mac_rx_switch_grp_to_sw(mac_group_t *);
770 * MAC address functions are used internally by MAC layer.
772 extern mac_address_t *mac_find_macaddr(mac_impl_t *, uint8_t *);
773 extern boolean_t mac_check_macaddr_shared(mac_address_t *);
774 extern int mac_update_macaddr(mac_address_t *, uint8_t *);
775 extern void mac_freshen_macaddr(mac_address_t *, uint8_t *);
776 extern void mac_retrieve_macaddr(mac_address_t *, uint8_t *);
777 extern void mac_init_macaddr(mac_impl_t *);
778 extern void mac_fini_macaddr(mac_impl_t *);
781 * Flow construction/destruction routines.
782 * Not meant to be used by mac clients.
784 extern int mac_link_flow_init(mac_client_handle_t, flow_entry_t *);
785 extern void mac_link_flow_clean(mac_client_handle_t, flow_entry_t *);
788 * Fanout update routines called when the link speed of the NIC changes
789 * or when a MAC client's share is unbound.
791 extern void mac_fanout_recompute_client(mac_client_impl_t *, cpupart_t *);
792 extern void mac_fanout_recompute(mac_impl_t *);
795 * The following functions are used internally by the MAC layer to
796 * add/remove/update flows associated with a mac_impl_t. They should
797 * never be used directly by MAC clients.
799 extern int mac_datapath_setup(mac_client_impl_t *, flow_entry_t *, uint32_t);
800 extern void mac_datapath_teardown(mac_client_impl_t *, flow_entry_t *,
801 uint32_t);
802 extern void mac_rx_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
803 uint32_t);
804 extern void mac_tx_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
805 uint32_t);
806 extern void mac_rx_srs_group_teardown(flow_entry_t *, boolean_t);
807 extern void mac_tx_srs_group_teardown(mac_client_impl_t *, flow_entry_t *,
808 uint32_t);
809 extern int mac_rx_classify_flow_quiesce(flow_entry_t *, void *);
810 extern int mac_rx_classify_flow_restart(flow_entry_t *, void *);
811 extern void mac_client_quiesce(mac_client_impl_t *);
812 extern void mac_client_restart(mac_client_impl_t *);
814 extern void mac_flow_update_priority(mac_client_impl_t *, flow_entry_t *);
816 extern void mac_flow_rem_subflow(flow_entry_t *);
817 extern void mac_rename_flow(flow_entry_t *, const char *);
818 extern void mac_flow_set_name(flow_entry_t *, const char *);
820 extern mblk_t *mac_add_vlan_tag(mblk_t *, uint_t, uint16_t);
821 extern mblk_t *mac_add_vlan_tag_chain(mblk_t *, uint_t, uint16_t);
822 extern mblk_t *mac_strip_vlan_tag_chain(mblk_t *);
823 extern void mac_pkt_drop(void *, mac_resource_handle_t, mblk_t *, boolean_t);
824 extern mblk_t *mac_rx_flow(mac_handle_t, mac_resource_handle_t, mblk_t *);
826 extern void i_mac_share_alloc(mac_client_impl_t *);
827 extern void i_mac_share_free(mac_client_impl_t *);
828 extern void i_mac_perim_enter(mac_impl_t *);
829 extern void i_mac_perim_exit(mac_impl_t *);
830 extern int i_mac_perim_enter_nowait(mac_impl_t *);
831 extern void i_mac_tx_srs_notify(mac_impl_t *, mac_ring_handle_t);
832 extern int mac_hold(const char *, mac_impl_t **);
833 extern void mac_rele(mac_impl_t *);
834 extern int i_mac_disable(mac_impl_t *);
835 extern void i_mac_notify(mac_impl_t *, mac_notify_type_t);
836 extern void i_mac_notify_exit(mac_impl_t *);
837 extern void mac_rx_group_unmark(mac_group_t *, uint_t);
838 extern void mac_tx_client_flush(mac_client_impl_t *);
839 extern void mac_tx_client_block(mac_client_impl_t *);
840 extern void mac_tx_client_unblock(mac_client_impl_t *);
841 extern void mac_tx_invoke_callbacks(mac_client_impl_t *, mac_tx_cookie_t);
842 extern int i_mac_promisc_set(mac_impl_t *, boolean_t);
843 extern void i_mac_promisc_walker_cleanup(mac_impl_t *);
844 extern mactype_t *mactype_getplugin(const char *);
845 extern void mac_addr_factory_init(mac_impl_t *);
846 extern void mac_addr_factory_fini(mac_impl_t *);
847 extern void mac_register_priv_prop(mac_impl_t *, char **);
848 extern void mac_unregister_priv_prop(mac_impl_t *);
849 extern int mac_init_rings(mac_impl_t *, mac_ring_type_t);
850 extern void mac_free_rings(mac_impl_t *, mac_ring_type_t);
851 extern void mac_compare_ddi_handle(mac_group_t *, uint_t, mac_ring_t *);
853 extern int mac_start_group(mac_group_t *);
854 extern void mac_stop_group(mac_group_t *);
855 extern int mac_start_ring(mac_ring_t *);
856 extern void mac_stop_ring(mac_ring_t *);
857 extern int mac_add_macaddr(mac_impl_t *, mac_group_t *, uint8_t *, boolean_t);
858 extern int mac_remove_macaddr(mac_address_t *);
860 extern void mac_set_group_state(mac_group_t *, mac_group_state_t);
861 extern void mac_group_add_client(mac_group_t *, mac_client_impl_t *);
862 extern void mac_group_remove_client(mac_group_t *, mac_client_impl_t *);
864 extern int i_mac_group_add_ring(mac_group_t *, mac_ring_t *, int);
865 extern void i_mac_group_rem_ring(mac_group_t *, mac_ring_t *, boolean_t);
866 extern int mac_group_ring_modify(mac_client_impl_t *, mac_group_t *,
867 mac_group_t *);
868 extern void mac_poll_state_change(mac_handle_t, boolean_t);
870 extern mac_group_state_t mac_group_next_state(mac_group_t *,
871 mac_client_impl_t **, mac_group_t *, boolean_t);
873 extern mblk_t *mac_protect_check(mac_client_handle_t, mblk_t *);
874 extern int mac_protect_set(mac_client_handle_t, mac_resource_props_t *);
875 extern boolean_t mac_protect_enabled(mac_client_handle_t, uint32_t);
876 extern int mac_protect_validate(mac_resource_props_t *);
877 extern void mac_protect_update(mac_resource_props_t *, mac_resource_props_t *);
878 extern void mac_protect_update_v6_local_addr(mac_client_impl_t *);
879 extern void mac_protect_intercept_dhcp(mac_client_impl_t *, mblk_t *);
880 extern void mac_protect_flush_dhcp(mac_client_impl_t *);
881 extern void mac_protect_cancel_timer(mac_client_impl_t *);
882 extern void mac_protect_init(mac_client_impl_t *);
883 extern void mac_protect_fini(mac_client_impl_t *);
885 extern int mac_set_resources(mac_handle_t, mac_resource_props_t *);
886 extern void mac_get_resources(mac_handle_t, mac_resource_props_t *);
887 extern void mac_get_effective_resources(mac_handle_t, mac_resource_props_t *);
889 extern cpupart_t *mac_pset_find(mac_resource_props_t *, boolean_t *);
890 extern void mac_set_pool_effective(boolean_t, cpupart_t *,
891 mac_resource_props_t *, mac_resource_props_t *);
892 extern void mac_set_rings_effective(mac_client_impl_t *);
893 extern mac_client_impl_t *mac_check_primary_relocation(mac_client_impl_t *,
894 boolean_t);
896 /* Global callbacks into the bridging module (when loaded) */
897 extern mac_bridge_tx_t mac_bridge_tx_cb;
898 extern mac_bridge_rx_t mac_bridge_rx_cb;
899 extern mac_bridge_ref_t mac_bridge_ref_cb;
900 extern mac_bridge_ls_t mac_bridge_ls_cb;
903 #ifdef __cplusplus
905 #endif
907 #endif /* _SYS_MAC_IMPL_H */