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