1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2018, Joyent, Inc.
24 */
25
26 #ifndef _SYS_MAC_IMPL_H
27 #define _SYS_MAC_IMPL_H
28
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>
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /*
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.
53 */
54 #define MAC_PRIVATE_MINOR ((MAXMIN32 + 1) / 2)
55
56 /*
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>
61 */
62 #define MAC_MAX_MINOR 1000
63
64 typedef struct mac_margin_req_s mac_margin_req_t;
65
66 struct mac_margin_req_s {
67 mac_margin_req_t *mmr_nextp;
68 uint_t mmr_ref;
69 uint32_t mmr_margin;
70 };
71
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;
77 };
78
79 /* Generic linked chain type */
80 typedef struct mac_chain_s {
81 struct mac_chain_s *next;
82 void *item;
83 } mac_chain_t;
84
85 /*
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.
91 */
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
96
97 extern boolean_t mac_tx_serialize;
98
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;
105
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;
112
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;
119
120 /*
121 * mac_callback_add(listinfo, listhead, listelement)
122 * mac_callback_remove(listinfo, listhead, listelement)
123 */
124 typedef boolean_t (*mcb_func_t)(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
125
126 #define MAC_CALLBACK_WALKER_INC(mcbi) { \
127 mutex_enter((mcbi)->mcbi_lockp); \
128 (mcbi)->mcbi_walker_cnt++; \
129 mutex_exit((mcbi)->mcbi_lockp); \
130 }
131
132 #define MAC_CALLBACK_WALKER_INC_HELD(mcbi) (mcbi)->mcbi_walker_cnt++;
133
134 #define MAC_CALLBACK_WALKER_DCR(mcbi, headp) { \
135 mac_cb_t *rmlist; \
136 \
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); \
142 } \
143 mutex_exit((mcbi)->mcbi_lockp); \
144 }
145
146 #define MAC_PROMISC_WALKER_INC(mip) \
147 MAC_CALLBACK_WALKER_INC(&(mip)->mi_promisc_cb_info)
148
149 #define MAC_PROMISC_WALKER_DCR(mip) { \
150 mac_cb_info_t *mcbi; \
151 \
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); \
157 } \
158 mutex_exit(mcbi->mcbi_lockp); \
159 }
160
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;
174
175 /*
176 * Multiple rings implementation.
177 */
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;
185
186 typedef struct mac_ring_s mac_ring_t;
187 typedef struct mac_group_s mac_group_t;
188
189 /*
190 * Ring data structure for ring control and management.
191 */
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;
197
198 /* mr_flag values */
199 #define MR_INCIPIENT 0x1
200 #define MR_CONDEMNED 0x2
201 #define MR_QUIESCE 0x4
202
203 typedef struct mac_impl_s mac_impl_t;
204
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 */
210
211 mac_classify_type_t mr_classify_type;
212 struct mac_soft_ring_set_s *mr_srs; /* associated SRS */
213 mac_ring_handle_t mr_prh; /* associated pseudo ring hdl */
214
215 /*
216 * Ring passthru callback and arguments. See the
217 * MAC_PASSTHRU_CLASSIFIER comment in mac_provider.h.
218 */
219 mac_rx_t mr_pt_fn;
220 void *mr_pt_arg1;
221 mac_resource_handle_t mr_pt_arg2;
222
223 uint_t mr_refcnt; /* Ring references */
224 /* ring generation no. to guard against drivers using stale rings */
225 uint64_t mr_gen_num;
226
227 kstat_t *mr_ksp; /* ring kstats */
228 mac_impl_t *mr_mip; /* pointer to primary's mip */
229
230 kmutex_t mr_lock;
231 kcondvar_t mr_cv; /* mr_lock */
232 mac_ring_state_t mr_state; /* mr_lock */
233 uint_t mr_flag; /* mr_lock */
234
235 mac_ring_info_t mr_info; /* driver supplied info */
236 };
237 #define mr_driver mr_info.mri_driver
238 #define mr_start mr_info.mri_start
239 #define mr_stop mr_info.mri_stop
240 #define mr_stat mr_info.mri_stat
241
242 #define MAC_RING_MARK(mr, flag) \
243 (mr)->mr_flag |= flag;
244
245 #define MAC_RING_UNMARK(mr, flag) \
246 (mr)->mr_flag &= ~flag;
247
248 /*
249 * Reference hold and release on mac_ring_t 'mr'
250 */
251 #define MR_REFHOLD_LOCKED(mr) { \
252 ASSERT(MUTEX_HELD(&mr->mr_lock)); \
253 (mr)->mr_refcnt++; \
254 }
255
256 #define MR_REFRELE(mr) { \
257 mutex_enter(&(mr)->mr_lock); \
258 ASSERT((mr)->mr_refcnt != 0); \
259 (mr)->mr_refcnt--; \
260 if ((mr)->mr_refcnt == 0 && \
261 ((mr)->mr_flag & (MR_CONDEMNED | MR_QUIESCE))) \
262 cv_signal(&(mr)->mr_cv); \
263 mutex_exit(&(mr)->mr_lock); \
264 }
265
266 /*
267 * Used to attach MAC clients to an Rx group. The members are SL
268 * protected.
269 */
270 typedef struct mac_grp_client {
271 struct mac_grp_client *mgc_next;
272 struct mac_client_impl_s *mgc_client;
273 } mac_grp_client_t;
274
275 #define MAC_GROUP_NO_CLIENT(g) ((g)->mrg_clients == NULL)
276
277 #define MAC_GROUP_ONLY_CLIENT(g) \
278 ((((g)->mrg_clients != NULL) && \
279 ((g)->mrg_clients->mgc_next == NULL)) ? \
280 (g)->mrg_clients->mgc_client : NULL)
281
282 #define MAC_GROUP_HW_VLAN(g) \
283 (((g) != NULL) && \
284 ((g)->mrg_info.mgi_addvlan != NULL) && \
285 ((g)->mrg_info.mgi_remvlan != NULL))
286
287 /*
288 * Common ring group data structure for ring control and management.
289 * The entire structure is SL protected.
290 */
291 struct mac_group_s {
292 int mrg_index; /* index in the list */
293 mac_ring_type_t mrg_type; /* ring type */
294 mac_group_state_t mrg_state; /* state of the group */
295 mac_group_t *mrg_next; /* next group in the chain */
296 mac_handle_t mrg_mh; /* reference to MAC */
297 mac_ring_t *mrg_rings; /* grouped rings */
298 uint_t mrg_cur_count; /* actual size of group */
299
300 mac_grp_client_t *mrg_clients; /* clients list */
301
302 mac_group_info_t mrg_info; /* driver supplied info */
303 };
304
305 #define mrg_driver mrg_info.mgi_driver
306 #define mrg_start mrg_info.mgi_start
307 #define mrg_stop mrg_info.mgi_stop
308
309 #define GROUP_INTR_HANDLE(g) (g)->mrg_info.mgi_intr.mi_handle
310 #define GROUP_INTR_ENABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_enable
311 #define GROUP_INTR_DISABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_disable
312
313 #define MAC_RING_TX(mhp, rh, mp, rest) { \
314 mac_ring_handle_t mrh = rh; \
315 mac_impl_t *mimpl = (mac_impl_t *)mhp; \
316 /* \
317 * Send packets through a selected tx ring, or through the \
318 * default handler if there is no selected ring. \
319 */ \
320 if (mrh == NULL) \
321 mrh = mimpl->mi_default_tx_ring; \
322 if (mrh == NULL) { \
323 rest = mimpl->mi_tx(mimpl->mi_driver, mp); \
324 } else { \
325 rest = mac_hwring_tx(mrh, mp); \
326 } \
327 }
328
329 /*
330 * This is the final stop before reaching the underlying driver
331 * or aggregation, so this is where the bridging hook is implemented.
332 * Packets that are bridged will return through mac_bridge_tx(), with
333 * rh nulled out if the bridge chooses to send output on a different
334 * link due to forwarding.
335 */
336 #define MAC_TX(mip, rh, mp, src_mcip) { \
337 mac_ring_handle_t rhandle = (rh); \
338 /* \
339 * If there is a bound Hybrid I/O share, send packets through \
340 * the default tx ring. (When there's a bound Hybrid I/O share, \
341 * the tx rings of this client are mapped in the guest domain \
342 * and not accessible from here.) \
343 */ \
344 _NOTE(CONSTANTCONDITION) \
345 if ((src_mcip)->mci_state_flags & MCIS_SHARE_BOUND) \
346 rhandle = (mip)->mi_default_tx_ring; \
347 if (mip->mi_promisc_list != NULL) \
348 mac_promisc_dispatch(mip, mp, src_mcip); \
349 /* \
350 * Grab the proper transmit pointer and handle. Special \
351 * optimization: we can test mi_bridge_link itself atomically, \
352 * and if that indicates no bridge send packets through tx ring.\
353 */ \
354 if (mip->mi_bridge_link == NULL) { \
355 MAC_RING_TX(mip, rhandle, mp, mp); \
356 } else { \
357 mp = mac_bridge_tx(mip, rhandle, mp); \
358 } \
359 }
360
361 /* mci_tx_flag */
362 #define MCI_TX_QUIESCE 0x1
363
364 typedef struct mac_factory_addr_s {
365 boolean_t mfa_in_use;
366 uint8_t mfa_addr[MAXMACADDRLEN];
367 struct mac_client_impl_s *mfa_client;
368 } mac_factory_addr_t;
369
370 typedef struct mac_mcast_addrs_s {
371 struct mac_mcast_addrs_s *mma_next;
372 uint8_t mma_addr[MAXMACADDRLEN];
373 int mma_ref;
374 } mac_mcast_addrs_t;
375
376 typedef enum {
377 MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED = 1, /* HW classification */
378 MAC_ADDRESS_TYPE_UNICAST_PROMISC /* promiscuous mode */
379 } mac_address_type_t;
380
381 typedef struct mac_vlan_s {
382 struct mac_vlan_s *mv_next;
383 uint16_t mv_vid;
384 } mac_vlan_t;
385
386 typedef struct mac_address_s {
387 mac_address_type_t ma_type; /* address type */
388 int ma_nusers; /* num users of addr */
389 struct mac_address_s *ma_next; /* next address */
390 uint8_t ma_addr[MAXMACADDRLEN]; /* address value */
391 size_t ma_len; /* address length */
392 mac_vlan_t *ma_vlans; /* VLANs on this addr */
393 boolean_t ma_untagged; /* accept untagged? */
394 mac_group_t *ma_group; /* asscociated group */
395 mac_impl_t *ma_mip; /* MAC handle */
396 } mac_address_t;
397
398 extern krwlock_t i_mac_impl_lock;
399 extern mod_hash_t *i_mac_impl_hash;
400 extern kmem_cache_t *i_mac_impl_cachep;
401 extern uint_t i_mac_impl_count;
402
403 /*
404 * Each registered MAC is associated with a mac_impl_t structure. The
405 * structure represents the undelying hardware, in terms of definition,
406 * resources (transmit, receive rings etc.), callback functions etc. It
407 * also holds the table of MAC clients that are configured on the device.
408 * The table is used for classifying incoming packets in software.
409 *
410 * The protection scheme uses 2 elements, a coarse serialization mechanism
411 * called perimeter and a finer traditional lock based scheme. More details
412 * can be found in the big block comment in mac.c.
413 *
414 * The protection scheme for each member of the mac_impl_t is described below.
415 *
416 * Write Once Only (WO): Typically these don't change for the lifetime of the
417 * data structure. For example something in mac_impl_t that stays the same
418 * from mac_register to mac_unregister, or something in a mac_client_impl_t
419 * that stays the same from mac_client_open to mac_client_close.
420 *
421 * Serializer (SL): Protected by the Serializer. All SLOP operations on a
422 * mac endpoint go through the serializer. MTOPs don't care about reading
423 * these fields atomically.
424 *
425 * Lock: Traditional mutex/rw lock. Modify operations still go through the
426 * mac serializer, the lock helps synchronize readers with writers.
427 */
428 struct mac_impl_s {
429 krwlock_t mi_rw_lock;
430 list_node_t mi_node;
431 char mi_name[LIFNAMSIZ]; /* WO */
432 uint32_t mi_state_flags;
433 void *mi_driver; /* Driver private, WO */
434 mac_info_t mi_info; /* WO */
435 mactype_t *mi_type; /* WO */
436 void *mi_pdata; /* WO */
437 size_t mi_pdata_size; /* WO */
438 mac_callbacks_t *mi_callbacks; /* WO */
439 dev_info_t *mi_dip; /* WO */
440 uint32_t mi_ref; /* i_mac_impl_lock */
441 uint_t mi_active; /* SL */
442 link_state_t mi_linkstate; /* none */
443 link_state_t mi_lowlinkstate; /* none */
444 link_state_t mi_lastlowlinkstate; /* none */
445 uint_t mi_devpromisc; /* SL */
446 uint8_t mi_addr[MAXMACADDRLEN]; /* mi_rw_lock */
447 uint8_t mi_dstaddr[MAXMACADDRLEN]; /* mi_rw_lock */
448 boolean_t mi_dstaddr_set;
449
450 /*
451 * The mac perimeter. All client initiated create/modify operations
452 * on a mac end point go through this.
453 */
454 kmutex_t mi_perim_lock;
455 kthread_t *mi_perim_owner; /* mi_perim_lock */
456 uint_t mi_perim_ocnt; /* mi_perim_lock */
457 kcondvar_t mi_perim_cv; /* mi_perim_lock */
458
459 /* mac notification callbacks */
460 kmutex_t mi_notify_lock;
461 mac_cb_info_t mi_notify_cb_info; /* mi_notify_lock */
462 mac_cb_t *mi_notify_cb_list; /* mi_notify_lock */
463 kthread_t *mi_notify_thread; /* mi_notify_lock */
464 uint_t mi_notify_bits; /* mi_notify_lock */
465
466 uint32_t mi_v12n_level; /* Virt'ion readiness */
467
468 /*
469 * RX groups, ring capability
470 * Fields of this block are SL protected.
471 */
472 mac_group_type_t mi_rx_group_type; /* grouping type */
473 uint_t mi_rx_group_count;
474 mac_group_t *mi_rx_groups;
475 mac_group_t *mi_rx_donor_grp;
476 uint_t mi_rxrings_rsvd;
477 uint_t mi_rxrings_avail;
478 uint_t mi_rxhwclnt_avail;
479 uint_t mi_rxhwclnt_used;
480
481 mac_capab_rings_t mi_rx_rings_cap;
482
483 /*
484 * TX groups and ring capability, SL Protected.
485 */
486 mac_group_type_t mi_tx_group_type; /* grouping type */
487 uint_t mi_tx_group_count;
488 uint_t mi_tx_group_free;
489 mac_group_t *mi_tx_groups;
490 mac_capab_rings_t mi_tx_rings_cap;
491 uint_t mi_txrings_rsvd;
492 uint_t mi_txrings_avail;
493 uint_t mi_txhwclnt_avail;
494 uint_t mi_txhwclnt_used;
495
496 mac_ring_handle_t mi_default_tx_ring;
497
498 /*
499 * Transceiver capabilities. SL protected.
500 */
501 mac_capab_transceiver_t mi_transceiver;
502
503 /*
504 * LED Capability information. SL protected.
505 */
506 mac_led_mode_t mi_led_modes;
507 mac_capab_led_t mi_led;
508
509 /*
510 * MAC address and VLAN lists. SL protected.
511 */
512 mac_address_t *mi_addresses;
513
514 /*
515 * This MAC's table of sub-flows
516 */
517 flow_tab_t *mi_flow_tab; /* WO */
518
519 kstat_t *mi_ksp; /* WO */
520 uint_t mi_kstat_count; /* WO */
521 uint_t mi_nactiveclients; /* SL */
522
523 /* for broadcast and multicast support */
524 struct mac_mcast_addrs_s *mi_mcast_addrs; /* mi_rw_lock */
525 struct mac_bcast_grp_s *mi_bcast_grp; /* mi_rw_lock */
526 uint_t mi_bcast_ngrps; /* mi_rw_lock */
527
528 /* list of MAC clients which opened this MAC */
529 struct mac_client_impl_s *mi_clients_list; /* mi_rw_lock */
530 uint_t mi_nclients; /* mi_rw_lock */
531 struct mac_client_impl_s *mi_single_active_client; /* mi_rw_lock */
532
533 uint32_t mi_margin; /* mi_rw_lock */
534 uint_t mi_sdu_min; /* mi_rw_lock */
535 uint_t mi_sdu_max; /* mi_rw_lock */
536 uint_t mi_sdu_multicast; /* mi_rw_lock */
537
538 /*
539 * Cache of factory MAC addresses provided by the driver. If
540 * the driver doesn't provide multiple factory MAC addresses,
541 * the mi_factory_addr is set to NULL, and mi_factory_addr_num
542 * is set to zero.
543 */
544 mac_factory_addr_t *mi_factory_addr; /* mi_rw_lock */
545 uint_t mi_factory_addr_num; /* mi_rw_lock */
546
547 /* for promiscuous mode support */
548 kmutex_t mi_promisc_lock;
549 mac_cb_t *mi_promisc_list; /* mi_promisc_lock */
550 mac_cb_info_t mi_promisc_cb_info; /* mi_promisc_lock */
551
552 /* cache of rings over this mac_impl */
553 kmutex_t mi_ring_lock;
554 mac_ring_t *mi_ring_freelist; /* mi_ring_lock */
555
556 /*
557 * These are used for caching the properties, if any, for the
558 * primary MAC client. If the MAC client is not yet in place
559 * when the properties are set then we cache them here to be
560 * applied to the MAC client when it is created.
561 */
562 mac_resource_props_t mi_resource_props; /* SL */
563 uint16_t mi_pvid; /* SL */
564
565 minor_t mi_minor; /* WO */
566 uint32_t mi_oref; /* SL */
567 mac_capab_legacy_t mi_capab_legacy; /* WO */
568 dev_t mi_phy_dev; /* WO */
569
570 /*
571 * List of margin value requests added by mac clients. This list is
572 * sorted: the first one has the greatest value.
573 */
574 mac_margin_req_t *mi_mmrp;
575 mac_mtu_req_t *mi_mtrp;
576 char **mi_priv_prop;
577 uint_t mi_priv_prop_count;
578
579 /*
580 * Hybrid I/O related definitions.
581 */
582 mac_capab_share_t mi_share_capab;
583
584 /*
585 * Bridging hooks and limit values. Uses mutex and reference counts
586 * (bridging only) for data path. Limits need no synchronization.
587 */
588 mac_handle_t mi_bridge_link;
589 kmutex_t mi_bridge_lock;
590 uint32_t mi_llimit;
591 uint32_t mi_ldecay;
592
593 /* This should be the last block in this structure */
594 #ifdef DEBUG
595 #define MAC_PERIM_STACK_DEPTH 15
596 int mi_perim_stack_depth;
597 pc_t mi_perim_stack[MAC_PERIM_STACK_DEPTH];
598 #endif
599 };
600
601 /*
602 * The default TX group is the last one in the list.
603 */
604 #define MAC_DEFAULT_TX_GROUP(mip) \
605 (mip)->mi_tx_groups + (mip)->mi_tx_group_count
606
607 /*
608 * The default RX group is the first one in the list
609 */
610 #define MAC_DEFAULT_RX_GROUP(mip) (mip)->mi_rx_groups
611
612 /* Reserved RX rings */
613 #define MAC_RX_RING_RESERVED(m, cnt) { \
614 ASSERT((m)->mi_rxrings_avail >= (cnt)); \
615 (m)->mi_rxrings_rsvd += (cnt); \
616 (m)->mi_rxrings_avail -= (cnt); \
617 }
618
619 /* Released RX rings */
620 #define MAC_RX_RING_RELEASED(m, cnt) { \
621 ASSERT((m)->mi_rxrings_rsvd >= (cnt)); \
622 (m)->mi_rxrings_rsvd -= (cnt); \
623 (m)->mi_rxrings_avail += (cnt); \
624 }
625
626 /* Reserved a RX group */
627 #define MAC_RX_GRP_RESERVED(m) { \
628 ASSERT((m)->mi_rxhwclnt_avail > 0); \
629 (m)->mi_rxhwclnt_avail--; \
630 (m)->mi_rxhwclnt_used++; \
631 }
632
633 /* Released a RX group */
634 #define MAC_RX_GRP_RELEASED(m) { \
635 ASSERT((m)->mi_rxhwclnt_used > 0); \
636 (m)->mi_rxhwclnt_avail++; \
637 (m)->mi_rxhwclnt_used--; \
638 }
639
640 /* Reserved TX rings */
641 #define MAC_TX_RING_RESERVED(m, cnt) { \
642 ASSERT((m)->mi_txrings_avail >= (cnt)); \
643 (m)->mi_txrings_rsvd += (cnt); \
644 (m)->mi_txrings_avail -= (cnt); \
645 }
646 /* Released TX rings */
647 #define MAC_TX_RING_RELEASED(m, cnt) { \
648 ASSERT((m)->mi_txrings_rsvd >= (cnt)); \
649 (m)->mi_txrings_rsvd -= (cnt); \
650 (m)->mi_txrings_avail += (cnt); \
651 }
652
653 /* Reserved a TX group */
654 #define MAC_TX_GRP_RESERVED(m) { \
655 ASSERT((m)->mi_txhwclnt_avail > 0); \
656 (m)->mi_txhwclnt_avail--; \
657 (m)->mi_txhwclnt_used++; \
658 }
659
660 /* Released a TX group */
661 #define MAC_TX_GRP_RELEASED(m) { \
662 ASSERT((m)->mi_txhwclnt_used > 0); \
663 (m)->mi_txhwclnt_avail++; \
664 (m)->mi_txhwclnt_used--; \
665 }
666
667 /* for mi_state_flags */
668 #define MIS_DISABLED 0x0001
669 #define MIS_IS_VNIC 0x0002
670 #define MIS_IS_AGGR 0x0004
671 #define MIS_NOTIFY_DONE 0x0008
672 #define MIS_EXCLUSIVE 0x0010
673 #define MIS_EXCLUSIVE_HELD 0x0020
674 #define MIS_LEGACY 0x0040
675 #define MIS_NO_ACTIVE 0x0080
676 #define MIS_POLL_DISABLE 0x0100
677
678 #define mi_getstat mi_callbacks->mc_getstat
679 #define mi_start mi_callbacks->mc_start
680 #define mi_stop mi_callbacks->mc_stop
681 #define mi_open mi_callbacks->mc_open
682 #define mi_close mi_callbacks->mc_close
683 #define mi_setpromisc mi_callbacks->mc_setpromisc
684 #define mi_multicst mi_callbacks->mc_multicst
685 #define mi_unicst mi_callbacks->mc_unicst
686 #define mi_tx mi_callbacks->mc_tx
687 #define mi_ioctl mi_callbacks->mc_ioctl
688 #define mi_getcapab mi_callbacks->mc_getcapab
689
690 typedef struct mac_notify_task_arg {
691 mac_impl_t *mnt_mip;
692 mac_notify_type_t mnt_type;
693 mac_ring_t *mnt_ring;
694 } mac_notify_task_arg_t;
695
696 /*
697 * The mac_perim_handle_t is an opaque type that encodes the 'mip' pointer
698 * and whether internally a mac_open was done when acquiring the perimeter.
699 */
700 #define MAC_ENCODE_MPH(mph, mh, need_close) \
701 (mph) = (mac_perim_handle_t)((uintptr_t)(mh) | need_close)
702
703 #define MAC_DECODE_MPH(mph, mip, need_close) { \
704 mip = (mac_impl_t *)(((uintptr_t)mph) & ~0x1); \
705 (need_close) = ((uintptr_t)mph & 0x1); \
706 }
707
708 /*
709 * Type of property information that can be returned by a driver.
710 * Valid flags of the pr_flags of the mac_prop_info_t data structure.
711 */
712 #define MAC_PROP_INFO_DEFAULT 0x0001
713 #define MAC_PROP_INFO_RANGE 0x0002
714 #define MAC_PROP_INFO_PERM 0x0004
715
716 /*
717 * Property information. pr_flags is a combination of one of the
718 * MAC_PROP_INFO_* flags, it is reset by the framework before invoking
719 * the driver's prefix_propinfo() entry point.
720 *
721 * Drivers should use MAC_PROP_INFO_SET_*() macros to provide
722 * information about a property.
723 */
724 typedef struct mac_prop_info_state_s {
725 uint8_t pr_flags;
726 uint8_t pr_perm;
727 uint8_t pr_errno;
728 void *pr_default;
729 size_t pr_default_size;
730 mac_propval_range_t *pr_range;
731 uint_t pr_range_cur_count;
732 } mac_prop_info_state_t;
733
734 #define MAC_PROTECT_ENABLED(mcip, type) \
735 (((mcip)->mci_flent-> \
736 fe_resource_props.mrp_mask & MRP_PROTECT) != 0 && \
737 ((mcip)->mci_flent-> \
738 fe_resource_props.mrp_protect.mp_types & (type)) != 0)
739
740 typedef struct mac_client_impl_s mac_client_impl_t;
741
742 extern void mac_init(void);
743 extern int mac_fini(void);
744
745 extern void mac_ndd_ioctl(mac_impl_t *, queue_t *, mblk_t *);
746 extern boolean_t mac_ip_hdr_length_v6(ip6_t *, uint8_t *, uint16_t *,
747 uint8_t *, ip6_frag_t **);
748
749 extern mblk_t *mac_copymsgchain_cksum(mblk_t *);
750 extern mblk_t *mac_fix_cksum(mblk_t *);
751 extern void mac_packet_print(mac_handle_t, mblk_t *);
752 extern void mac_rx_deliver(void *, mac_resource_handle_t, mblk_t *,
753 mac_header_info_t *);
754 extern void mac_tx_notify(mac_impl_t *);
755
756 extern boolean_t mac_callback_find(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
757 extern void mac_callback_add(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
758 extern boolean_t mac_callback_remove(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
759 extern void mac_callback_remove_wait(mac_cb_info_t *);
760 extern void mac_callback_free(mac_cb_t *);
761 extern mac_cb_t *mac_callback_walker_cleanup(mac_cb_info_t *, mac_cb_t **);
762
763 /* in mac_bcast.c */
764 extern void mac_bcast_init(void);
765 extern void mac_bcast_fini(void);
766 extern mac_impl_t *mac_bcast_grp_mip(void *);
767 extern int mac_bcast_add(mac_client_impl_t *, const uint8_t *, uint16_t,
768 mac_addrtype_t);
769 extern void mac_bcast_delete(mac_client_impl_t *, const uint8_t *, uint16_t);
770 extern void mac_bcast_send(void *, void *, mblk_t *, boolean_t);
771 extern void mac_bcast_grp_free(void *);
772 extern void mac_bcast_refresh(mac_impl_t *, mac_multicst_t, void *,
773 boolean_t);
774 extern void mac_client_bcast_refresh(mac_client_impl_t *, mac_multicst_t,
775 void *, boolean_t);
776
777 /*
778 * Grouping functions are used internally by MAC layer.
779 */
780 extern int mac_group_addmac(mac_group_t *, const uint8_t *);
781 extern int mac_group_remmac(mac_group_t *, const uint8_t *);
782 extern int mac_group_addvlan(mac_group_t *, uint16_t);
783 extern int mac_group_remvlan(mac_group_t *, uint16_t);
784 extern int mac_rx_group_add_flow(mac_client_impl_t *, flow_entry_t *,
785 mac_group_t *);
786 extern mblk_t *mac_hwring_tx(mac_ring_handle_t, mblk_t *);
787 extern mblk_t *mac_bridge_tx(mac_impl_t *, mac_ring_handle_t, mblk_t *);
788 extern mac_group_t *mac_reserve_rx_group(mac_client_impl_t *, uint8_t *,
789 boolean_t);
790 extern void mac_release_rx_group(mac_client_impl_t *, mac_group_t *);
791 extern int mac_rx_switch_group(mac_client_impl_t *, mac_group_t *,
792 mac_group_t *);
793 extern mac_ring_t *mac_reserve_tx_ring(mac_impl_t *, mac_ring_t *);
794 extern mac_group_t *mac_reserve_tx_group(mac_client_impl_t *, boolean_t);
795 extern void mac_release_tx_group(mac_client_impl_t *, mac_group_t *);
796 extern void mac_tx_switch_group(mac_client_impl_t *, mac_group_t *,
797 mac_group_t *);
798 extern void mac_rx_switch_grp_to_sw(mac_group_t *);
799
800 /*
801 * MAC address functions are used internally by MAC layer.
802 */
803 extern mac_address_t *mac_find_macaddr(mac_impl_t *, uint8_t *);
804 extern mac_address_t *mac_find_macaddr_vlan(mac_impl_t *, uint8_t *, uint16_t);
805 extern boolean_t mac_check_macaddr_shared(mac_address_t *);
806 extern int mac_update_macaddr(mac_address_t *, uint8_t *);
807 extern void mac_freshen_macaddr(mac_address_t *, uint8_t *);
808 extern void mac_retrieve_macaddr(mac_address_t *, uint8_t *);
809 extern void mac_init_macaddr(mac_impl_t *);
810 extern void mac_fini_macaddr(mac_impl_t *);
811
812 /*
813 * Flow construction/destruction routines.
814 * Not meant to be used by mac clients.
815 */
816 extern int mac_link_flow_init(mac_client_handle_t, flow_entry_t *);
817 extern void mac_link_flow_clean(mac_client_handle_t, flow_entry_t *);
818
819 /*
820 * Fanout update routines called when the link speed of the NIC changes
821 * or when a MAC client's share is unbound.
822 */
823 extern void mac_fanout_recompute_client(mac_client_impl_t *, cpupart_t *);
824 extern void mac_fanout_recompute(mac_impl_t *);
825
826 /*
827 * The following functions are used internally by the MAC layer to
828 * add/remove/update flows associated with a mac_impl_t. They should
829 * never be used directly by MAC clients.
830 */
831 extern int mac_datapath_setup(mac_client_impl_t *, flow_entry_t *, uint32_t);
832 extern void mac_datapath_teardown(mac_client_impl_t *, flow_entry_t *,
833 uint32_t);
834 extern void mac_rx_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
835 uint32_t);
836 extern void mac_tx_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
837 uint32_t);
838 extern void mac_rx_srs_group_teardown(flow_entry_t *, boolean_t);
839 extern void mac_tx_srs_group_teardown(mac_client_impl_t *, flow_entry_t *,
840 uint32_t);
841 extern int mac_rx_classify_flow_quiesce(flow_entry_t *, void *);
842 extern int mac_rx_classify_flow_restart(flow_entry_t *, void *);
843 extern void mac_client_quiesce(mac_client_impl_t *);
844 extern void mac_client_restart(mac_client_impl_t *);
845
846 extern void mac_flow_update_priority(mac_client_impl_t *, flow_entry_t *);
847
848 extern void mac_flow_rem_subflow(flow_entry_t *);
849 extern void mac_rename_flow(flow_entry_t *, const char *);
850 extern void mac_flow_set_name(flow_entry_t *, const char *);
851
852 extern mblk_t *mac_add_vlan_tag(mblk_t *, uint_t, uint16_t);
853 extern mblk_t *mac_add_vlan_tag_chain(mblk_t *, uint_t, uint16_t);
854 extern mblk_t *mac_strip_vlan_tag_chain(mblk_t *);
855 extern void mac_pkt_drop(void *, mac_resource_handle_t, mblk_t *, boolean_t);
856 extern mblk_t *mac_rx_flow(mac_handle_t, mac_resource_handle_t, mblk_t *);
857
858 extern void i_mac_share_alloc(mac_client_impl_t *);
859 extern void i_mac_share_free(mac_client_impl_t *);
860 extern void i_mac_perim_enter(mac_impl_t *);
861 extern void i_mac_perim_exit(mac_impl_t *);
862 extern int i_mac_perim_enter_nowait(mac_impl_t *);
863 extern void i_mac_tx_srs_notify(mac_impl_t *, mac_ring_handle_t);
864 extern int mac_hold(const char *, mac_impl_t **);
865 extern void mac_rele(mac_impl_t *);
866 extern int i_mac_disable(mac_impl_t *);
867 extern void i_mac_notify(mac_impl_t *, mac_notify_type_t);
868 extern void i_mac_notify_exit(mac_impl_t *);
869 extern void mac_rx_group_unmark(mac_group_t *, uint_t);
870 extern void mac_tx_client_flush(mac_client_impl_t *);
871 extern void mac_tx_client_block(mac_client_impl_t *);
872 extern void mac_tx_client_unblock(mac_client_impl_t *);
873 extern void mac_tx_invoke_callbacks(mac_client_impl_t *, mac_tx_cookie_t);
874 extern int i_mac_promisc_set(mac_impl_t *, boolean_t);
875 extern void i_mac_promisc_walker_cleanup(mac_impl_t *);
876 extern mactype_t *mactype_getplugin(const char *);
877 extern void mac_addr_factory_init(mac_impl_t *);
878 extern void mac_addr_factory_fini(mac_impl_t *);
879 extern void mac_register_priv_prop(mac_impl_t *, char **);
880 extern void mac_unregister_priv_prop(mac_impl_t *);
881 extern int mac_init_rings(mac_impl_t *, mac_ring_type_t);
882 extern void mac_free_rings(mac_impl_t *, mac_ring_type_t);
883 extern void mac_compare_ddi_handle(mac_group_t *, uint_t, mac_ring_t *);
884
885 extern int mac_start_group(mac_group_t *);
886 extern void mac_stop_group(mac_group_t *);
887 extern int mac_start_ring(mac_ring_t *);
888 extern void mac_stop_ring(mac_ring_t *);
889 extern int mac_add_macaddr_vlan(mac_impl_t *, mac_group_t *, uint8_t *,
890 uint16_t, boolean_t);
891 extern int mac_remove_macaddr_vlan(mac_address_t *, uint16_t);
892
893 extern void mac_set_group_state(mac_group_t *, mac_group_state_t);
894 extern void mac_group_add_client(mac_group_t *, mac_client_impl_t *);
895 extern void mac_group_remove_client(mac_group_t *, mac_client_impl_t *);
896
897 extern int i_mac_group_add_ring(mac_group_t *, mac_ring_t *, int);
898 extern void i_mac_group_rem_ring(mac_group_t *, mac_ring_t *, boolean_t);
899 extern int mac_group_ring_modify(mac_client_impl_t *, mac_group_t *,
900 mac_group_t *);
901 extern void mac_poll_state_change(mac_handle_t, boolean_t);
902
903 extern mac_group_state_t mac_group_next_state(mac_group_t *,
904 mac_client_impl_t **, mac_group_t *, boolean_t);
905
906 extern mblk_t *mac_protect_check(mac_client_handle_t, mblk_t *);
907 extern int mac_protect_set(mac_client_handle_t, mac_resource_props_t *);
908 extern boolean_t mac_protect_enabled(mac_client_handle_t, uint32_t);
909 extern int mac_protect_validate(mac_resource_props_t *);
910 extern void mac_protect_update(mac_resource_props_t *, mac_resource_props_t *);
911 extern void mac_protect_update_mac_token(mac_client_impl_t *);
912 extern void mac_protect_intercept_dynamic(mac_client_impl_t *, mblk_t *);
913 extern void mac_protect_flush_dynamic(mac_client_impl_t *);
914 extern void mac_protect_cancel_timer(mac_client_impl_t *);
915 extern void mac_protect_init(mac_client_impl_t *);
916 extern void mac_protect_fini(mac_client_impl_t *);
917
918 extern int mac_set_resources(mac_handle_t, mac_resource_props_t *);
919 extern void mac_get_resources(mac_handle_t, mac_resource_props_t *);
920 extern void mac_get_effective_resources(mac_handle_t, mac_resource_props_t *);
921 extern void mac_set_promisc_filtered(mac_client_handle_t, boolean_t);
922 extern boolean_t mac_get_promisc_filtered(mac_client_handle_t);
923
924 extern cpupart_t *mac_pset_find(mac_resource_props_t *, boolean_t *);
925 extern void mac_set_pool_effective(boolean_t, cpupart_t *,
926 mac_resource_props_t *, mac_resource_props_t *);
927 extern void mac_set_rings_effective(mac_client_impl_t *);
928 extern mac_client_impl_t *mac_check_primary_relocation(mac_client_impl_t *,
929 boolean_t);
930
931 /* Global callbacks into the bridging module (when loaded) */
932 extern mac_bridge_tx_t mac_bridge_tx_cb;
933 extern mac_bridge_rx_t mac_bridge_rx_cb;
934 extern mac_bridge_ref_t mac_bridge_ref_cb;
935 extern mac_bridge_ls_t mac_bridge_ls_cb;
936
937 /*
938 * MAC Transceiver related functions
939 */
940 struct mac_transceiver_info {
941 boolean_t mti_present;
942 boolean_t mti_usable;
943 };
944
945 extern void mac_transceiver_init(mac_impl_t *);
946 extern int mac_transceiver_count(mac_handle_t, uint_t *);
947 extern int mac_transceiver_info(mac_handle_t, uint_t, boolean_t *, boolean_t *);
948 extern int mac_transceiver_read(mac_handle_t, uint_t, uint_t, void *, size_t,
949 off_t, size_t *);
950
951 /*
952 * MAC LED related functions
953 */
954 #define MAC_LED_ALL (MAC_LED_DEFAULT | MAC_LED_OFF | MAC_LED_IDENT | \
955 MAC_LED_ON)
956 extern void mac_led_init(mac_impl_t *);
957 extern int mac_led_get(mac_handle_t, mac_led_mode_t *, mac_led_mode_t *);
958 extern int mac_led_set(mac_handle_t, mac_led_mode_t);
959
960 #ifdef __cplusplus
961 }
962 #endif
963
964 #endif /* _SYS_MAC_IMPL_H */