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