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