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