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