10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51852Syz147064 * Common Development and Distribution License (the "License"). 61852Syz147064 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 2211528SBaban.Kenkre@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _SYS_MAC_IMPL_H 270Sstevel@tonic-gate #define _SYS_MAC_IMPL_H 280Sstevel@tonic-gate 29*11878SVenu.Iyer@Sun.COM #include <sys/cpupart.h> 308275SEric Cheng #include <sys/modhash.h> 318275SEric Cheng #include <sys/mac_client.h> 328275SEric Cheng #include <sys/mac_provider.h> 3310491SRishi.Srivatsavai@Sun.COM #include <sys/note.h> 34*11878SVenu.Iyer@Sun.COM #include <sys/avl.h> 352311Sseb #include <net/if.h> 368275SEric Cheng #include <sys/mac_flow_impl.h> 378275SEric Cheng #include <netinet/ip6.h> 380Sstevel@tonic-gate 390Sstevel@tonic-gate #ifdef __cplusplus 400Sstevel@tonic-gate extern "C" { 410Sstevel@tonic-gate #endif 420Sstevel@tonic-gate 4310654SGarrett.Damore@Sun.COM /* 4410654SGarrett.Damore@Sun.COM * This is the first minor number available for MAC provider private 4510654SGarrett.Damore@Sun.COM * use. This makes it possible to deliver a driver that is both a MAC 4610654SGarrett.Damore@Sun.COM * provider and a regular character/block device. See PSARC 2009/380 4710654SGarrett.Damore@Sun.COM * for more detail about the construction of such devices. The value 4810654SGarrett.Damore@Sun.COM * chosen leaves half of the 32-bit minor numbers (which are really 4910654SGarrett.Damore@Sun.COM * only 18 bits wide) available for driver private use. Drivers can 5010654SGarrett.Damore@Sun.COM * easily identify their private number by the presence of this value 5110654SGarrett.Damore@Sun.COM * in the bits that make up the minor number, since its just the 5210654SGarrett.Damore@Sun.COM * highest bit available for such minor numbers. 5310654SGarrett.Damore@Sun.COM */ 5410654SGarrett.Damore@Sun.COM #define MAC_PRIVATE_MINOR ((MAXMIN32 + 1) / 2) 5510654SGarrett.Damore@Sun.COM 5610654SGarrett.Damore@Sun.COM /* 5710654SGarrett.Damore@Sun.COM * The maximum minor number that corresponds to a real instance. This 5810654SGarrett.Damore@Sun.COM * limits the number of physical ports that a mac provider can offer. 5910654SGarrett.Damore@Sun.COM * Note that this macro must be synchronized with DLS_MAX_MINOR in 6010654SGarrett.Damore@Sun.COM * <sys/dls.h> 6110654SGarrett.Damore@Sun.COM */ 6210654SGarrett.Damore@Sun.COM #define MAC_MAX_MINOR 1000 6310654SGarrett.Damore@Sun.COM 645895Syz147064 typedef struct mac_margin_req_s mac_margin_req_t; 655895Syz147064 665895Syz147064 struct mac_margin_req_s { 675895Syz147064 mac_margin_req_t *mmr_nextp; 685895Syz147064 uint_t mmr_ref; 695895Syz147064 uint32_t mmr_margin; 705895Syz147064 }; 715895Syz147064 728275SEric Cheng /* Generic linked chain type */ 738275SEric Cheng typedef struct mac_chain_s { 748275SEric Cheng struct mac_chain_s *next; 758275SEric Cheng void *item; 768275SEric Cheng } mac_chain_t; 778275SEric Cheng 788275SEric Cheng /* 798275SEric Cheng * Generic mac callback list manipulation structures and macros. The mac_cb_t 808275SEric Cheng * represents a general callback list element embedded in a particular 818275SEric Cheng * data structure such as a mac_notify_cb_t or a mac_promisc_impl_t. 828275SEric Cheng * The mac_cb_info_t represents general information about list walkers. 838275SEric Cheng * Please see the comments above mac_callback_add for more information. 848275SEric Cheng */ 858275SEric Cheng /* mcb_flags */ 868275SEric Cheng #define MCB_CONDEMNED 0x1 /* Logically deleted */ 878275SEric Cheng #define MCB_NOTIFY_CB_T 0x2 888275SEric Cheng #define MCB_TX_NOTIFY_CB_T 0x4 890Sstevel@tonic-gate 90*11878SVenu.Iyer@Sun.COM extern boolean_t mac_tx_serialize; 91*11878SVenu.Iyer@Sun.COM 928275SEric Cheng typedef struct mac_cb_s { 938275SEric Cheng struct mac_cb_s *mcb_nextp; /* Linked list of callbacks */ 948275SEric Cheng void *mcb_objp; /* Ptr to enclosing object */ 958275SEric Cheng size_t mcb_objsize; /* Sizeof the enclosing obj */ 968275SEric Cheng uint_t mcb_flags; 978275SEric Cheng } mac_cb_t; 980Sstevel@tonic-gate 998275SEric Cheng typedef struct mac_cb_info_s { 1008275SEric Cheng kmutex_t *mcbi_lockp; 1018275SEric Cheng kcondvar_t mcbi_cv; 1028275SEric Cheng uint_t mcbi_del_cnt; /* Deleted callback cnt */ 1038275SEric Cheng uint_t mcbi_walker_cnt; /* List walker count */ 1048275SEric Cheng } mac_cb_info_t; 1058275SEric Cheng 1068275SEric Cheng typedef struct mac_notify_cb_s { 1078275SEric Cheng mac_cb_t mncb_link; /* Linked list of callbacks */ 1088275SEric Cheng mac_notify_t mncb_fn; /* callback function */ 1098275SEric Cheng void *mncb_arg; /* callback argument */ 1108275SEric Cheng struct mac_impl_s *mncb_mip; 1118275SEric Cheng } mac_notify_cb_t; 1120Sstevel@tonic-gate 1138275SEric Cheng /* 1148275SEric Cheng * mac_callback_add(listinfo, listhead, listelement) 1158275SEric Cheng * mac_callback_remove(listinfo, listhead, listelement) 1168275SEric Cheng */ 1178275SEric Cheng typedef boolean_t (*mcb_func_t)(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 1188275SEric Cheng 1198275SEric Cheng #define MAC_CALLBACK_WALKER_INC(mcbi) { \ 1208275SEric Cheng mutex_enter((mcbi)->mcbi_lockp); \ 1218275SEric Cheng (mcbi)->mcbi_walker_cnt++; \ 1228275SEric Cheng mutex_exit((mcbi)->mcbi_lockp); \ 1238275SEric Cheng } 1248275SEric Cheng 1258275SEric Cheng #define MAC_CALLBACK_WALKER_INC_HELD(mcbi) (mcbi)->mcbi_walker_cnt++; 1260Sstevel@tonic-gate 1278275SEric Cheng #define MAC_CALLBACK_WALKER_DCR(mcbi, headp) { \ 1288275SEric Cheng mac_cb_t *rmlist; \ 1298275SEric Cheng \ 1308275SEric Cheng mutex_enter((mcbi)->mcbi_lockp); \ 1318275SEric Cheng if (--(mcbi)->mcbi_walker_cnt == 0 && (mcbi)->mcbi_del_cnt != 0) { \ 1328275SEric Cheng rmlist = mac_callback_walker_cleanup((mcbi), headp); \ 1338275SEric Cheng mac_callback_free(rmlist); \ 1348275SEric Cheng cv_broadcast(&(mcbi)->mcbi_cv); \ 1358275SEric Cheng } \ 1368275SEric Cheng mutex_exit((mcbi)->mcbi_lockp); \ 1378275SEric Cheng } 1380Sstevel@tonic-gate 1398275SEric Cheng #define MAC_PROMISC_WALKER_INC(mip) \ 1408275SEric Cheng MAC_CALLBACK_WALKER_INC(&(mip)->mi_promisc_cb_info) 1418275SEric Cheng 1428275SEric Cheng #define MAC_PROMISC_WALKER_DCR(mip) { \ 1438275SEric Cheng mac_cb_info_t *mcbi; \ 1448275SEric Cheng \ 1458275SEric Cheng mcbi = &(mip)->mi_promisc_cb_info; \ 1468275SEric Cheng mutex_enter(mcbi->mcbi_lockp); \ 1478275SEric Cheng if (--mcbi->mcbi_walker_cnt == 0 && mcbi->mcbi_del_cnt != 0) { \ 1488275SEric Cheng i_mac_promisc_walker_cleanup(mip); \ 1498275SEric Cheng cv_broadcast(&mcbi->mcbi_cv); \ 1508275SEric Cheng } \ 1518275SEric Cheng mutex_exit(mcbi->mcbi_lockp); \ 1528275SEric Cheng } 1530Sstevel@tonic-gate 1542311Sseb typedef struct mactype_s { 1552311Sseb const char *mt_ident; 1562311Sseb uint32_t mt_ref; 1572311Sseb uint_t mt_type; 1583147Sxc151355 uint_t mt_nativetype; 1592311Sseb size_t mt_addr_length; 1602311Sseb uint8_t *mt_brdcst_addr; 1612311Sseb mactype_ops_t mt_ops; 1622311Sseb mac_stat_info_t *mt_stats; /* array of mac_stat_info_t elements */ 1632311Sseb size_t mt_statcount; /* number of elements in mt_stats */ 1646512Ssowmini mac_ndd_mapping_t *mt_mapping; 1656512Ssowmini size_t mt_mappingcount; 1662311Sseb } mactype_t; 1670Sstevel@tonic-gate 1688275SEric Cheng /* 1698275SEric Cheng * Multiple rings implementation. 1708275SEric Cheng */ 1718275SEric Cheng typedef enum { 1728275SEric Cheng MAC_GROUP_STATE_UNINIT = 0, /* initial state of data structure */ 1738275SEric Cheng MAC_GROUP_STATE_REGISTERED, /* hooked with h/w group */ 1748275SEric Cheng MAC_GROUP_STATE_RESERVED, /* group is reserved and opened */ 1758275SEric Cheng MAC_GROUP_STATE_SHARED /* default group shared among */ 1768275SEric Cheng /* multiple mac clients */ 1778275SEric Cheng } mac_group_state_t; 1785084Sjohnlev 1798275SEric Cheng typedef struct mac_ring_s mac_ring_t; 1808275SEric Cheng typedef struct mac_group_s mac_group_t; 1818275SEric Cheng 1828275SEric Cheng /* 1838275SEric Cheng * Ring data structure for ring control and management. 1848275SEric Cheng */ 1858275SEric Cheng typedef enum { 1868275SEric Cheng MR_FREE, /* Available for assignment to flows */ 1878275SEric Cheng MR_NEWLY_ADDED, /* Just assigned to another group */ 1888275SEric Cheng MR_INUSE /* Assigned to an SRS */ 1898275SEric Cheng } mac_ring_state_t; 1908275SEric Cheng 1918275SEric Cheng /* mr_flag values */ 1928275SEric Cheng #define MR_INCIPIENT 0x1 1938275SEric Cheng #define MR_CONDEMNED 0x2 1948275SEric Cheng #define MR_QUIESCE 0x4 1958275SEric Cheng 196*11878SVenu.Iyer@Sun.COM typedef struct mac_impl_s mac_impl_t; 197*11878SVenu.Iyer@Sun.COM 1988275SEric Cheng struct mac_ring_s { 1998275SEric Cheng int mr_index; /* index in the original list */ 2008275SEric Cheng mac_ring_type_t mr_type; /* ring type */ 2018275SEric Cheng mac_ring_t *mr_next; /* next ring in the chain */ 2028275SEric Cheng mac_group_handle_t mr_gh; /* reference to group */ 2038275SEric Cheng 2048275SEric Cheng mac_classify_type_t mr_classify_type; /* HW vs SW */ 205*11878SVenu.Iyer@Sun.COM struct mac_soft_ring_set_s *mr_srs; /* associated SRS */ 206*11878SVenu.Iyer@Sun.COM mac_ring_handle_t mr_prh; /* associated pseudo ring hdl */ 207*11878SVenu.Iyer@Sun.COM uint_t mr_refcnt; /* Ring references */ 2088275SEric Cheng /* ring generation no. to guard against drivers using stale rings */ 2098275SEric Cheng uint64_t mr_gen_num; 2108275SEric Cheng 211*11878SVenu.Iyer@Sun.COM kstat_t *mr_ksp; /* ring kstats */ 212*11878SVenu.Iyer@Sun.COM mac_impl_t *mr_mip; /* pointer to primary's mip */ 213*11878SVenu.Iyer@Sun.COM 2148275SEric Cheng kmutex_t mr_lock; 2158275SEric Cheng kcondvar_t mr_cv; /* mr_lock */ 2168275SEric Cheng mac_ring_state_t mr_state; /* mr_lock */ 2178275SEric Cheng uint_t mr_flag; /* mr_lock */ 2188275SEric Cheng 2198275SEric Cheng mac_ring_info_t mr_info; /* driver supplied info */ 2208275SEric Cheng }; 2218275SEric Cheng #define mr_driver mr_info.mri_driver 2228275SEric Cheng #define mr_start mr_info.mri_start 2238275SEric Cheng #define mr_stop mr_info.mri_stop 224*11878SVenu.Iyer@Sun.COM #define mr_stat mr_info.mri_stat 2258275SEric Cheng 2268275SEric Cheng #define MAC_RING_MARK(mr, flag) \ 2278275SEric Cheng (mr)->mr_flag |= flag; 2288275SEric Cheng 2298275SEric Cheng #define MAC_RING_UNMARK(mr, flag) \ 2308275SEric Cheng (mr)->mr_flag &= ~flag; 2318275SEric Cheng 2328275SEric Cheng /* 2338275SEric Cheng * Reference hold and release on mac_ring_t 'mr' 2348275SEric Cheng */ 2358275SEric Cheng #define MR_REFHOLD_LOCKED(mr) { \ 2368275SEric Cheng ASSERT(MUTEX_HELD(&mr->mr_lock)); \ 2378275SEric Cheng (mr)->mr_refcnt++; \ 2385084Sjohnlev } 2395084Sjohnlev 2408275SEric Cheng #define MR_REFRELE(mr) { \ 2418275SEric Cheng mutex_enter(&(mr)->mr_lock); \ 2428275SEric Cheng ASSERT((mr)->mr_refcnt != 0); \ 2438275SEric Cheng (mr)->mr_refcnt--; \ 2448275SEric Cheng if ((mr)->mr_refcnt == 0 && \ 2458275SEric Cheng ((mr)->mr_flag & (MR_CONDEMNED | MR_QUIESCE))) \ 2468275SEric Cheng cv_signal(&(mr)->mr_cv); \ 2478275SEric Cheng mutex_exit(&(mr)->mr_lock); \ 2485084Sjohnlev } 2495084Sjohnlev 2508275SEric Cheng /* 2518275SEric Cheng * Per mac client flow information associated with a RX group. 2528275SEric Cheng * The entire structure is SL protected. 2538275SEric Cheng */ 2548275SEric Cheng typedef struct mac_grp_client { 2558275SEric Cheng struct mac_grp_client *mgc_next; 2568275SEric Cheng struct mac_client_impl_s *mgc_client; 2578275SEric Cheng } mac_grp_client_t; 2585084Sjohnlev 259*11878SVenu.Iyer@Sun.COM #define MAC_GROUP_NO_CLIENT(g) ((g)->mrg_clients == NULL) 2608275SEric Cheng 261*11878SVenu.Iyer@Sun.COM #define MAC_GROUP_ONLY_CLIENT(g) \ 2628275SEric Cheng ((((g)->mrg_clients != NULL) && \ 2638275SEric Cheng ((g)->mrg_clients->mgc_next == NULL)) ? \ 2648275SEric Cheng (g)->mrg_clients->mgc_client : NULL) 2656512Ssowmini 2662311Sseb /* 2678275SEric Cheng * Common ring group data structure for ring control and management. 2688275SEric Cheng * The entire structure is SL protected 2692311Sseb */ 2708275SEric Cheng struct mac_group_s { 2718275SEric Cheng int mrg_index; /* index in the list */ 2728275SEric Cheng mac_ring_type_t mrg_type; /* ring type */ 2738275SEric Cheng mac_group_state_t mrg_state; /* state of the group */ 2748275SEric Cheng mac_group_t *mrg_next; /* next ring in the chain */ 2758275SEric Cheng mac_handle_t mrg_mh; /* reference to MAC */ 2768275SEric Cheng mac_ring_t *mrg_rings; /* grouped rings */ 2778275SEric Cheng uint_t mrg_cur_count; /* actual size of group */ 2788275SEric Cheng 2798275SEric Cheng mac_grp_client_t *mrg_clients; /* clients list */ 2808275SEric Cheng 2818275SEric Cheng mac_group_info_t mrg_info; /* driver supplied info */ 2828275SEric Cheng }; 2838275SEric Cheng 2848275SEric Cheng #define mrg_driver mrg_info.mgi_driver 2858275SEric Cheng #define mrg_start mrg_info.mgi_start 2868275SEric Cheng #define mrg_stop mrg_info.mgi_stop 2878275SEric Cheng 2888275SEric Cheng #define GROUP_INTR_HANDLE(g) (g)->mrg_info.mgi_intr.mi_handle 2898275SEric Cheng #define GROUP_INTR_ENABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_enable 2908275SEric Cheng #define GROUP_INTR_DISABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_disable 2918275SEric Cheng 29210491SRishi.Srivatsavai@Sun.COM #define MAC_RING_TX(mhp, rh, mp, rest) { \ 29310491SRishi.Srivatsavai@Sun.COM mac_ring_handle_t mrh = rh; \ 29410491SRishi.Srivatsavai@Sun.COM mac_impl_t *mimpl = (mac_impl_t *)mhp; \ 2958275SEric Cheng /* \ 29610491SRishi.Srivatsavai@Sun.COM * Send packets through a selected tx ring, or through the \ 29710491SRishi.Srivatsavai@Sun.COM * default handler if there is no selected ring. \ 2988275SEric Cheng */ \ 29910491SRishi.Srivatsavai@Sun.COM if (mrh == NULL) \ 30010491SRishi.Srivatsavai@Sun.COM mrh = mimpl->mi_default_tx_ring; \ 30110491SRishi.Srivatsavai@Sun.COM if (mrh == NULL) { \ 30210491SRishi.Srivatsavai@Sun.COM rest = mimpl->mi_tx(mimpl->mi_driver, mp); \ 30310491SRishi.Srivatsavai@Sun.COM } else { \ 30410491SRishi.Srivatsavai@Sun.COM rest = mac_hwring_tx(mrh, mp); \ 30510491SRishi.Srivatsavai@Sun.COM } \ 30610491SRishi.Srivatsavai@Sun.COM } 30710491SRishi.Srivatsavai@Sun.COM 30810491SRishi.Srivatsavai@Sun.COM /* 30910491SRishi.Srivatsavai@Sun.COM * This is the final stop before reaching the underlying driver 31010491SRishi.Srivatsavai@Sun.COM * or aggregation, so this is where the bridging hook is implemented. 31110491SRishi.Srivatsavai@Sun.COM * Packets that are bridged will return through mac_bridge_tx(), with 31210491SRishi.Srivatsavai@Sun.COM * rh nulled out if the bridge chooses to send output on a different 31310491SRishi.Srivatsavai@Sun.COM * link due to forwarding. 31410491SRishi.Srivatsavai@Sun.COM */ 315*11878SVenu.Iyer@Sun.COM #define MAC_TX(mip, rh, mp, src_mcip) { \ 316*11878SVenu.Iyer@Sun.COM mac_ring_handle_t rhandle = (rh); \ 31710491SRishi.Srivatsavai@Sun.COM /* \ 31810491SRishi.Srivatsavai@Sun.COM * If there is a bound Hybrid I/O share, send packets through \ 31910491SRishi.Srivatsavai@Sun.COM * the default tx ring. (When there's a bound Hybrid I/O share, \ 32010491SRishi.Srivatsavai@Sun.COM * the tx rings of this client are mapped in the guest domain \ 32110491SRishi.Srivatsavai@Sun.COM * and not accessible from here.) \ 32210491SRishi.Srivatsavai@Sun.COM */ \ 32310491SRishi.Srivatsavai@Sun.COM _NOTE(CONSTANTCONDITION) \ 324*11878SVenu.Iyer@Sun.COM if ((src_mcip)->mci_state_flags & MCIS_SHARE_BOUND) \ 325*11878SVenu.Iyer@Sun.COM rhandle = (mip)->mi_default_tx_ring; \ 326*11878SVenu.Iyer@Sun.COM if (mip->mi_promisc_list != NULL) \ 327*11878SVenu.Iyer@Sun.COM mac_promisc_dispatch(mip, mp, src_mcip); \ 32810491SRishi.Srivatsavai@Sun.COM /* \ 32910491SRishi.Srivatsavai@Sun.COM * Grab the proper transmit pointer and handle. Special \ 33010491SRishi.Srivatsavai@Sun.COM * optimization: we can test mi_bridge_link itself atomically, \ 33110491SRishi.Srivatsavai@Sun.COM * and if that indicates no bridge send packets through tx ring.\ 33210491SRishi.Srivatsavai@Sun.COM */ \ 33310491SRishi.Srivatsavai@Sun.COM if (mip->mi_bridge_link == NULL) { \ 334*11878SVenu.Iyer@Sun.COM MAC_RING_TX(mip, rhandle, mp, mp); \ 33510491SRishi.Srivatsavai@Sun.COM } else { \ 336*11878SVenu.Iyer@Sun.COM mp = mac_bridge_tx(mip, rhandle, mp); \ 33710491SRishi.Srivatsavai@Sun.COM } \ 3388275SEric Cheng } 3398275SEric Cheng 3408275SEric Cheng /* mci_tx_flag */ 3418275SEric Cheng #define MCI_TX_QUIESCE 0x1 3428275SEric Cheng 3438275SEric Cheng typedef struct mac_factory_addr_s { 3448275SEric Cheng boolean_t mfa_in_use; 3458275SEric Cheng uint8_t mfa_addr[MAXMACADDRLEN]; 3468275SEric Cheng struct mac_client_impl_s *mfa_client; 3478275SEric Cheng } mac_factory_addr_t; 3485895Syz147064 3498275SEric Cheng typedef struct mac_mcast_addrs_s { 3508275SEric Cheng struct mac_mcast_addrs_s *mma_next; 3518275SEric Cheng uint8_t mma_addr[MAXMACADDRLEN]; 3528275SEric Cheng int mma_ref; 3538275SEric Cheng } mac_mcast_addrs_t; 3548275SEric Cheng 3558275SEric Cheng typedef enum { 3568275SEric Cheng MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED = 1, /* hardware steering */ 3578275SEric Cheng MAC_ADDRESS_TYPE_UNICAST_PROMISC /* promiscuous mode */ 3588275SEric Cheng } mac_address_type_t; 3598275SEric Cheng 3608275SEric Cheng typedef struct mac_address_s { 3618275SEric Cheng mac_address_type_t ma_type; /* address type */ 3628275SEric Cheng int ma_nusers; /* number of users */ 3638275SEric Cheng /* of that address */ 3648275SEric Cheng struct mac_address_s *ma_next; /* next address */ 3658275SEric Cheng uint8_t ma_addr[MAXMACADDRLEN]; /* address value */ 3668275SEric Cheng size_t ma_len; /* address length */ 3678275SEric Cheng mac_group_t *ma_group; /* asscociated group */ 3688275SEric Cheng mac_impl_t *ma_mip; /* MAC handle */ 3698275SEric Cheng } mac_address_t; 3708275SEric Cheng 3718275SEric Cheng extern krwlock_t i_mac_impl_lock; 3728275SEric Cheng extern mod_hash_t *i_mac_impl_hash; 3738275SEric Cheng extern kmem_cache_t *i_mac_impl_cachep; 3748275SEric Cheng extern uint_t i_mac_impl_count; 3755895Syz147064 3768275SEric Cheng /* 3778275SEric Cheng * Each registered MAC is associated with a mac_impl_t structure. The 3788275SEric Cheng * structure represents the undelying hardware, in terms of definition, 3798275SEric Cheng * resources (transmit, receive rings etc.), callback functions etc. It 3808275SEric Cheng * also holds the table of MAC clients that are configured on the device. 3818275SEric Cheng * The table is used for classifying incoming packets in software. 3828275SEric Cheng * 3838275SEric Cheng * The protection scheme uses 2 elements, a coarse serialization mechanism 3848275SEric Cheng * called perimeter and a finer traditional lock based scheme. More details 3858275SEric Cheng * can be found in the big block comment in mac.c. 3868275SEric Cheng * 3878275SEric Cheng * The protection scheme for each member of the mac_impl_t is described below. 3888275SEric Cheng * 3898275SEric Cheng * Write Once Only (WO): Typically these don't change for the lifetime of the 3908275SEric Cheng * data structure. For example something in mac_impl_t that stays the same 3918275SEric Cheng * from mac_register to mac_unregister, or something in a mac_client_impl_t 3928275SEric Cheng * that stays the same from mac_client_open to mac_client_close. 3938275SEric Cheng * 3948275SEric Cheng * Serializer (SL): Protected by the Serializer. All SLOP operations on a 3958275SEric Cheng * mac endpoint go through the serializer. MTOPs don't care about reading 3968275SEric Cheng * these fields atomically. 3978275SEric Cheng * 3988275SEric Cheng * Lock: Traditional mutex/rw lock. Modify operations still go through the 3998275SEric Cheng * mac serializer, the lock helps synchronize readers with writers. 4008275SEric Cheng */ 4018275SEric Cheng struct mac_impl_s { 4028275SEric Cheng krwlock_t mi_rw_lock; 4038275SEric Cheng char mi_name[LIFNAMSIZ]; /* WO */ 4048275SEric Cheng uint32_t mi_state_flags; 4058275SEric Cheng void *mi_driver; /* Driver private, WO */ 4068275SEric Cheng mac_info_t mi_info; /* WO */ 4078275SEric Cheng mactype_t *mi_type; /* WO */ 4088275SEric Cheng void *mi_pdata; /* WO */ 4098275SEric Cheng size_t mi_pdata_size; /* WO */ 4108275SEric Cheng mac_callbacks_t *mi_callbacks; /* WO */ 4118275SEric Cheng dev_info_t *mi_dip; /* WO */ 4128275SEric Cheng uint32_t mi_ref; /* i_mac_impl_lock */ 4138275SEric Cheng uint_t mi_active; /* SL */ 4148275SEric Cheng link_state_t mi_linkstate; /* none */ 41510491SRishi.Srivatsavai@Sun.COM link_state_t mi_lowlinkstate; /* none */ 41610491SRishi.Srivatsavai@Sun.COM link_state_t mi_lastlowlinkstate; /* none */ 4178275SEric Cheng uint_t mi_devpromisc; /* SL */ 4188275SEric Cheng uint8_t mi_addr[MAXMACADDRLEN]; /* mi_rw_lock */ 4198275SEric Cheng uint8_t mi_dstaddr[MAXMACADDRLEN]; /* mi_rw_lock */ 42010616SSebastien.Roy@Sun.COM boolean_t mi_dstaddr_set; 4215895Syz147064 4228275SEric Cheng /* 4238275SEric Cheng * The mac perimeter. All client initiated create/modify operations 4248275SEric Cheng * on a mac end point go through this. 4258275SEric Cheng */ 4268275SEric Cheng kmutex_t mi_perim_lock; 4278275SEric Cheng kthread_t *mi_perim_owner; /* mi_perim_lock */ 4288275SEric Cheng uint_t mi_perim_ocnt; /* mi_perim_lock */ 4298275SEric Cheng kcondvar_t mi_perim_cv; /* mi_perim_lock */ 4305895Syz147064 4318275SEric Cheng /* mac notification callbacks */ 4328275SEric Cheng kmutex_t mi_notify_lock; 4338275SEric Cheng mac_cb_info_t mi_notify_cb_info; /* mi_notify_lock */ 4348275SEric Cheng mac_cb_t *mi_notify_cb_list; /* mi_notify_lock */ 4358275SEric Cheng kthread_t *mi_notify_thread; /* mi_notify_lock */ 4368275SEric Cheng uint_t mi_notify_bits; /* mi_notify_lock */ 4378275SEric Cheng 4388275SEric Cheng uint32_t mi_v12n_level; /* Virt'ion readiness */ 4398275SEric Cheng 4408275SEric Cheng /* 4418275SEric Cheng * RX groups, ring capability 4428275SEric Cheng * Fields of this block are SL protected. 4438275SEric Cheng */ 4448275SEric Cheng mac_group_type_t mi_rx_group_type; /* grouping type */ 4458275SEric Cheng uint_t mi_rx_group_count; 4468275SEric Cheng mac_group_t *mi_rx_groups; 447*11878SVenu.Iyer@Sun.COM mac_group_t *mi_rx_donor_grp; 448*11878SVenu.Iyer@Sun.COM uint_t mi_rxrings_rsvd; 449*11878SVenu.Iyer@Sun.COM uint_t mi_rxrings_avail; 450*11878SVenu.Iyer@Sun.COM uint_t mi_rxhwclnt_avail; 451*11878SVenu.Iyer@Sun.COM uint_t mi_rxhwclnt_used; 4525895Syz147064 4538275SEric Cheng mac_capab_rings_t mi_rx_rings_cap; 4548275SEric Cheng 4558275SEric Cheng /* 4568275SEric Cheng * TX groups and ring capability, SL Protected. 4578275SEric Cheng */ 4588275SEric Cheng mac_group_type_t mi_tx_group_type; /* grouping type */ 4598275SEric Cheng uint_t mi_tx_group_count; 4608275SEric Cheng uint_t mi_tx_group_free; 4618275SEric Cheng mac_group_t *mi_tx_groups; 4628275SEric Cheng mac_capab_rings_t mi_tx_rings_cap; 463*11878SVenu.Iyer@Sun.COM uint_t mi_txrings_rsvd; 464*11878SVenu.Iyer@Sun.COM uint_t mi_txrings_avail; 465*11878SVenu.Iyer@Sun.COM uint_t mi_txhwclnt_avail; 466*11878SVenu.Iyer@Sun.COM uint_t mi_txhwclnt_used; 4678275SEric Cheng 4688275SEric Cheng mac_ring_handle_t mi_default_tx_ring; 4695895Syz147064 4708275SEric Cheng /* 4718275SEric Cheng * MAC address list. SL protected. 4728275SEric Cheng */ 4738275SEric Cheng mac_address_t *mi_addresses; 4748275SEric Cheng 4758275SEric Cheng /* 4768275SEric Cheng * This MAC's table of sub-flows 4778275SEric Cheng */ 4788275SEric Cheng flow_tab_t *mi_flow_tab; /* WO */ 4798275SEric Cheng 4808275SEric Cheng kstat_t *mi_ksp; /* WO */ 4818275SEric Cheng uint_t mi_kstat_count; /* WO */ 4828275SEric Cheng uint_t mi_nactiveclients; /* SL */ 4838275SEric Cheng 4848275SEric Cheng /* for broadcast and multicast support */ 4858275SEric Cheng struct mac_mcast_addrs_s *mi_mcast_addrs; /* mi_rw_lock */ 4868275SEric Cheng struct mac_bcast_grp_s *mi_bcast_grp; /* mi_rw_lock */ 4878275SEric Cheng uint_t mi_bcast_ngrps; /* mi_rw_lock */ 4885895Syz147064 4898275SEric Cheng /* list of MAC clients which opened this MAC */ 4908275SEric Cheng struct mac_client_impl_s *mi_clients_list; /* mi_rw_lock */ 4918275SEric Cheng uint_t mi_nclients; /* mi_rw_lock */ 4928833SVenu.Iyer@Sun.COM struct mac_client_impl_s *mi_single_active_client; /* mi_rw_lock */ 4938275SEric Cheng 4948275SEric Cheng uint32_t mi_margin; /* mi_rw_lock */ 4958275SEric Cheng uint_t mi_sdu_min; /* mi_rw_lock */ 4968275SEric Cheng uint_t mi_sdu_max; /* mi_rw_lock */ 4978275SEric Cheng 4988275SEric Cheng /* 4998275SEric Cheng * Cache of factory MAC addresses provided by the driver. If 5008275SEric Cheng * the driver doesn't provide multiple factory MAC addresses, 5018275SEric Cheng * the mi_factory_addr is set to NULL, and mi_factory_addr_num 5028275SEric Cheng * is set to zero. 5038275SEric Cheng */ 5048275SEric Cheng mac_factory_addr_t *mi_factory_addr; /* mi_rw_lock */ 5058275SEric Cheng uint_t mi_factory_addr_num; /* mi_rw_lock */ 5065895Syz147064 5078275SEric Cheng /* for promiscuous mode support */ 5088275SEric Cheng kmutex_t mi_promisc_lock; 5098275SEric Cheng mac_cb_t *mi_promisc_list; /* mi_promisc_lock */ 5108275SEric Cheng mac_cb_info_t mi_promisc_cb_info; /* mi_promisc_lock */ 5118275SEric Cheng 5128275SEric Cheng /* cache of rings over this mac_impl */ 5138275SEric Cheng kmutex_t mi_ring_lock; 5148275SEric Cheng mac_ring_t *mi_ring_freelist; /* mi_ring_lock */ 5155895Syz147064 5165895Syz147064 /* 5178275SEric Cheng * These are used for caching the properties, if any, for the 5188275SEric Cheng * primary MAC client. If the MAC client is not yet in place 5198275SEric Cheng * when the properties are set then we cache them here to be 5208275SEric Cheng * applied to the MAC client when it is created. 5218275SEric Cheng */ 5228275SEric Cheng mac_resource_props_t mi_resource_props; /* SL */ 52310491SRishi.Srivatsavai@Sun.COM uint16_t mi_pvid; /* SL */ 5248275SEric Cheng 5258275SEric Cheng minor_t mi_minor; /* WO */ 5269073SCathy.Zhou@Sun.COM uint32_t mi_oref; /* SL */ 5279073SCathy.Zhou@Sun.COM mac_capab_legacy_t mi_capab_legacy; /* WO */ 5288275SEric Cheng dev_t mi_phy_dev; /* WO */ 5299073SCathy.Zhou@Sun.COM 5308275SEric Cheng /* 5315895Syz147064 * List of margin value requests added by mac clients. This list is 5325895Syz147064 * sorted: the first one has the greatest value. 5335895Syz147064 */ 5345895Syz147064 mac_margin_req_t *mi_mmrp; 535*11878SVenu.Iyer@Sun.COM char **mi_priv_prop; 5366512Ssowmini uint_t mi_priv_prop_count; 5378275SEric Cheng 5388275SEric Cheng /* 5398275SEric Cheng * Hybrid I/O related definitions. 5408275SEric Cheng */ 5418275SEric Cheng mac_capab_share_t mi_share_capab; 5428275SEric Cheng 54310491SRishi.Srivatsavai@Sun.COM /* 54410491SRishi.Srivatsavai@Sun.COM * Bridging hooks and limit values. Uses mutex and reference counts 54510491SRishi.Srivatsavai@Sun.COM * (bridging only) for data path. Limits need no synchronization. 54610491SRishi.Srivatsavai@Sun.COM */ 54710491SRishi.Srivatsavai@Sun.COM mac_handle_t mi_bridge_link; 54810491SRishi.Srivatsavai@Sun.COM kmutex_t mi_bridge_lock; 54910491SRishi.Srivatsavai@Sun.COM uint32_t mi_llimit; 55010491SRishi.Srivatsavai@Sun.COM uint32_t mi_ldecay; 55110491SRishi.Srivatsavai@Sun.COM 5528275SEric Cheng /* This should be the last block in this structure */ 5538275SEric Cheng #ifdef DEBUG 5548275SEric Cheng #define MAC_PERIM_STACK_DEPTH 15 5558275SEric Cheng int mi_perim_stack_depth; 5568275SEric Cheng pc_t mi_perim_stack[MAC_PERIM_STACK_DEPTH]; 5578275SEric Cheng #endif 5588275SEric Cheng }; 5598275SEric Cheng 560*11878SVenu.Iyer@Sun.COM /* 561*11878SVenu.Iyer@Sun.COM * The default TX group is the last one in the list. 562*11878SVenu.Iyer@Sun.COM */ 563*11878SVenu.Iyer@Sun.COM #define MAC_DEFAULT_TX_GROUP(mip) \ 564*11878SVenu.Iyer@Sun.COM (mip)->mi_tx_groups + (mip)->mi_tx_group_count 565*11878SVenu.Iyer@Sun.COM 566*11878SVenu.Iyer@Sun.COM /* 567*11878SVenu.Iyer@Sun.COM * The default RX group is the first one in the list 568*11878SVenu.Iyer@Sun.COM */ 569*11878SVenu.Iyer@Sun.COM #define MAC_DEFAULT_RX_GROUP(mip) (mip)->mi_rx_groups 570*11878SVenu.Iyer@Sun.COM 571*11878SVenu.Iyer@Sun.COM /* Reserved RX rings */ 572*11878SVenu.Iyer@Sun.COM #define MAC_RX_RING_RESERVED(m, cnt) { \ 573*11878SVenu.Iyer@Sun.COM ASSERT((m)->mi_rxrings_avail >= (cnt)); \ 574*11878SVenu.Iyer@Sun.COM (m)->mi_rxrings_rsvd += (cnt); \ 575*11878SVenu.Iyer@Sun.COM (m)->mi_rxrings_avail -= (cnt); \ 576*11878SVenu.Iyer@Sun.COM } 577*11878SVenu.Iyer@Sun.COM 578*11878SVenu.Iyer@Sun.COM /* Released RX rings */ 579*11878SVenu.Iyer@Sun.COM #define MAC_RX_RING_RELEASED(m, cnt) { \ 580*11878SVenu.Iyer@Sun.COM ASSERT((m)->mi_rxrings_rsvd >= (cnt)); \ 581*11878SVenu.Iyer@Sun.COM (m)->mi_rxrings_rsvd -= (cnt); \ 582*11878SVenu.Iyer@Sun.COM (m)->mi_rxrings_avail += (cnt); \ 583*11878SVenu.Iyer@Sun.COM } 584*11878SVenu.Iyer@Sun.COM 585*11878SVenu.Iyer@Sun.COM /* Reserved a RX group */ 586*11878SVenu.Iyer@Sun.COM #define MAC_RX_GRP_RESERVED(m) { \ 587*11878SVenu.Iyer@Sun.COM ASSERT((m)->mi_rxhwclnt_avail > 0); \ 588*11878SVenu.Iyer@Sun.COM (m)->mi_rxhwclnt_avail--; \ 589*11878SVenu.Iyer@Sun.COM (m)->mi_rxhwclnt_used++; \ 590*11878SVenu.Iyer@Sun.COM } 591*11878SVenu.Iyer@Sun.COM 592*11878SVenu.Iyer@Sun.COM /* Released a RX group */ 593*11878SVenu.Iyer@Sun.COM #define MAC_RX_GRP_RELEASED(m) { \ 594*11878SVenu.Iyer@Sun.COM ASSERT((m)->mi_rxhwclnt_used > 0); \ 595*11878SVenu.Iyer@Sun.COM (m)->mi_rxhwclnt_avail++; \ 596*11878SVenu.Iyer@Sun.COM (m)->mi_rxhwclnt_used--; \ 597*11878SVenu.Iyer@Sun.COM } 598*11878SVenu.Iyer@Sun.COM 599*11878SVenu.Iyer@Sun.COM /* Reserved TX rings */ 600*11878SVenu.Iyer@Sun.COM #define MAC_TX_RING_RESERVED(m, cnt) { \ 601*11878SVenu.Iyer@Sun.COM ASSERT((m)->mi_txrings_avail >= (cnt)); \ 602*11878SVenu.Iyer@Sun.COM (m)->mi_txrings_rsvd += (cnt); \ 603*11878SVenu.Iyer@Sun.COM (m)->mi_txrings_avail -= (cnt); \ 604*11878SVenu.Iyer@Sun.COM } 605*11878SVenu.Iyer@Sun.COM /* Released TX rings */ 606*11878SVenu.Iyer@Sun.COM #define MAC_TX_RING_RELEASED(m, cnt) { \ 607*11878SVenu.Iyer@Sun.COM ASSERT((m)->mi_txrings_rsvd >= (cnt)); \ 608*11878SVenu.Iyer@Sun.COM (m)->mi_txrings_rsvd -= (cnt); \ 609*11878SVenu.Iyer@Sun.COM (m)->mi_txrings_avail += (cnt); \ 610*11878SVenu.Iyer@Sun.COM } 611*11878SVenu.Iyer@Sun.COM 612*11878SVenu.Iyer@Sun.COM /* Reserved a TX group */ 613*11878SVenu.Iyer@Sun.COM #define MAC_TX_GRP_RESERVED(m) { \ 614*11878SVenu.Iyer@Sun.COM ASSERT((m)->mi_txhwclnt_avail > 0); \ 615*11878SVenu.Iyer@Sun.COM (m)->mi_txhwclnt_avail--; \ 616*11878SVenu.Iyer@Sun.COM (m)->mi_txhwclnt_used++; \ 617*11878SVenu.Iyer@Sun.COM } 618*11878SVenu.Iyer@Sun.COM 619*11878SVenu.Iyer@Sun.COM /* Released a TX group */ 620*11878SVenu.Iyer@Sun.COM #define MAC_TX_GRP_RELEASED(m) { \ 621*11878SVenu.Iyer@Sun.COM ASSERT((m)->mi_txhwclnt_used > 0); \ 622*11878SVenu.Iyer@Sun.COM (m)->mi_txhwclnt_avail++; \ 623*11878SVenu.Iyer@Sun.COM (m)->mi_txhwclnt_used--; \ 624*11878SVenu.Iyer@Sun.COM } 625*11878SVenu.Iyer@Sun.COM 6268275SEric Cheng /* for mi_state_flags */ 6278275SEric Cheng #define MIS_DISABLED 0x0001 6288275SEric Cheng #define MIS_IS_VNIC 0x0002 6298275SEric Cheng #define MIS_IS_AGGR 0x0004 6308275SEric Cheng #define MIS_NOTIFY_DONE 0x0008 6318275SEric Cheng #define MIS_EXCLUSIVE 0x0010 6328275SEric Cheng #define MIS_EXCLUSIVE_HELD 0x0020 6338275SEric Cheng #define MIS_LEGACY 0x0040 63410491SRishi.Srivatsavai@Sun.COM #define MIS_NO_ACTIVE 0x0080 63510491SRishi.Srivatsavai@Sun.COM #define MIS_POLL_DISABLE 0x0100 6362311Sseb 6372311Sseb #define mi_getstat mi_callbacks->mc_getstat 6382311Sseb #define mi_start mi_callbacks->mc_start 6392311Sseb #define mi_stop mi_callbacks->mc_stop 6405895Syz147064 #define mi_open mi_callbacks->mc_open 6415895Syz147064 #define mi_close mi_callbacks->mc_close 6422311Sseb #define mi_setpromisc mi_callbacks->mc_setpromisc 6432311Sseb #define mi_multicst mi_callbacks->mc_multicst 6442311Sseb #define mi_unicst mi_callbacks->mc_unicst 6452311Sseb #define mi_tx mi_callbacks->mc_tx 6462311Sseb #define mi_ioctl mi_callbacks->mc_ioctl 6472311Sseb #define mi_getcapab mi_callbacks->mc_getcapab 6480Sstevel@tonic-gate 6498275SEric Cheng typedef struct mac_notify_task_arg { 6508275SEric Cheng mac_impl_t *mnt_mip; 6518275SEric Cheng mac_notify_type_t mnt_type; 6528275SEric Cheng mac_ring_t *mnt_ring; 6538275SEric Cheng } mac_notify_task_arg_t; 6548275SEric Cheng 6558275SEric Cheng /* 6568275SEric Cheng * XXX All MAC_DBG_PRTs must be replaced with call to dtrace probes. For now 6578275SEric Cheng * it may be easier to have these printfs for easier debugging 6588275SEric Cheng */ 6598275SEric Cheng #ifdef DEBUG 6608275SEric Cheng extern int mac_dbg; 6618275SEric Cheng #define MAC_DBG_PRT(a) if (mac_dbg > 0) {(void) printf a; } 6628275SEric Cheng #else 6638275SEric Cheng #define MAC_DBG_PRT(a) 6648275SEric Cheng #endif 6658275SEric Cheng 6668275SEric Cheng /* 6678275SEric Cheng * The mac_perim_handle_t is an opaque type that encodes the 'mip' pointer 6688275SEric Cheng * and whether internally a mac_open was done when acquiring the perimeter. 6698275SEric Cheng */ 6708275SEric Cheng #define MAC_ENCODE_MPH(mph, mh, need_close) \ 6718275SEric Cheng (mph) = (mac_perim_handle_t)((uintptr_t)(mh) | need_close) 6728275SEric Cheng 6738275SEric Cheng #define MAC_DECODE_MPH(mph, mip, need_close) { \ 6748275SEric Cheng mip = (mac_impl_t *)(((uintptr_t)mph) & ~0x1); \ 6758275SEric Cheng (need_close) = ((uintptr_t)mph & 0x1); \ 6768275SEric Cheng } 6778275SEric Cheng 678*11878SVenu.Iyer@Sun.COM /* 679*11878SVenu.Iyer@Sun.COM * Type of property information that can be returned by a driver. 680*11878SVenu.Iyer@Sun.COM * Valid flags of the pr_flags of the mac_prop_info_t data structure. 681*11878SVenu.Iyer@Sun.COM */ 682*11878SVenu.Iyer@Sun.COM #define MAC_PROP_INFO_DEFAULT 0x0001 683*11878SVenu.Iyer@Sun.COM #define MAC_PROP_INFO_RANGE 0x0002 684*11878SVenu.Iyer@Sun.COM #define MAC_PROP_INFO_PERM 0x0004 685*11878SVenu.Iyer@Sun.COM 686*11878SVenu.Iyer@Sun.COM /* 687*11878SVenu.Iyer@Sun.COM * Property information. pr_flags is a combination of one of the 688*11878SVenu.Iyer@Sun.COM * MAC_PROP_INFO_* flags, it is reset by the framework before invoking 689*11878SVenu.Iyer@Sun.COM * the driver's prefix_propinfo() entry point. 690*11878SVenu.Iyer@Sun.COM * 691*11878SVenu.Iyer@Sun.COM * Drivers should use MAC_PROP_INFO_SET_*() macros to provide 692*11878SVenu.Iyer@Sun.COM * information about a property. 693*11878SVenu.Iyer@Sun.COM */ 694*11878SVenu.Iyer@Sun.COM typedef struct mac_prop_info_state_s { 695*11878SVenu.Iyer@Sun.COM uint8_t pr_flags; 696*11878SVenu.Iyer@Sun.COM uint8_t pr_perm; 697*11878SVenu.Iyer@Sun.COM void *pr_default; 698*11878SVenu.Iyer@Sun.COM size_t pr_default_size; 699*11878SVenu.Iyer@Sun.COM uint8_t pr_default_status; 700*11878SVenu.Iyer@Sun.COM mac_propval_range_t *pr_range; 701*11878SVenu.Iyer@Sun.COM } mac_prop_info_state_t; 702*11878SVenu.Iyer@Sun.COM 703*11878SVenu.Iyer@Sun.COM #define MAC_PROTECT_ENABLED(mcip, type) \ 704*11878SVenu.Iyer@Sun.COM (((mcip)->mci_flent-> \ 705*11878SVenu.Iyer@Sun.COM fe_resource_props.mrp_mask & MRP_PROTECT) != 0 && \ 706*11878SVenu.Iyer@Sun.COM ((mcip)->mci_flent-> \ 707*11878SVenu.Iyer@Sun.COM fe_resource_props.mrp_protect.mp_types & (type)) != 0) 708*11878SVenu.Iyer@Sun.COM 7098275SEric Cheng typedef struct mac_client_impl_s mac_client_impl_t; 7108275SEric Cheng 7110Sstevel@tonic-gate extern void mac_init(void); 7120Sstevel@tonic-gate extern int mac_fini(void); 7130Sstevel@tonic-gate 7148275SEric Cheng extern void mac_ndd_ioctl(mac_impl_t *, queue_t *, mblk_t *); 715*11878SVenu.Iyer@Sun.COM extern boolean_t mac_ip_hdr_length_v6(ip6_t *, uint8_t *, uint16_t *, 716*11878SVenu.Iyer@Sun.COM uint8_t *, ip6_frag_t **); 7170Sstevel@tonic-gate 7188275SEric Cheng extern mblk_t *mac_copymsgchain_cksum(mblk_t *); 7198275SEric Cheng extern mblk_t *mac_fix_cksum(mblk_t *); 7208275SEric Cheng extern void mac_packet_print(mac_handle_t, mblk_t *); 7218275SEric Cheng extern void mac_rx_deliver(void *, mac_resource_handle_t, mblk_t *, 7228275SEric Cheng mac_header_info_t *); 7238275SEric Cheng extern void mac_tx_notify(mac_impl_t *); 7248275SEric Cheng 7258275SEric Cheng extern boolean_t mac_callback_find(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 7268275SEric Cheng extern void mac_callback_add(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 7278275SEric Cheng extern boolean_t mac_callback_remove(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 7288275SEric Cheng extern void mac_callback_remove_wait(mac_cb_info_t *); 7298275SEric Cheng extern void mac_callback_free(mac_cb_t *); 7308275SEric Cheng extern mac_cb_t *mac_callback_walker_cleanup(mac_cb_info_t *, mac_cb_t **); 7318275SEric Cheng 7328275SEric Cheng /* in mac_bcast.c */ 7338275SEric Cheng extern void mac_bcast_init(void); 7348275SEric Cheng extern void mac_bcast_fini(void); 7358275SEric Cheng extern mac_impl_t *mac_bcast_grp_mip(void *); 7368275SEric Cheng extern int mac_bcast_add(mac_client_impl_t *, const uint8_t *, uint16_t, 7378275SEric Cheng mac_addrtype_t); 7388275SEric Cheng extern void mac_bcast_delete(mac_client_impl_t *, const uint8_t *, uint16_t); 7398275SEric Cheng extern void mac_bcast_send(void *, void *, mblk_t *, boolean_t); 7408275SEric Cheng extern void mac_bcast_grp_free(void *); 7418275SEric Cheng extern void mac_bcast_refresh(mac_impl_t *, mac_multicst_t, void *, 7428275SEric Cheng boolean_t); 7438275SEric Cheng extern void mac_client_bcast_refresh(mac_client_impl_t *, mac_multicst_t, 7448275SEric Cheng void *, boolean_t); 7458275SEric Cheng 7468275SEric Cheng /* 7478275SEric Cheng * Grouping functions are used internally by MAC layer. 7488275SEric Cheng */ 7498275SEric Cheng extern int mac_group_addmac(mac_group_t *, const uint8_t *); 7508275SEric Cheng extern int mac_group_remmac(mac_group_t *, const uint8_t *); 7518275SEric Cheng extern int mac_rx_group_add_flow(mac_client_impl_t *, flow_entry_t *, 7528275SEric Cheng mac_group_t *); 75310309SSriharsha.Basavapatna@Sun.COM extern mblk_t *mac_hwring_tx(mac_ring_handle_t, mblk_t *); 75410491SRishi.Srivatsavai@Sun.COM extern mblk_t *mac_bridge_tx(mac_impl_t *, mac_ring_handle_t, mblk_t *); 755*11878SVenu.Iyer@Sun.COM extern mac_group_t *mac_reserve_rx_group(mac_client_impl_t *, uint8_t *, 756*11878SVenu.Iyer@Sun.COM boolean_t); 757*11878SVenu.Iyer@Sun.COM extern void mac_release_rx_group(mac_client_impl_t *, mac_group_t *); 758*11878SVenu.Iyer@Sun.COM extern int mac_rx_switch_group(mac_client_impl_t *, mac_group_t *, 759*11878SVenu.Iyer@Sun.COM mac_group_t *); 7608275SEric Cheng extern mac_ring_t *mac_reserve_tx_ring(mac_impl_t *, mac_ring_t *); 761*11878SVenu.Iyer@Sun.COM extern mac_group_t *mac_reserve_tx_group(mac_client_impl_t *, boolean_t); 762*11878SVenu.Iyer@Sun.COM extern void mac_release_tx_group(mac_client_impl_t *, mac_group_t *); 763*11878SVenu.Iyer@Sun.COM extern void mac_tx_switch_group(mac_client_impl_t *, mac_group_t *, 764*11878SVenu.Iyer@Sun.COM mac_group_t *); 765*11878SVenu.Iyer@Sun.COM extern void mac_rx_switch_grp_to_sw(mac_group_t *); 7668275SEric Cheng 7678275SEric Cheng /* 7688275SEric Cheng * MAC address functions are used internally by MAC layer. 7698275SEric Cheng */ 7708275SEric Cheng extern mac_address_t *mac_find_macaddr(mac_impl_t *, uint8_t *); 7718275SEric Cheng extern boolean_t mac_check_macaddr_shared(mac_address_t *); 7728275SEric Cheng extern int mac_update_macaddr(mac_address_t *, uint8_t *); 7738275SEric Cheng extern void mac_freshen_macaddr(mac_address_t *, uint8_t *); 7748275SEric Cheng extern void mac_retrieve_macaddr(mac_address_t *, uint8_t *); 7758275SEric Cheng extern void mac_init_macaddr(mac_impl_t *); 7768275SEric Cheng extern void mac_fini_macaddr(mac_impl_t *); 7778275SEric Cheng 7788275SEric Cheng /* 7798275SEric Cheng * Flow construction/destruction routines. 7808275SEric Cheng * Not meant to be used by mac clients. 7818275SEric Cheng */ 7828275SEric Cheng extern int mac_link_flow_init(mac_client_handle_t, flow_entry_t *); 7838275SEric Cheng extern void mac_link_flow_clean(mac_client_handle_t, flow_entry_t *); 7848275SEric Cheng 7858275SEric Cheng /* 7868400SNicolas.Droux@Sun.COM * Fanout update routines called when the link speed of the NIC changes 7878400SNicolas.Droux@Sun.COM * or when a MAC client's share is unbound. 7888275SEric Cheng */ 789*11878SVenu.Iyer@Sun.COM extern void mac_fanout_recompute_client(mac_client_impl_t *, cpupart_t *); 7908275SEric Cheng extern void mac_fanout_recompute(mac_impl_t *); 7918275SEric Cheng 7928275SEric Cheng /* 7938275SEric Cheng * The following functions are used internally by the MAC layer to 7948275SEric Cheng * add/remove/update flows associated with a mac_impl_t. They should 7958275SEric Cheng * never be used directly by MAC clients. 7968275SEric Cheng */ 7978275SEric Cheng extern int mac_datapath_setup(mac_client_impl_t *, flow_entry_t *, uint32_t); 7988275SEric Cheng extern void mac_datapath_teardown(mac_client_impl_t *, flow_entry_t *, 7998275SEric Cheng uint32_t); 800*11878SVenu.Iyer@Sun.COM extern void mac_rx_srs_group_setup(mac_client_impl_t *, flow_entry_t *, 801*11878SVenu.Iyer@Sun.COM uint32_t); 802*11878SVenu.Iyer@Sun.COM extern void mac_tx_srs_group_setup(mac_client_impl_t *, flow_entry_t *, 803*11878SVenu.Iyer@Sun.COM uint32_t); 804*11878SVenu.Iyer@Sun.COM extern void mac_rx_srs_group_teardown(flow_entry_t *, boolean_t); 805*11878SVenu.Iyer@Sun.COM extern void mac_tx_srs_group_teardown(mac_client_impl_t *, flow_entry_t *, 8068275SEric Cheng uint32_t); 8078275SEric Cheng extern int mac_rx_classify_flow_quiesce(flow_entry_t *, void *); 8088275SEric Cheng extern int mac_rx_classify_flow_restart(flow_entry_t *, void *); 8098275SEric Cheng extern void mac_client_quiesce(mac_client_impl_t *); 8108275SEric Cheng extern void mac_client_restart(mac_client_impl_t *); 8118275SEric Cheng 8128275SEric Cheng extern void mac_flow_update_priority(mac_client_impl_t *, flow_entry_t *); 8138275SEric Cheng 8148275SEric Cheng extern void mac_flow_rem_subflow(flow_entry_t *); 8158275SEric Cheng extern void mac_rename_flow(flow_entry_t *, const char *); 8168275SEric Cheng extern void mac_flow_set_name(flow_entry_t *, const char *); 8178275SEric Cheng 8188275SEric Cheng extern mblk_t *mac_add_vlan_tag(mblk_t *, uint_t, uint16_t); 8198275SEric Cheng extern mblk_t *mac_add_vlan_tag_chain(mblk_t *, uint_t, uint16_t); 8208275SEric Cheng extern mblk_t *mac_strip_vlan_tag_chain(mblk_t *); 8218275SEric Cheng extern void mac_pkt_drop(void *, mac_resource_handle_t, mblk_t *, boolean_t); 8228275SEric Cheng extern mblk_t *mac_rx_flow(mac_handle_t, mac_resource_handle_t, mblk_t *); 8238275SEric Cheng 8248275SEric Cheng extern void i_mac_share_alloc(mac_client_impl_t *); 8258275SEric Cheng extern void i_mac_share_free(mac_client_impl_t *); 8268275SEric Cheng extern void i_mac_perim_enter(mac_impl_t *); 8278275SEric Cheng extern void i_mac_perim_exit(mac_impl_t *); 8288275SEric Cheng extern int i_mac_perim_enter_nowait(mac_impl_t *); 8298275SEric Cheng extern void i_mac_tx_srs_notify(mac_impl_t *, mac_ring_handle_t); 8308275SEric Cheng extern int mac_hold(const char *, mac_impl_t **); 8318275SEric Cheng extern void mac_rele(mac_impl_t *); 8328275SEric Cheng extern int i_mac_disable(mac_impl_t *); 8338275SEric Cheng extern void i_mac_notify(mac_impl_t *, mac_notify_type_t); 8348275SEric Cheng extern void i_mac_notify_exit(mac_impl_t *); 8358275SEric Cheng extern void mac_rx_group_unmark(mac_group_t *, uint_t); 8368275SEric Cheng extern void mac_tx_client_flush(mac_client_impl_t *); 8378275SEric Cheng extern void mac_tx_client_block(mac_client_impl_t *); 8388275SEric Cheng extern void mac_tx_client_unblock(mac_client_impl_t *); 839*11878SVenu.Iyer@Sun.COM extern void mac_tx_invoke_callbacks(mac_client_impl_t *, mac_tx_cookie_t); 8409641SGirish.Moodalbail@Sun.COM extern int i_mac_promisc_set(mac_impl_t *, boolean_t); 8418275SEric Cheng extern void i_mac_promisc_walker_cleanup(mac_impl_t *); 8428275SEric Cheng extern mactype_t *mactype_getplugin(const char *); 8438275SEric Cheng extern void mac_addr_factory_init(mac_impl_t *); 8448275SEric Cheng extern void mac_addr_factory_fini(mac_impl_t *); 845*11878SVenu.Iyer@Sun.COM extern void mac_register_priv_prop(mac_impl_t *, char **); 8468275SEric Cheng extern void mac_unregister_priv_prop(mac_impl_t *); 8478275SEric Cheng extern int mac_init_rings(mac_impl_t *, mac_ring_type_t); 8488275SEric Cheng extern void mac_free_rings(mac_impl_t *, mac_ring_type_t); 849*11878SVenu.Iyer@Sun.COM extern void mac_compare_ddi_handle(mac_group_t *, uint_t, mac_ring_t *); 8508275SEric Cheng 8518275SEric Cheng extern int mac_start_group(mac_group_t *); 8528275SEric Cheng extern void mac_stop_group(mac_group_t *); 8538275SEric Cheng extern int mac_start_ring(mac_ring_t *); 8548275SEric Cheng extern void mac_stop_ring(mac_ring_t *); 8558400SNicolas.Droux@Sun.COM extern int mac_add_macaddr(mac_impl_t *, mac_group_t *, uint8_t *, boolean_t); 8568275SEric Cheng extern int mac_remove_macaddr(mac_address_t *); 8578275SEric Cheng 858*11878SVenu.Iyer@Sun.COM extern void mac_set_group_state(mac_group_t *, mac_group_state_t); 859*11878SVenu.Iyer@Sun.COM extern void mac_group_add_client(mac_group_t *, mac_client_impl_t *); 860*11878SVenu.Iyer@Sun.COM extern void mac_group_remove_client(mac_group_t *, mac_client_impl_t *); 861*11878SVenu.Iyer@Sun.COM 8628275SEric Cheng extern int i_mac_group_add_ring(mac_group_t *, mac_ring_t *, int); 8638275SEric Cheng extern void i_mac_group_rem_ring(mac_group_t *, mac_ring_t *, boolean_t); 864*11878SVenu.Iyer@Sun.COM extern int mac_group_ring_modify(mac_client_impl_t *, mac_group_t *, 865*11878SVenu.Iyer@Sun.COM mac_group_t *); 866*11878SVenu.Iyer@Sun.COM extern void mac_poll_state_change(mac_handle_t, boolean_t); 8676512Ssowmini 868*11878SVenu.Iyer@Sun.COM extern mac_group_state_t mac_group_next_state(mac_group_t *, 869*11878SVenu.Iyer@Sun.COM mac_client_impl_t **, mac_group_t *, boolean_t); 87010491SRishi.Srivatsavai@Sun.COM 87110734SEric Cheng extern mblk_t *mac_protect_check(mac_client_handle_t, mblk_t *); 87210734SEric Cheng extern int mac_protect_set(mac_client_handle_t, mac_resource_props_t *); 87310734SEric Cheng extern boolean_t mac_protect_enabled(mac_client_handle_t, uint32_t); 87410734SEric Cheng extern int mac_protect_validate(mac_resource_props_t *); 87510734SEric Cheng extern void mac_protect_update(mac_resource_props_t *, mac_resource_props_t *); 876*11878SVenu.Iyer@Sun.COM extern void mac_protect_update_v6_local_addr(mac_client_impl_t *); 877*11878SVenu.Iyer@Sun.COM extern void mac_protect_intercept_dhcp(mac_client_impl_t *, mblk_t *); 878*11878SVenu.Iyer@Sun.COM extern void mac_protect_flush_dhcp(mac_client_impl_t *); 879*11878SVenu.Iyer@Sun.COM extern void mac_protect_cancel_timer(mac_client_impl_t *); 880*11878SVenu.Iyer@Sun.COM extern void mac_protect_init(mac_client_impl_t *); 881*11878SVenu.Iyer@Sun.COM extern void mac_protect_fini(mac_client_impl_t *); 882*11878SVenu.Iyer@Sun.COM 883*11878SVenu.Iyer@Sun.COM extern int mac_set_resources(mac_handle_t, mac_resource_props_t *); 884*11878SVenu.Iyer@Sun.COM extern void mac_get_resources(mac_handle_t, mac_resource_props_t *); 885*11878SVenu.Iyer@Sun.COM extern void mac_get_effective_resources(mac_handle_t, mac_resource_props_t *); 886*11878SVenu.Iyer@Sun.COM 887*11878SVenu.Iyer@Sun.COM extern cpupart_t *mac_pset_find(mac_resource_props_t *, boolean_t *); 888*11878SVenu.Iyer@Sun.COM extern void mac_set_pool_effective(boolean_t, cpupart_t *, 889*11878SVenu.Iyer@Sun.COM mac_resource_props_t *, mac_resource_props_t *); 890*11878SVenu.Iyer@Sun.COM extern void mac_set_rings_effective(mac_client_impl_t *); 891*11878SVenu.Iyer@Sun.COM extern mac_client_impl_t *mac_check_primary_relocation(mac_client_impl_t *, 892*11878SVenu.Iyer@Sun.COM boolean_t); 89310734SEric Cheng 89410491SRishi.Srivatsavai@Sun.COM /* Global callbacks into the bridging module (when loaded) */ 89510491SRishi.Srivatsavai@Sun.COM extern mac_bridge_tx_t mac_bridge_tx_cb; 89610491SRishi.Srivatsavai@Sun.COM extern mac_bridge_rx_t mac_bridge_rx_cb; 89710491SRishi.Srivatsavai@Sun.COM extern mac_bridge_ref_t mac_bridge_ref_cb; 89810491SRishi.Srivatsavai@Sun.COM extern mac_bridge_ls_t mac_bridge_ls_cb; 89910491SRishi.Srivatsavai@Sun.COM 900*11878SVenu.Iyer@Sun.COM 9010Sstevel@tonic-gate #ifdef __cplusplus 9020Sstevel@tonic-gate } 9030Sstevel@tonic-gate #endif 9040Sstevel@tonic-gate 9050Sstevel@tonic-gate #endif /* _SYS_MAC_IMPL_H */ 906