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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_MAC_IMPL_H 27 #define _SYS_MAC_IMPL_H 28 29 #include <sys/modhash.h> 30 #include <sys/mac_client.h> 31 #include <sys/mac_provider.h> 32 #include <sys/note.h> 33 #include <net/if.h> 34 #include <sys/mac_flow_impl.h> 35 #include <netinet/ip6.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /* 42 * This is the first minor number available for MAC provider private 43 * use. This makes it possible to deliver a driver that is both a MAC 44 * provider and a regular character/block device. See PSARC 2009/380 45 * for more detail about the construction of such devices. The value 46 * chosen leaves half of the 32-bit minor numbers (which are really 47 * only 18 bits wide) available for driver private use. Drivers can 48 * easily identify their private number by the presence of this value 49 * in the bits that make up the minor number, since its just the 50 * highest bit available for such minor numbers. 51 */ 52 #define MAC_PRIVATE_MINOR ((MAXMIN32 + 1) / 2) 53 54 /* 55 * The maximum minor number that corresponds to a real instance. This 56 * limits the number of physical ports that a mac provider can offer. 57 * Note that this macro must be synchronized with DLS_MAX_MINOR in 58 * <sys/dls.h> 59 */ 60 #define MAC_MAX_MINOR 1000 61 62 typedef struct mac_margin_req_s mac_margin_req_t; 63 64 struct mac_margin_req_s { 65 mac_margin_req_t *mmr_nextp; 66 uint_t mmr_ref; 67 uint32_t mmr_margin; 68 }; 69 70 /* Generic linked chain type */ 71 typedef struct mac_chain_s { 72 struct mac_chain_s *next; 73 void *item; 74 } mac_chain_t; 75 76 /* 77 * Generic mac callback list manipulation structures and macros. The mac_cb_t 78 * represents a general callback list element embedded in a particular 79 * data structure such as a mac_notify_cb_t or a mac_promisc_impl_t. 80 * The mac_cb_info_t represents general information about list walkers. 81 * Please see the comments above mac_callback_add for more information. 82 */ 83 /* mcb_flags */ 84 #define MCB_CONDEMNED 0x1 /* Logically deleted */ 85 #define MCB_NOTIFY_CB_T 0x2 86 #define MCB_TX_NOTIFY_CB_T 0x4 87 88 typedef struct mac_cb_s { 89 struct mac_cb_s *mcb_nextp; /* Linked list of callbacks */ 90 void *mcb_objp; /* Ptr to enclosing object */ 91 size_t mcb_objsize; /* Sizeof the enclosing obj */ 92 uint_t mcb_flags; 93 } mac_cb_t; 94 95 typedef struct mac_cb_info_s { 96 kmutex_t *mcbi_lockp; 97 kcondvar_t mcbi_cv; 98 uint_t mcbi_del_cnt; /* Deleted callback cnt */ 99 uint_t mcbi_walker_cnt; /* List walker count */ 100 } mac_cb_info_t; 101 102 typedef struct mac_notify_cb_s { 103 mac_cb_t mncb_link; /* Linked list of callbacks */ 104 mac_notify_t mncb_fn; /* callback function */ 105 void *mncb_arg; /* callback argument */ 106 struct mac_impl_s *mncb_mip; 107 } mac_notify_cb_t; 108 109 /* 110 * mac_callback_add(listinfo, listhead, listelement) 111 * mac_callback_remove(listinfo, listhead, listelement) 112 */ 113 typedef boolean_t (*mcb_func_t)(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 114 115 #define MAC_CALLBACK_WALKER_INC(mcbi) { \ 116 mutex_enter((mcbi)->mcbi_lockp); \ 117 (mcbi)->mcbi_walker_cnt++; \ 118 mutex_exit((mcbi)->mcbi_lockp); \ 119 } 120 121 #define MAC_CALLBACK_WALKER_INC_HELD(mcbi) (mcbi)->mcbi_walker_cnt++; 122 123 #define MAC_CALLBACK_WALKER_DCR(mcbi, headp) { \ 124 mac_cb_t *rmlist; \ 125 \ 126 mutex_enter((mcbi)->mcbi_lockp); \ 127 if (--(mcbi)->mcbi_walker_cnt == 0 && (mcbi)->mcbi_del_cnt != 0) { \ 128 rmlist = mac_callback_walker_cleanup((mcbi), headp); \ 129 mac_callback_free(rmlist); \ 130 cv_broadcast(&(mcbi)->mcbi_cv); \ 131 } \ 132 mutex_exit((mcbi)->mcbi_lockp); \ 133 } 134 135 #define MAC_PROMISC_WALKER_INC(mip) \ 136 MAC_CALLBACK_WALKER_INC(&(mip)->mi_promisc_cb_info) 137 138 #define MAC_PROMISC_WALKER_DCR(mip) { \ 139 mac_cb_info_t *mcbi; \ 140 \ 141 mcbi = &(mip)->mi_promisc_cb_info; \ 142 mutex_enter(mcbi->mcbi_lockp); \ 143 if (--mcbi->mcbi_walker_cnt == 0 && mcbi->mcbi_del_cnt != 0) { \ 144 i_mac_promisc_walker_cleanup(mip); \ 145 cv_broadcast(&mcbi->mcbi_cv); \ 146 } \ 147 mutex_exit(mcbi->mcbi_lockp); \ 148 } 149 150 typedef struct mactype_s { 151 const char *mt_ident; 152 uint32_t mt_ref; 153 uint_t mt_type; 154 uint_t mt_nativetype; 155 size_t mt_addr_length; 156 uint8_t *mt_brdcst_addr; 157 mactype_ops_t mt_ops; 158 mac_stat_info_t *mt_stats; /* array of mac_stat_info_t elements */ 159 size_t mt_statcount; /* number of elements in mt_stats */ 160 mac_ndd_mapping_t *mt_mapping; 161 size_t mt_mappingcount; 162 } mactype_t; 163 164 /* 165 * Multiple rings implementation. 166 */ 167 typedef enum { 168 MAC_GROUP_STATE_UNINIT = 0, /* initial state of data structure */ 169 MAC_GROUP_STATE_REGISTERED, /* hooked with h/w group */ 170 MAC_GROUP_STATE_RESERVED, /* group is reserved and opened */ 171 MAC_GROUP_STATE_SHARED /* default group shared among */ 172 /* multiple mac clients */ 173 } mac_group_state_t; 174 175 typedef struct mac_ring_s mac_ring_t; 176 typedef struct mac_group_s mac_group_t; 177 178 /* 179 * Ring data structure for ring control and management. 180 */ 181 typedef enum { 182 MR_FREE, /* Available for assignment to flows */ 183 MR_NEWLY_ADDED, /* Just assigned to another group */ 184 MR_INUSE /* Assigned to an SRS */ 185 } mac_ring_state_t; 186 187 /* mr_flag values */ 188 #define MR_INCIPIENT 0x1 189 #define MR_CONDEMNED 0x2 190 #define MR_QUIESCE 0x4 191 192 struct mac_ring_s { 193 int mr_index; /* index in the original list */ 194 mac_ring_type_t mr_type; /* ring type */ 195 mac_ring_t *mr_next; /* next ring in the chain */ 196 mac_group_handle_t mr_gh; /* reference to group */ 197 198 mac_classify_type_t mr_classify_type; /* HW vs SW */ 199 struct mac_soft_ring_set_s *mr_srs; /* associated SRS */ 200 uint_t mr_refcnt; /* Ring references */ 201 /* ring generation no. to guard against drivers using stale rings */ 202 uint64_t mr_gen_num; 203 204 kmutex_t mr_lock; 205 kcondvar_t mr_cv; /* mr_lock */ 206 mac_ring_state_t mr_state; /* mr_lock */ 207 uint_t mr_flag; /* mr_lock */ 208 209 mac_ring_info_t mr_info; /* driver supplied info */ 210 }; 211 #define mr_driver mr_info.mri_driver 212 #define mr_start mr_info.mri_start 213 #define mr_stop mr_info.mri_stop 214 215 #define MAC_RING_MARK(mr, flag) \ 216 (mr)->mr_flag |= flag; 217 218 #define MAC_RING_UNMARK(mr, flag) \ 219 (mr)->mr_flag &= ~flag; 220 221 /* 222 * Reference hold and release on mac_ring_t 'mr' 223 */ 224 #define MR_REFHOLD_LOCKED(mr) { \ 225 ASSERT(MUTEX_HELD(&mr->mr_lock)); \ 226 (mr)->mr_refcnt++; \ 227 } 228 229 #define MR_REFRELE(mr) { \ 230 mutex_enter(&(mr)->mr_lock); \ 231 ASSERT((mr)->mr_refcnt != 0); \ 232 (mr)->mr_refcnt--; \ 233 if ((mr)->mr_refcnt == 0 && \ 234 ((mr)->mr_flag & (MR_CONDEMNED | MR_QUIESCE))) \ 235 cv_signal(&(mr)->mr_cv); \ 236 mutex_exit(&(mr)->mr_lock); \ 237 } 238 239 /* 240 * Per mac client flow information associated with a RX group. 241 * The entire structure is SL protected. 242 */ 243 typedef struct mac_grp_client { 244 struct mac_grp_client *mgc_next; 245 struct mac_client_impl_s *mgc_client; 246 } mac_grp_client_t; 247 248 #define MAC_RX_GROUP_NO_CLIENT(g) ((g)->mrg_clients == NULL) 249 250 #define MAC_RX_GROUP_ONLY_CLIENT(g) \ 251 ((((g)->mrg_clients != NULL) && \ 252 ((g)->mrg_clients->mgc_next == NULL)) ? \ 253 (g)->mrg_clients->mgc_client : NULL) 254 255 /* 256 * Common ring group data structure for ring control and management. 257 * The entire structure is SL protected 258 */ 259 struct mac_group_s { 260 int mrg_index; /* index in the list */ 261 mac_ring_type_t mrg_type; /* ring type */ 262 mac_group_state_t mrg_state; /* state of the group */ 263 mac_group_t *mrg_next; /* next ring in the chain */ 264 mac_handle_t mrg_mh; /* reference to MAC */ 265 mac_ring_t *mrg_rings; /* grouped rings */ 266 uint_t mrg_cur_count; /* actual size of group */ 267 268 mac_grp_client_t *mrg_clients; /* clients list */ 269 270 struct mac_client_impl_s *mrg_tx_client; /* TX client pointer */ 271 mac_group_info_t mrg_info; /* driver supplied info */ 272 }; 273 274 #define mrg_driver mrg_info.mgi_driver 275 #define mrg_start mrg_info.mgi_start 276 #define mrg_stop mrg_info.mgi_stop 277 278 #define GROUP_INTR_HANDLE(g) (g)->mrg_info.mgi_intr.mi_handle 279 #define GROUP_INTR_ENABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_enable 280 #define GROUP_INTR_DISABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_disable 281 282 #define MAC_DEFAULT_GROUP(mh) (((mac_impl_t *)mh)->mi_rx_groups) 283 284 #define MAC_RING_TX(mhp, rh, mp, rest) { \ 285 mac_ring_handle_t mrh = rh; \ 286 mac_impl_t *mimpl = (mac_impl_t *)mhp; \ 287 /* \ 288 * Send packets through a selected tx ring, or through the \ 289 * default handler if there is no selected ring. \ 290 */ \ 291 if (mrh == NULL) \ 292 mrh = mimpl->mi_default_tx_ring; \ 293 if (mrh == NULL) { \ 294 rest = mimpl->mi_tx(mimpl->mi_driver, mp); \ 295 } else { \ 296 rest = mac_hwring_tx(mrh, mp); \ 297 } \ 298 } 299 300 /* 301 * This is the final stop before reaching the underlying driver 302 * or aggregation, so this is where the bridging hook is implemented. 303 * Packets that are bridged will return through mac_bridge_tx(), with 304 * rh nulled out if the bridge chooses to send output on a different 305 * link due to forwarding. 306 */ 307 #define MAC_TX(mip, rh, mp, share_bound) { \ 308 /* \ 309 * If there is a bound Hybrid I/O share, send packets through \ 310 * the default tx ring. (When there's a bound Hybrid I/O share, \ 311 * the tx rings of this client are mapped in the guest domain \ 312 * and not accessible from here.) \ 313 */ \ 314 _NOTE(CONSTANTCONDITION) \ 315 if (share_bound) \ 316 rh = NULL; \ 317 /* \ 318 * Grab the proper transmit pointer and handle. Special \ 319 * optimization: we can test mi_bridge_link itself atomically, \ 320 * and if that indicates no bridge send packets through tx ring.\ 321 */ \ 322 if (mip->mi_bridge_link == NULL) { \ 323 MAC_RING_TX(mip, rh, mp, mp); \ 324 } else { \ 325 mp = mac_bridge_tx(mip, rh, mp); \ 326 } \ 327 } 328 329 /* mci_tx_flag */ 330 #define MCI_TX_QUIESCE 0x1 331 332 typedef struct mac_factory_addr_s { 333 boolean_t mfa_in_use; 334 uint8_t mfa_addr[MAXMACADDRLEN]; 335 struct mac_client_impl_s *mfa_client; 336 } mac_factory_addr_t; 337 338 typedef struct mac_mcast_addrs_s { 339 struct mac_mcast_addrs_s *mma_next; 340 uint8_t mma_addr[MAXMACADDRLEN]; 341 int mma_ref; 342 } mac_mcast_addrs_t; 343 344 typedef enum { 345 MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED = 1, /* hardware steering */ 346 MAC_ADDRESS_TYPE_UNICAST_PROMISC /* promiscuous mode */ 347 } mac_address_type_t; 348 349 typedef struct mac_impl_s mac_impl_t; 350 351 typedef struct mac_address_s { 352 mac_address_type_t ma_type; /* address type */ 353 int ma_nusers; /* number of users */ 354 /* of that address */ 355 struct mac_address_s *ma_next; /* next address */ 356 uint8_t ma_addr[MAXMACADDRLEN]; /* address value */ 357 size_t ma_len; /* address length */ 358 mac_group_t *ma_group; /* asscociated group */ 359 mac_impl_t *ma_mip; /* MAC handle */ 360 } mac_address_t; 361 362 extern krwlock_t i_mac_impl_lock; 363 extern mod_hash_t *i_mac_impl_hash; 364 extern kmem_cache_t *i_mac_impl_cachep; 365 extern uint_t i_mac_impl_count; 366 367 /* 368 * Each registered MAC is associated with a mac_impl_t structure. The 369 * structure represents the undelying hardware, in terms of definition, 370 * resources (transmit, receive rings etc.), callback functions etc. It 371 * also holds the table of MAC clients that are configured on the device. 372 * The table is used for classifying incoming packets in software. 373 * 374 * The protection scheme uses 2 elements, a coarse serialization mechanism 375 * called perimeter and a finer traditional lock based scheme. More details 376 * can be found in the big block comment in mac.c. 377 * 378 * The protection scheme for each member of the mac_impl_t is described below. 379 * 380 * Write Once Only (WO): Typically these don't change for the lifetime of the 381 * data structure. For example something in mac_impl_t that stays the same 382 * from mac_register to mac_unregister, or something in a mac_client_impl_t 383 * that stays the same from mac_client_open to mac_client_close. 384 * 385 * Serializer (SL): Protected by the Serializer. All SLOP operations on a 386 * mac endpoint go through the serializer. MTOPs don't care about reading 387 * these fields atomically. 388 * 389 * Lock: Traditional mutex/rw lock. Modify operations still go through the 390 * mac serializer, the lock helps synchronize readers with writers. 391 */ 392 struct mac_impl_s { 393 krwlock_t mi_rw_lock; 394 char mi_name[LIFNAMSIZ]; /* WO */ 395 uint32_t mi_state_flags; 396 void *mi_driver; /* Driver private, WO */ 397 mac_info_t mi_info; /* WO */ 398 mactype_t *mi_type; /* WO */ 399 void *mi_pdata; /* WO */ 400 size_t mi_pdata_size; /* WO */ 401 mac_callbacks_t *mi_callbacks; /* WO */ 402 dev_info_t *mi_dip; /* WO */ 403 uint32_t mi_ref; /* i_mac_impl_lock */ 404 uint_t mi_active; /* SL */ 405 link_state_t mi_linkstate; /* none */ 406 link_state_t mi_lowlinkstate; /* none */ 407 link_state_t mi_lastlowlinkstate; /* none */ 408 uint_t mi_devpromisc; /* SL */ 409 kmutex_t mi_lock; 410 uint8_t mi_addr[MAXMACADDRLEN]; /* mi_rw_lock */ 411 uint8_t mi_dstaddr[MAXMACADDRLEN]; /* mi_rw_lock */ 412 boolean_t mi_dstaddr_set; 413 414 /* 415 * The mac perimeter. All client initiated create/modify operations 416 * on a mac end point go through this. 417 */ 418 kmutex_t mi_perim_lock; 419 kthread_t *mi_perim_owner; /* mi_perim_lock */ 420 uint_t mi_perim_ocnt; /* mi_perim_lock */ 421 kcondvar_t mi_perim_cv; /* mi_perim_lock */ 422 423 /* mac notification callbacks */ 424 kmutex_t mi_notify_lock; 425 mac_cb_info_t mi_notify_cb_info; /* mi_notify_lock */ 426 mac_cb_t *mi_notify_cb_list; /* mi_notify_lock */ 427 kthread_t *mi_notify_thread; /* mi_notify_lock */ 428 uint_t mi_notify_bits; /* mi_notify_lock */ 429 430 uint32_t mi_v12n_level; /* Virt'ion readiness */ 431 432 /* 433 * RX groups, ring capability 434 * Fields of this block are SL protected. 435 */ 436 mac_group_type_t mi_rx_group_type; /* grouping type */ 437 uint_t mi_rx_group_count; 438 mac_group_t *mi_rx_groups; 439 440 mac_capab_rings_t mi_rx_rings_cap; 441 442 /* 443 * TX groups and ring capability, SL Protected. 444 */ 445 mac_group_type_t mi_tx_group_type; /* grouping type */ 446 uint_t mi_tx_group_count; 447 uint_t mi_tx_group_free; 448 mac_group_t *mi_tx_groups; 449 450 mac_capab_rings_t mi_tx_rings_cap; 451 452 mac_ring_handle_t mi_default_tx_ring; 453 454 /* 455 * MAC address list. SL protected. 456 */ 457 mac_address_t *mi_addresses; 458 459 /* 460 * This MAC's table of sub-flows 461 */ 462 flow_tab_t *mi_flow_tab; /* WO */ 463 464 kstat_t *mi_ksp; /* WO */ 465 uint_t mi_kstat_count; /* WO */ 466 uint_t mi_nactiveclients; /* SL */ 467 468 /* for broadcast and multicast support */ 469 struct mac_mcast_addrs_s *mi_mcast_addrs; /* mi_rw_lock */ 470 struct mac_bcast_grp_s *mi_bcast_grp; /* mi_rw_lock */ 471 uint_t mi_bcast_ngrps; /* mi_rw_lock */ 472 473 /* list of MAC clients which opened this MAC */ 474 struct mac_client_impl_s *mi_clients_list; /* mi_rw_lock */ 475 uint_t mi_nclients; /* mi_rw_lock */ 476 struct mac_client_impl_s *mi_single_active_client; /* mi_rw_lock */ 477 478 uint32_t mi_margin; /* mi_rw_lock */ 479 uint_t mi_sdu_min; /* mi_rw_lock */ 480 uint_t mi_sdu_max; /* mi_rw_lock */ 481 482 /* 483 * Cache of factory MAC addresses provided by the driver. If 484 * the driver doesn't provide multiple factory MAC addresses, 485 * the mi_factory_addr is set to NULL, and mi_factory_addr_num 486 * is set to zero. 487 */ 488 mac_factory_addr_t *mi_factory_addr; /* mi_rw_lock */ 489 uint_t mi_factory_addr_num; /* mi_rw_lock */ 490 491 /* for promiscuous mode support */ 492 kmutex_t mi_promisc_lock; 493 mac_cb_t *mi_promisc_list; /* mi_promisc_lock */ 494 mac_cb_info_t mi_promisc_cb_info; /* mi_promisc_lock */ 495 496 /* cache of rings over this mac_impl */ 497 kmutex_t mi_ring_lock; 498 mac_ring_t *mi_ring_freelist; /* mi_ring_lock */ 499 500 /* 501 * These are used for caching the properties, if any, for the 502 * primary MAC client. If the MAC client is not yet in place 503 * when the properties are set then we cache them here to be 504 * applied to the MAC client when it is created. 505 */ 506 mac_resource_props_t mi_resource_props; /* SL */ 507 uint16_t mi_pvid; /* SL */ 508 509 minor_t mi_minor; /* WO */ 510 uint32_t mi_oref; /* SL */ 511 mac_capab_legacy_t mi_capab_legacy; /* WO */ 512 dev_t mi_phy_dev; /* WO */ 513 514 /* 515 * List of margin value requests added by mac clients. This list is 516 * sorted: the first one has the greatest value. 517 */ 518 mac_margin_req_t *mi_mmrp; 519 mac_priv_prop_t *mi_priv_prop; 520 uint_t mi_priv_prop_count; 521 522 /* 523 * Hybrid I/O related definitions. 524 */ 525 mac_capab_share_t mi_share_capab; 526 527 /* 528 * Bridging hooks and limit values. Uses mutex and reference counts 529 * (bridging only) for data path. Limits need no synchronization. 530 */ 531 mac_handle_t mi_bridge_link; 532 kmutex_t mi_bridge_lock; 533 uint32_t mi_llimit; 534 uint32_t mi_ldecay; 535 536 /* This should be the last block in this structure */ 537 #ifdef DEBUG 538 #define MAC_PERIM_STACK_DEPTH 15 539 int mi_perim_stack_depth; 540 pc_t mi_perim_stack[MAC_PERIM_STACK_DEPTH]; 541 #endif 542 }; 543 544 /* for mi_state_flags */ 545 #define MIS_DISABLED 0x0001 546 #define MIS_IS_VNIC 0x0002 547 #define MIS_IS_AGGR 0x0004 548 #define MIS_NOTIFY_DONE 0x0008 549 #define MIS_EXCLUSIVE 0x0010 550 #define MIS_EXCLUSIVE_HELD 0x0020 551 #define MIS_LEGACY 0x0040 552 #define MIS_NO_ACTIVE 0x0080 553 #define MIS_POLL_DISABLE 0x0100 554 555 #define mi_getstat mi_callbacks->mc_getstat 556 #define mi_start mi_callbacks->mc_start 557 #define mi_stop mi_callbacks->mc_stop 558 #define mi_open mi_callbacks->mc_open 559 #define mi_close mi_callbacks->mc_close 560 #define mi_setpromisc mi_callbacks->mc_setpromisc 561 #define mi_multicst mi_callbacks->mc_multicst 562 #define mi_unicst mi_callbacks->mc_unicst 563 #define mi_tx mi_callbacks->mc_tx 564 #define mi_ioctl mi_callbacks->mc_ioctl 565 #define mi_getcapab mi_callbacks->mc_getcapab 566 567 typedef struct mac_notify_task_arg { 568 mac_impl_t *mnt_mip; 569 mac_notify_type_t mnt_type; 570 mac_ring_t *mnt_ring; 571 } mac_notify_task_arg_t; 572 573 typedef enum { 574 MAC_RX_NO_RESERVE, 575 MAC_RX_RESERVE_DEFAULT, 576 MAC_RX_RESERVE_NONDEFAULT 577 } mac_rx_group_reserve_type_t; 578 579 /* 580 * XXX All MAC_DBG_PRTs must be replaced with call to dtrace probes. For now 581 * it may be easier to have these printfs for easier debugging 582 */ 583 #ifdef DEBUG 584 extern int mac_dbg; 585 #define MAC_DBG_PRT(a) if (mac_dbg > 0) {(void) printf a; } 586 #else 587 #define MAC_DBG_PRT(a) 588 #endif 589 590 /* 591 * The mac_perim_handle_t is an opaque type that encodes the 'mip' pointer 592 * and whether internally a mac_open was done when acquiring the perimeter. 593 */ 594 #define MAC_ENCODE_MPH(mph, mh, need_close) \ 595 (mph) = (mac_perim_handle_t)((uintptr_t)(mh) | need_close) 596 597 #define MAC_DECODE_MPH(mph, mip, need_close) { \ 598 mip = (mac_impl_t *)(((uintptr_t)mph) & ~0x1); \ 599 (need_close) = ((uintptr_t)mph & 0x1); \ 600 } 601 602 typedef struct mac_client_impl_s mac_client_impl_t; 603 604 extern void mac_init(void); 605 extern int mac_fini(void); 606 607 extern void mac_stat_create(mac_impl_t *); 608 extern void mac_stat_destroy(mac_impl_t *); 609 extern uint64_t mac_stat_default(mac_impl_t *, uint_t); 610 extern void mac_ndd_ioctl(mac_impl_t *, queue_t *, mblk_t *); 611 extern void mac_create_soft_ring_kstats(mac_impl_t *, int32_t); 612 extern boolean_t mac_ip_hdr_length_v6(mblk_t *, ip6_t *, uint16_t *, 613 uint8_t *); 614 615 extern mblk_t *mac_copymsgchain_cksum(mblk_t *); 616 extern mblk_t *mac_fix_cksum(mblk_t *); 617 extern void mac_packet_print(mac_handle_t, mblk_t *); 618 extern void mac_rx_deliver(void *, mac_resource_handle_t, mblk_t *, 619 mac_header_info_t *); 620 extern void mac_tx_notify(mac_impl_t *); 621 622 extern boolean_t mac_callback_find(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 623 extern void mac_callback_add(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 624 extern boolean_t mac_callback_remove(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 625 extern void mac_callback_remove_wait(mac_cb_info_t *); 626 extern void mac_callback_free(mac_cb_t *); 627 extern mac_cb_t *mac_callback_walker_cleanup(mac_cb_info_t *, mac_cb_t **); 628 629 /* in mac_bcast.c */ 630 extern void mac_bcast_init(void); 631 extern void mac_bcast_fini(void); 632 extern mac_impl_t *mac_bcast_grp_mip(void *); 633 extern int mac_bcast_add(mac_client_impl_t *, const uint8_t *, uint16_t, 634 mac_addrtype_t); 635 extern void mac_bcast_delete(mac_client_impl_t *, const uint8_t *, uint16_t); 636 extern void mac_bcast_send(void *, void *, mblk_t *, boolean_t); 637 extern void mac_bcast_grp_free(void *); 638 extern void mac_bcast_refresh(mac_impl_t *, mac_multicst_t, void *, 639 boolean_t); 640 extern void mac_client_bcast_refresh(mac_client_impl_t *, mac_multicst_t, 641 void *, boolean_t); 642 643 /* 644 * Grouping functions are used internally by MAC layer. 645 */ 646 extern int mac_group_addmac(mac_group_t *, const uint8_t *); 647 extern int mac_group_remmac(mac_group_t *, const uint8_t *); 648 extern int mac_rx_group_add_flow(mac_client_impl_t *, flow_entry_t *, 649 mac_group_t *); 650 extern mblk_t *mac_hwring_tx(mac_ring_handle_t, mblk_t *); 651 extern mblk_t *mac_bridge_tx(mac_impl_t *, mac_ring_handle_t, mblk_t *); 652 extern mac_ring_t *mac_reserve_tx_ring(mac_impl_t *, mac_ring_t *); 653 extern void mac_release_tx_ring(mac_ring_handle_t); 654 extern mac_group_t *mac_reserve_tx_group(mac_impl_t *, mac_share_handle_t); 655 extern void mac_release_tx_group(mac_impl_t *, mac_group_t *); 656 657 /* 658 * MAC address functions are used internally by MAC layer. 659 */ 660 extern mac_address_t *mac_find_macaddr(mac_impl_t *, uint8_t *); 661 extern boolean_t mac_check_macaddr_shared(mac_address_t *); 662 extern int mac_update_macaddr(mac_address_t *, uint8_t *); 663 extern void mac_freshen_macaddr(mac_address_t *, uint8_t *); 664 extern void mac_retrieve_macaddr(mac_address_t *, uint8_t *); 665 extern void mac_init_macaddr(mac_impl_t *); 666 extern void mac_fini_macaddr(mac_impl_t *); 667 668 /* 669 * Flow construction/destruction routines. 670 * Not meant to be used by mac clients. 671 */ 672 extern int mac_link_flow_init(mac_client_handle_t, flow_entry_t *); 673 extern void mac_link_flow_clean(mac_client_handle_t, flow_entry_t *); 674 675 /* 676 * Fanout update routines called when the link speed of the NIC changes 677 * or when a MAC client's share is unbound. 678 */ 679 extern void mac_fanout_recompute_client(mac_client_impl_t *); 680 extern void mac_fanout_recompute(mac_impl_t *); 681 682 /* 683 * The following functions are used internally by the MAC layer to 684 * add/remove/update flows associated with a mac_impl_t. They should 685 * never be used directly by MAC clients. 686 */ 687 extern int mac_datapath_setup(mac_client_impl_t *, flow_entry_t *, uint32_t); 688 extern void mac_datapath_teardown(mac_client_impl_t *, flow_entry_t *, 689 uint32_t); 690 extern void mac_srs_group_setup(mac_client_impl_t *, flow_entry_t *, 691 mac_group_t *, uint32_t); 692 extern void mac_srs_group_teardown(mac_client_impl_t *, flow_entry_t *, 693 uint32_t); 694 extern int mac_rx_classify_flow_quiesce(flow_entry_t *, void *); 695 extern int mac_rx_classify_flow_restart(flow_entry_t *, void *); 696 extern void mac_tx_client_quiesce(mac_client_impl_t *, uint_t); 697 extern void mac_tx_client_restart(mac_client_impl_t *); 698 extern void mac_client_quiesce(mac_client_impl_t *); 699 extern void mac_client_restart(mac_client_impl_t *); 700 701 extern void mac_flow_update_priority(mac_client_impl_t *, flow_entry_t *); 702 703 extern void mac_flow_rem_subflow(flow_entry_t *); 704 extern void mac_rename_flow(flow_entry_t *, const char *); 705 extern void mac_flow_set_name(flow_entry_t *, const char *); 706 707 extern mblk_t *mac_add_vlan_tag(mblk_t *, uint_t, uint16_t); 708 extern mblk_t *mac_add_vlan_tag_chain(mblk_t *, uint_t, uint16_t); 709 extern mblk_t *mac_strip_vlan_tag_chain(mblk_t *); 710 extern void mac_pkt_drop(void *, mac_resource_handle_t, mblk_t *, boolean_t); 711 extern mblk_t *mac_rx_flow(mac_handle_t, mac_resource_handle_t, mblk_t *); 712 713 extern void i_mac_share_alloc(mac_client_impl_t *); 714 extern void i_mac_share_free(mac_client_impl_t *); 715 extern void i_mac_perim_enter(mac_impl_t *); 716 extern void i_mac_perim_exit(mac_impl_t *); 717 extern int i_mac_perim_enter_nowait(mac_impl_t *); 718 extern void i_mac_tx_srs_notify(mac_impl_t *, mac_ring_handle_t); 719 extern int mac_hold(const char *, mac_impl_t **); 720 extern void mac_rele(mac_impl_t *); 721 extern int i_mac_disable(mac_impl_t *); 722 extern void i_mac_notify(mac_impl_t *, mac_notify_type_t); 723 extern void i_mac_notify_exit(mac_impl_t *); 724 extern void mac_rx_group_unmark(mac_group_t *, uint_t); 725 extern void mac_tx_client_flush(mac_client_impl_t *); 726 extern void mac_tx_client_block(mac_client_impl_t *); 727 extern void mac_tx_client_unblock(mac_client_impl_t *); 728 extern int i_mac_promisc_set(mac_impl_t *, boolean_t); 729 extern void i_mac_promisc_walker_cleanup(mac_impl_t *); 730 extern mactype_t *mactype_getplugin(const char *); 731 extern void mac_addr_factory_init(mac_impl_t *); 732 extern void mac_addr_factory_fini(mac_impl_t *); 733 extern void mac_register_priv_prop(mac_impl_t *, mac_priv_prop_t *, uint_t); 734 extern void mac_unregister_priv_prop(mac_impl_t *); 735 extern int mac_init_rings(mac_impl_t *, mac_ring_type_t); 736 extern void mac_free_rings(mac_impl_t *, mac_ring_type_t); 737 738 extern int mac_start_group(mac_group_t *); 739 extern void mac_stop_group(mac_group_t *); 740 extern int mac_start_ring(mac_ring_t *); 741 extern void mac_stop_ring(mac_ring_t *); 742 extern int mac_add_macaddr(mac_impl_t *, mac_group_t *, uint8_t *, boolean_t); 743 extern int mac_remove_macaddr(mac_address_t *); 744 745 extern void mac_set_rx_group_state(mac_group_t *, mac_group_state_t); 746 extern void mac_rx_group_add_client(mac_group_t *, mac_client_impl_t *); 747 extern void mac_rx_group_remove_client(mac_group_t *, mac_client_impl_t *) 748 ; 749 extern int i_mac_group_add_ring(mac_group_t *, mac_ring_t *, int); 750 extern void i_mac_group_rem_ring(mac_group_t *, mac_ring_t *, boolean_t); 751 752 extern void mac_poll_state_change(mac_handle_t, boolean_t); 753 754 /* Global callbacks into the bridging module (when loaded) */ 755 extern mac_bridge_tx_t mac_bridge_tx_cb; 756 extern mac_bridge_rx_t mac_bridge_rx_cb; 757 extern mac_bridge_ref_t mac_bridge_ref_cb; 758 extern mac_bridge_ls_t mac_bridge_ls_cb; 759 760 #ifdef __cplusplus 761 } 762 #endif 763 764 #endif /* _SYS_MAC_IMPL_H */ 765