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