17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5490ed22dSyz147064 * Common Development and Distribution License (the "License"). 6490ed22dSyz147064 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 220591ddd0SPrakash Jalan * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 2348a4016cSRobert Mustacchi * Copyright (c) 2017, Joyent, Inc. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _SYS_MAC_IMPL_H 277c478bd9Sstevel@tonic-gate #define _SYS_MAC_IMPL_H 287c478bd9Sstevel@tonic-gate 290dc2366fSVenugopal Iyer #include <sys/cpupart.h> 30da14cebeSEric Cheng #include <sys/modhash.h> 31da14cebeSEric Cheng #include <sys/mac_client.h> 32da14cebeSEric Cheng #include <sys/mac_provider.h> 334eaa4710SRishi Srivatsavai #include <sys/note.h> 340dc2366fSVenugopal Iyer #include <sys/avl.h> 35ba2e4443Sseb #include <net/if.h> 36da14cebeSEric Cheng #include <sys/mac_flow_impl.h> 37da14cebeSEric Cheng #include <netinet/ip6.h> 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #ifdef __cplusplus 407c478bd9Sstevel@tonic-gate extern "C" { 417c478bd9Sstevel@tonic-gate #endif 427c478bd9Sstevel@tonic-gate 4361af1958SGarrett D'Amore /* 4461af1958SGarrett D'Amore * This is the first minor number available for MAC provider private 4561af1958SGarrett D'Amore * use. This makes it possible to deliver a driver that is both a MAC 4661af1958SGarrett D'Amore * provider and a regular character/block device. See PSARC 2009/380 4761af1958SGarrett D'Amore * for more detail about the construction of such devices. The value 4861af1958SGarrett D'Amore * chosen leaves half of the 32-bit minor numbers (which are really 4961af1958SGarrett D'Amore * only 18 bits wide) available for driver private use. Drivers can 5061af1958SGarrett D'Amore * easily identify their private number by the presence of this value 5161af1958SGarrett D'Amore * in the bits that make up the minor number, since its just the 5261af1958SGarrett D'Amore * highest bit available for such minor numbers. 5361af1958SGarrett D'Amore */ 5461af1958SGarrett D'Amore #define MAC_PRIVATE_MINOR ((MAXMIN32 + 1) / 2) 5561af1958SGarrett D'Amore 5661af1958SGarrett D'Amore /* 5761af1958SGarrett D'Amore * The maximum minor number that corresponds to a real instance. This 5861af1958SGarrett D'Amore * limits the number of physical ports that a mac provider can offer. 5961af1958SGarrett D'Amore * Note that this macro must be synchronized with DLS_MAX_MINOR in 6061af1958SGarrett D'Amore * <sys/dls.h> 6161af1958SGarrett D'Amore */ 6261af1958SGarrett D'Amore #define MAC_MAX_MINOR 1000 6361af1958SGarrett D'Amore 64d62bc4baSyz147064 typedef struct mac_margin_req_s mac_margin_req_t; 65d62bc4baSyz147064 66d62bc4baSyz147064 struct mac_margin_req_s { 67d62bc4baSyz147064 mac_margin_req_t *mmr_nextp; 68d62bc4baSyz147064 uint_t mmr_ref; 69d62bc4baSyz147064 uint32_t mmr_margin; 70d62bc4baSyz147064 }; 71d62bc4baSyz147064 72a776d98eSRobert Mustacchi typedef struct mac_mtu_req_s mac_mtu_req_t; 73a776d98eSRobert Mustacchi struct mac_mtu_req_s { 74a776d98eSRobert Mustacchi mac_mtu_req_t *mtr_nextp; 75a776d98eSRobert Mustacchi uint_t mtr_ref; 76a776d98eSRobert Mustacchi uint32_t mtr_mtu; 77a776d98eSRobert Mustacchi }; 78a776d98eSRobert Mustacchi 79da14cebeSEric Cheng /* Generic linked chain type */ 80da14cebeSEric Cheng typedef struct mac_chain_s { 81da14cebeSEric Cheng struct mac_chain_s *next; 82da14cebeSEric Cheng void *item; 83da14cebeSEric Cheng } mac_chain_t; 847c478bd9Sstevel@tonic-gate 85da14cebeSEric Cheng /* 86da14cebeSEric Cheng * Generic mac callback list manipulation structures and macros. The mac_cb_t 87da14cebeSEric Cheng * represents a general callback list element embedded in a particular 88da14cebeSEric Cheng * data structure such as a mac_notify_cb_t or a mac_promisc_impl_t. 89da14cebeSEric Cheng * The mac_cb_info_t represents general information about list walkers. 90da14cebeSEric Cheng * Please see the comments above mac_callback_add for more information. 91da14cebeSEric Cheng */ 92da14cebeSEric Cheng /* mcb_flags */ 93da14cebeSEric Cheng #define MCB_CONDEMNED 0x1 /* Logically deleted */ 94da14cebeSEric Cheng #define MCB_NOTIFY_CB_T 0x2 95da14cebeSEric Cheng #define MCB_TX_NOTIFY_CB_T 0x4 967c478bd9Sstevel@tonic-gate 970dc2366fSVenugopal Iyer extern boolean_t mac_tx_serialize; 980dc2366fSVenugopal Iyer 99da14cebeSEric Cheng typedef struct mac_cb_s { 100da14cebeSEric Cheng struct mac_cb_s *mcb_nextp; /* Linked list of callbacks */ 101da14cebeSEric Cheng void *mcb_objp; /* Ptr to enclosing object */ 102da14cebeSEric Cheng size_t mcb_objsize; /* Sizeof the enclosing obj */ 103da14cebeSEric Cheng uint_t mcb_flags; 104da14cebeSEric Cheng } mac_cb_t; 1057c478bd9Sstevel@tonic-gate 106da14cebeSEric Cheng typedef struct mac_cb_info_s { 107da14cebeSEric Cheng kmutex_t *mcbi_lockp; 108da14cebeSEric Cheng kcondvar_t mcbi_cv; 109da14cebeSEric Cheng uint_t mcbi_del_cnt; /* Deleted callback cnt */ 110da14cebeSEric Cheng uint_t mcbi_walker_cnt; /* List walker count */ 111da14cebeSEric Cheng } mac_cb_info_t; 1127c478bd9Sstevel@tonic-gate 113da14cebeSEric Cheng typedef struct mac_notify_cb_s { 114da14cebeSEric Cheng mac_cb_t mncb_link; /* Linked list of callbacks */ 115da14cebeSEric Cheng mac_notify_t mncb_fn; /* callback function */ 116da14cebeSEric Cheng void *mncb_arg; /* callback argument */ 117da14cebeSEric Cheng struct mac_impl_s *mncb_mip; 118da14cebeSEric Cheng } mac_notify_cb_t; 1197c478bd9Sstevel@tonic-gate 120da14cebeSEric Cheng /* 121da14cebeSEric Cheng * mac_callback_add(listinfo, listhead, listelement) 122da14cebeSEric Cheng * mac_callback_remove(listinfo, listhead, listelement) 123da14cebeSEric Cheng */ 124da14cebeSEric Cheng typedef boolean_t (*mcb_func_t)(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 125da14cebeSEric Cheng 126da14cebeSEric Cheng #define MAC_CALLBACK_WALKER_INC(mcbi) { \ 127da14cebeSEric Cheng mutex_enter((mcbi)->mcbi_lockp); \ 128da14cebeSEric Cheng (mcbi)->mcbi_walker_cnt++; \ 129da14cebeSEric Cheng mutex_exit((mcbi)->mcbi_lockp); \ 130da14cebeSEric Cheng } 131da14cebeSEric Cheng 132da14cebeSEric Cheng #define MAC_CALLBACK_WALKER_INC_HELD(mcbi) (mcbi)->mcbi_walker_cnt++; 133da14cebeSEric Cheng 134da14cebeSEric Cheng #define MAC_CALLBACK_WALKER_DCR(mcbi, headp) { \ 135da14cebeSEric Cheng mac_cb_t *rmlist; \ 136da14cebeSEric Cheng \ 137da14cebeSEric Cheng mutex_enter((mcbi)->mcbi_lockp); \ 138da14cebeSEric Cheng if (--(mcbi)->mcbi_walker_cnt == 0 && (mcbi)->mcbi_del_cnt != 0) { \ 139da14cebeSEric Cheng rmlist = mac_callback_walker_cleanup((mcbi), headp); \ 140da14cebeSEric Cheng mac_callback_free(rmlist); \ 141da14cebeSEric Cheng cv_broadcast(&(mcbi)->mcbi_cv); \ 142da14cebeSEric Cheng } \ 143da14cebeSEric Cheng mutex_exit((mcbi)->mcbi_lockp); \ 144da14cebeSEric Cheng } 145da14cebeSEric Cheng 146da14cebeSEric Cheng #define MAC_PROMISC_WALKER_INC(mip) \ 147da14cebeSEric Cheng MAC_CALLBACK_WALKER_INC(&(mip)->mi_promisc_cb_info) 148da14cebeSEric Cheng 149da14cebeSEric Cheng #define MAC_PROMISC_WALKER_DCR(mip) { \ 150da14cebeSEric Cheng mac_cb_info_t *mcbi; \ 151da14cebeSEric Cheng \ 152da14cebeSEric Cheng mcbi = &(mip)->mi_promisc_cb_info; \ 153da14cebeSEric Cheng mutex_enter(mcbi->mcbi_lockp); \ 154da14cebeSEric Cheng if (--mcbi->mcbi_walker_cnt == 0 && mcbi->mcbi_del_cnt != 0) { \ 155da14cebeSEric Cheng i_mac_promisc_walker_cleanup(mip); \ 156da14cebeSEric Cheng cv_broadcast(&mcbi->mcbi_cv); \ 157da14cebeSEric Cheng } \ 158da14cebeSEric Cheng mutex_exit(mcbi->mcbi_lockp); \ 159da14cebeSEric Cheng } 1607c478bd9Sstevel@tonic-gate 161ba2e4443Sseb typedef struct mactype_s { 162ba2e4443Sseb const char *mt_ident; 163ba2e4443Sseb uint32_t mt_ref; 164ba2e4443Sseb uint_t mt_type; 1650ba2cbe9Sxc151355 uint_t mt_nativetype; 166ba2e4443Sseb size_t mt_addr_length; 167ba2e4443Sseb uint8_t *mt_brdcst_addr; 168ba2e4443Sseb mactype_ops_t mt_ops; 169ba2e4443Sseb mac_stat_info_t *mt_stats; /* array of mac_stat_info_t elements */ 170ba2e4443Sseb size_t mt_statcount; /* number of elements in mt_stats */ 1714045d941Ssowmini mac_ndd_mapping_t *mt_mapping; 1724045d941Ssowmini size_t mt_mappingcount; 173ba2e4443Sseb } mactype_t; 1747c478bd9Sstevel@tonic-gate 175da14cebeSEric Cheng /* 176da14cebeSEric Cheng * Multiple rings implementation. 177da14cebeSEric Cheng */ 178da14cebeSEric Cheng typedef enum { 179da14cebeSEric Cheng MAC_GROUP_STATE_UNINIT = 0, /* initial state of data structure */ 180da14cebeSEric Cheng MAC_GROUP_STATE_REGISTERED, /* hooked with h/w group */ 181da14cebeSEric Cheng MAC_GROUP_STATE_RESERVED, /* group is reserved and opened */ 182da14cebeSEric Cheng MAC_GROUP_STATE_SHARED /* default group shared among */ 183da14cebeSEric Cheng /* multiple mac clients */ 184da14cebeSEric Cheng } mac_group_state_t; 185843e1988Sjohnlev 186da14cebeSEric Cheng typedef struct mac_ring_s mac_ring_t; 187da14cebeSEric Cheng typedef struct mac_group_s mac_group_t; 1884045d941Ssowmini 189ba2e4443Sseb /* 190da14cebeSEric Cheng * Ring data structure for ring control and management. 191ba2e4443Sseb */ 192da14cebeSEric Cheng typedef enum { 193da14cebeSEric Cheng MR_FREE, /* Available for assignment to flows */ 194da14cebeSEric Cheng MR_NEWLY_ADDED, /* Just assigned to another group */ 195da14cebeSEric Cheng MR_INUSE /* Assigned to an SRS */ 196da14cebeSEric Cheng } mac_ring_state_t; 197da14cebeSEric Cheng 198da14cebeSEric Cheng /* mr_flag values */ 199da14cebeSEric Cheng #define MR_INCIPIENT 0x1 200da14cebeSEric Cheng #define MR_CONDEMNED 0x2 201da14cebeSEric Cheng #define MR_QUIESCE 0x4 202da14cebeSEric Cheng 2030dc2366fSVenugopal Iyer typedef struct mac_impl_s mac_impl_t; 2040dc2366fSVenugopal Iyer 205da14cebeSEric Cheng struct mac_ring_s { 206da14cebeSEric Cheng int mr_index; /* index in the original list */ 207da14cebeSEric Cheng mac_ring_type_t mr_type; /* ring type */ 208da14cebeSEric Cheng mac_ring_t *mr_next; /* next ring in the chain */ 209da14cebeSEric Cheng mac_group_handle_t mr_gh; /* reference to group */ 210da14cebeSEric Cheng 211da14cebeSEric Cheng mac_classify_type_t mr_classify_type; /* HW vs SW */ 212da14cebeSEric Cheng struct mac_soft_ring_set_s *mr_srs; /* associated SRS */ 2130dc2366fSVenugopal Iyer mac_ring_handle_t mr_prh; /* associated pseudo ring hdl */ 214da14cebeSEric Cheng uint_t mr_refcnt; /* Ring references */ 215da14cebeSEric Cheng /* ring generation no. to guard against drivers using stale rings */ 216da14cebeSEric Cheng uint64_t mr_gen_num; 217da14cebeSEric Cheng 2180dc2366fSVenugopal Iyer kstat_t *mr_ksp; /* ring kstats */ 2190dc2366fSVenugopal Iyer mac_impl_t *mr_mip; /* pointer to primary's mip */ 2200dc2366fSVenugopal Iyer 221da14cebeSEric Cheng kmutex_t mr_lock; 222da14cebeSEric Cheng kcondvar_t mr_cv; /* mr_lock */ 223da14cebeSEric Cheng mac_ring_state_t mr_state; /* mr_lock */ 224da14cebeSEric Cheng uint_t mr_flag; /* mr_lock */ 225da14cebeSEric Cheng 226da14cebeSEric Cheng mac_ring_info_t mr_info; /* driver supplied info */ 227da14cebeSEric Cheng }; 228da14cebeSEric Cheng #define mr_driver mr_info.mri_driver 229da14cebeSEric Cheng #define mr_start mr_info.mri_start 230da14cebeSEric Cheng #define mr_stop mr_info.mri_stop 2310dc2366fSVenugopal Iyer #define mr_stat mr_info.mri_stat 232da14cebeSEric Cheng 233da14cebeSEric Cheng #define MAC_RING_MARK(mr, flag) \ 234da14cebeSEric Cheng (mr)->mr_flag |= flag; 235da14cebeSEric Cheng 236da14cebeSEric Cheng #define MAC_RING_UNMARK(mr, flag) \ 237da14cebeSEric Cheng (mr)->mr_flag &= ~flag; 238da14cebeSEric Cheng 239d62bc4baSyz147064 /* 240da14cebeSEric Cheng * Reference hold and release on mac_ring_t 'mr' 241d62bc4baSyz147064 */ 242da14cebeSEric Cheng #define MR_REFHOLD_LOCKED(mr) { \ 243da14cebeSEric Cheng ASSERT(MUTEX_HELD(&mr->mr_lock)); \ 244da14cebeSEric Cheng (mr)->mr_refcnt++; \ 245da14cebeSEric Cheng } 246d62bc4baSyz147064 247da14cebeSEric Cheng #define MR_REFRELE(mr) { \ 248da14cebeSEric Cheng mutex_enter(&(mr)->mr_lock); \ 249da14cebeSEric Cheng ASSERT((mr)->mr_refcnt != 0); \ 250da14cebeSEric Cheng (mr)->mr_refcnt--; \ 251da14cebeSEric Cheng if ((mr)->mr_refcnt == 0 && \ 252da14cebeSEric Cheng ((mr)->mr_flag & (MR_CONDEMNED | MR_QUIESCE))) \ 253da14cebeSEric Cheng cv_signal(&(mr)->mr_cv); \ 254da14cebeSEric Cheng mutex_exit(&(mr)->mr_lock); \ 255da14cebeSEric Cheng } 256d62bc4baSyz147064 257da14cebeSEric Cheng /* 258da14cebeSEric Cheng * Per mac client flow information associated with a RX group. 259da14cebeSEric Cheng * The entire structure is SL protected. 260da14cebeSEric Cheng */ 261da14cebeSEric Cheng typedef struct mac_grp_client { 262da14cebeSEric Cheng struct mac_grp_client *mgc_next; 263da14cebeSEric Cheng struct mac_client_impl_s *mgc_client; 264da14cebeSEric Cheng } mac_grp_client_t; 265d62bc4baSyz147064 2660dc2366fSVenugopal Iyer #define MAC_GROUP_NO_CLIENT(g) ((g)->mrg_clients == NULL) 267d62bc4baSyz147064 2680dc2366fSVenugopal Iyer #define MAC_GROUP_ONLY_CLIENT(g) \ 269da14cebeSEric Cheng ((((g)->mrg_clients != NULL) && \ 270da14cebeSEric Cheng ((g)->mrg_clients->mgc_next == NULL)) ? \ 271da14cebeSEric Cheng (g)->mrg_clients->mgc_client : NULL) 272d62bc4baSyz147064 273da14cebeSEric Cheng /* 274da14cebeSEric Cheng * Common ring group data structure for ring control and management. 275da14cebeSEric Cheng * The entire structure is SL protected 276da14cebeSEric Cheng */ 277da14cebeSEric Cheng struct mac_group_s { 278da14cebeSEric Cheng int mrg_index; /* index in the list */ 279da14cebeSEric Cheng mac_ring_type_t mrg_type; /* ring type */ 280da14cebeSEric Cheng mac_group_state_t mrg_state; /* state of the group */ 281da14cebeSEric Cheng mac_group_t *mrg_next; /* next ring in the chain */ 282da14cebeSEric Cheng mac_handle_t mrg_mh; /* reference to MAC */ 283da14cebeSEric Cheng mac_ring_t *mrg_rings; /* grouped rings */ 284da14cebeSEric Cheng uint_t mrg_cur_count; /* actual size of group */ 285d62bc4baSyz147064 286da14cebeSEric Cheng mac_grp_client_t *mrg_clients; /* clients list */ 287d62bc4baSyz147064 288da14cebeSEric Cheng mac_group_info_t mrg_info; /* driver supplied info */ 289da14cebeSEric Cheng }; 290d62bc4baSyz147064 291da14cebeSEric Cheng #define mrg_driver mrg_info.mgi_driver 292da14cebeSEric Cheng #define mrg_start mrg_info.mgi_start 293da14cebeSEric Cheng #define mrg_stop mrg_info.mgi_stop 294da14cebeSEric Cheng 295da14cebeSEric Cheng #define GROUP_INTR_HANDLE(g) (g)->mrg_info.mgi_intr.mi_handle 296da14cebeSEric Cheng #define GROUP_INTR_ENABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_enable 297da14cebeSEric Cheng #define GROUP_INTR_DISABLE_FUNC(g) (g)->mrg_info.mgi_intr.mi_disable 298da14cebeSEric Cheng 2994eaa4710SRishi Srivatsavai #define MAC_RING_TX(mhp, rh, mp, rest) { \ 3004eaa4710SRishi Srivatsavai mac_ring_handle_t mrh = rh; \ 3014eaa4710SRishi Srivatsavai mac_impl_t *mimpl = (mac_impl_t *)mhp; \ 302da14cebeSEric Cheng /* \ 3034eaa4710SRishi Srivatsavai * Send packets through a selected tx ring, or through the \ 3044eaa4710SRishi Srivatsavai * default handler if there is no selected ring. \ 305da14cebeSEric Cheng */ \ 3064eaa4710SRishi Srivatsavai if (mrh == NULL) \ 3074eaa4710SRishi Srivatsavai mrh = mimpl->mi_default_tx_ring; \ 3084eaa4710SRishi Srivatsavai if (mrh == NULL) { \ 3094eaa4710SRishi Srivatsavai rest = mimpl->mi_tx(mimpl->mi_driver, mp); \ 3104eaa4710SRishi Srivatsavai } else { \ 3114eaa4710SRishi Srivatsavai rest = mac_hwring_tx(mrh, mp); \ 3124eaa4710SRishi Srivatsavai } \ 3134eaa4710SRishi Srivatsavai } 3144eaa4710SRishi Srivatsavai 3154eaa4710SRishi Srivatsavai /* 3164eaa4710SRishi Srivatsavai * This is the final stop before reaching the underlying driver 3174eaa4710SRishi Srivatsavai * or aggregation, so this is where the bridging hook is implemented. 3184eaa4710SRishi Srivatsavai * Packets that are bridged will return through mac_bridge_tx(), with 3194eaa4710SRishi Srivatsavai * rh nulled out if the bridge chooses to send output on a different 3204eaa4710SRishi Srivatsavai * link due to forwarding. 3214eaa4710SRishi Srivatsavai */ 3220dc2366fSVenugopal Iyer #define MAC_TX(mip, rh, mp, src_mcip) { \ 3230dc2366fSVenugopal Iyer mac_ring_handle_t rhandle = (rh); \ 3244eaa4710SRishi Srivatsavai /* \ 3254eaa4710SRishi Srivatsavai * If there is a bound Hybrid I/O share, send packets through \ 3264eaa4710SRishi Srivatsavai * the default tx ring. (When there's a bound Hybrid I/O share, \ 3274eaa4710SRishi Srivatsavai * the tx rings of this client are mapped in the guest domain \ 3284eaa4710SRishi Srivatsavai * and not accessible from here.) \ 3294eaa4710SRishi Srivatsavai */ \ 3304eaa4710SRishi Srivatsavai _NOTE(CONSTANTCONDITION) \ 3310dc2366fSVenugopal Iyer if ((src_mcip)->mci_state_flags & MCIS_SHARE_BOUND) \ 3320dc2366fSVenugopal Iyer rhandle = (mip)->mi_default_tx_ring; \ 3330dc2366fSVenugopal Iyer if (mip->mi_promisc_list != NULL) \ 3340dc2366fSVenugopal Iyer mac_promisc_dispatch(mip, mp, src_mcip); \ 3354eaa4710SRishi Srivatsavai /* \ 3364eaa4710SRishi Srivatsavai * Grab the proper transmit pointer and handle. Special \ 3374eaa4710SRishi Srivatsavai * optimization: we can test mi_bridge_link itself atomically, \ 3384eaa4710SRishi Srivatsavai * and if that indicates no bridge send packets through tx ring.\ 3394eaa4710SRishi Srivatsavai */ \ 3404eaa4710SRishi Srivatsavai if (mip->mi_bridge_link == NULL) { \ 3410dc2366fSVenugopal Iyer MAC_RING_TX(mip, rhandle, mp, mp); \ 3424eaa4710SRishi Srivatsavai } else { \ 3430dc2366fSVenugopal Iyer mp = mac_bridge_tx(mip, rhandle, mp); \ 3444eaa4710SRishi Srivatsavai } \ 345da14cebeSEric Cheng } 346da14cebeSEric Cheng 347da14cebeSEric Cheng /* mci_tx_flag */ 348da14cebeSEric Cheng #define MCI_TX_QUIESCE 0x1 349da14cebeSEric Cheng 350da14cebeSEric Cheng typedef struct mac_factory_addr_s { 351da14cebeSEric Cheng boolean_t mfa_in_use; 352da14cebeSEric Cheng uint8_t mfa_addr[MAXMACADDRLEN]; 353da14cebeSEric Cheng struct mac_client_impl_s *mfa_client; 354da14cebeSEric Cheng } mac_factory_addr_t; 355da14cebeSEric Cheng 356da14cebeSEric Cheng typedef struct mac_mcast_addrs_s { 357da14cebeSEric Cheng struct mac_mcast_addrs_s *mma_next; 358da14cebeSEric Cheng uint8_t mma_addr[MAXMACADDRLEN]; 359da14cebeSEric Cheng int mma_ref; 360da14cebeSEric Cheng } mac_mcast_addrs_t; 361da14cebeSEric Cheng 362da14cebeSEric Cheng typedef enum { 363da14cebeSEric Cheng MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED = 1, /* hardware steering */ 364da14cebeSEric Cheng MAC_ADDRESS_TYPE_UNICAST_PROMISC /* promiscuous mode */ 365da14cebeSEric Cheng } mac_address_type_t; 366da14cebeSEric Cheng 367da14cebeSEric Cheng typedef struct mac_address_s { 368da14cebeSEric Cheng mac_address_type_t ma_type; /* address type */ 369da14cebeSEric Cheng int ma_nusers; /* number of users */ 370da14cebeSEric Cheng /* of that address */ 371da14cebeSEric Cheng struct mac_address_s *ma_next; /* next address */ 372da14cebeSEric Cheng uint8_t ma_addr[MAXMACADDRLEN]; /* address value */ 373da14cebeSEric Cheng size_t ma_len; /* address length */ 374da14cebeSEric Cheng mac_group_t *ma_group; /* asscociated group */ 375da14cebeSEric Cheng mac_impl_t *ma_mip; /* MAC handle */ 376da14cebeSEric Cheng } mac_address_t; 377da14cebeSEric Cheng 378da14cebeSEric Cheng extern krwlock_t i_mac_impl_lock; 379da14cebeSEric Cheng extern mod_hash_t *i_mac_impl_hash; 380da14cebeSEric Cheng extern kmem_cache_t *i_mac_impl_cachep; 381da14cebeSEric Cheng extern uint_t i_mac_impl_count; 382da14cebeSEric Cheng 383da14cebeSEric Cheng /* 384da14cebeSEric Cheng * Each registered MAC is associated with a mac_impl_t structure. The 385da14cebeSEric Cheng * structure represents the undelying hardware, in terms of definition, 386da14cebeSEric Cheng * resources (transmit, receive rings etc.), callback functions etc. It 387da14cebeSEric Cheng * also holds the table of MAC clients that are configured on the device. 388da14cebeSEric Cheng * The table is used for classifying incoming packets in software. 389da14cebeSEric Cheng * 390da14cebeSEric Cheng * The protection scheme uses 2 elements, a coarse serialization mechanism 391da14cebeSEric Cheng * called perimeter and a finer traditional lock based scheme. More details 392da14cebeSEric Cheng * can be found in the big block comment in mac.c. 393da14cebeSEric Cheng * 394da14cebeSEric Cheng * The protection scheme for each member of the mac_impl_t is described below. 395da14cebeSEric Cheng * 396da14cebeSEric Cheng * Write Once Only (WO): Typically these don't change for the lifetime of the 397da14cebeSEric Cheng * data structure. For example something in mac_impl_t that stays the same 398da14cebeSEric Cheng * from mac_register to mac_unregister, or something in a mac_client_impl_t 399da14cebeSEric Cheng * that stays the same from mac_client_open to mac_client_close. 400da14cebeSEric Cheng * 401da14cebeSEric Cheng * Serializer (SL): Protected by the Serializer. All SLOP operations on a 402da14cebeSEric Cheng * mac endpoint go through the serializer. MTOPs don't care about reading 403da14cebeSEric Cheng * these fields atomically. 404da14cebeSEric Cheng * 405da14cebeSEric Cheng * Lock: Traditional mutex/rw lock. Modify operations still go through the 406da14cebeSEric Cheng * mac serializer, the lock helps synchronize readers with writers. 407da14cebeSEric Cheng */ 408da14cebeSEric Cheng struct mac_impl_s { 409da14cebeSEric Cheng krwlock_t mi_rw_lock; 410c228408bSMichael Lim list_node_t mi_node; 411da14cebeSEric Cheng char mi_name[LIFNAMSIZ]; /* WO */ 412da14cebeSEric Cheng uint32_t mi_state_flags; 413da14cebeSEric Cheng void *mi_driver; /* Driver private, WO */ 414da14cebeSEric Cheng mac_info_t mi_info; /* WO */ 415da14cebeSEric Cheng mactype_t *mi_type; /* WO */ 416da14cebeSEric Cheng void *mi_pdata; /* WO */ 417da14cebeSEric Cheng size_t mi_pdata_size; /* WO */ 418da14cebeSEric Cheng mac_callbacks_t *mi_callbacks; /* WO */ 419da14cebeSEric Cheng dev_info_t *mi_dip; /* WO */ 420da14cebeSEric Cheng uint32_t mi_ref; /* i_mac_impl_lock */ 421da14cebeSEric Cheng uint_t mi_active; /* SL */ 422da14cebeSEric Cheng link_state_t mi_linkstate; /* none */ 4234eaa4710SRishi Srivatsavai link_state_t mi_lowlinkstate; /* none */ 4244eaa4710SRishi Srivatsavai link_state_t mi_lastlowlinkstate; /* none */ 425da14cebeSEric Cheng uint_t mi_devpromisc; /* SL */ 426da14cebeSEric Cheng uint8_t mi_addr[MAXMACADDRLEN]; /* mi_rw_lock */ 427da14cebeSEric Cheng uint8_t mi_dstaddr[MAXMACADDRLEN]; /* mi_rw_lock */ 4282b24ab6bSSebastien Roy boolean_t mi_dstaddr_set; 429d62bc4baSyz147064 430da14cebeSEric Cheng /* 431da14cebeSEric Cheng * The mac perimeter. All client initiated create/modify operations 432da14cebeSEric Cheng * on a mac end point go through this. 433da14cebeSEric Cheng */ 434da14cebeSEric Cheng kmutex_t mi_perim_lock; 435da14cebeSEric Cheng kthread_t *mi_perim_owner; /* mi_perim_lock */ 436da14cebeSEric Cheng uint_t mi_perim_ocnt; /* mi_perim_lock */ 437da14cebeSEric Cheng kcondvar_t mi_perim_cv; /* mi_perim_lock */ 438d62bc4baSyz147064 439da14cebeSEric Cheng /* mac notification callbacks */ 440da14cebeSEric Cheng kmutex_t mi_notify_lock; 441da14cebeSEric Cheng mac_cb_info_t mi_notify_cb_info; /* mi_notify_lock */ 442da14cebeSEric Cheng mac_cb_t *mi_notify_cb_list; /* mi_notify_lock */ 443da14cebeSEric Cheng kthread_t *mi_notify_thread; /* mi_notify_lock */ 444da14cebeSEric Cheng uint_t mi_notify_bits; /* mi_notify_lock */ 445da14cebeSEric Cheng 446da14cebeSEric Cheng uint32_t mi_v12n_level; /* Virt'ion readiness */ 447da14cebeSEric Cheng 448da14cebeSEric Cheng /* 449da14cebeSEric Cheng * RX groups, ring capability 450da14cebeSEric Cheng * Fields of this block are SL protected. 451da14cebeSEric Cheng */ 452da14cebeSEric Cheng mac_group_type_t mi_rx_group_type; /* grouping type */ 453da14cebeSEric Cheng uint_t mi_rx_group_count; 454da14cebeSEric Cheng mac_group_t *mi_rx_groups; 4550dc2366fSVenugopal Iyer mac_group_t *mi_rx_donor_grp; 4560dc2366fSVenugopal Iyer uint_t mi_rxrings_rsvd; 4570dc2366fSVenugopal Iyer uint_t mi_rxrings_avail; 4580dc2366fSVenugopal Iyer uint_t mi_rxhwclnt_avail; 4590dc2366fSVenugopal Iyer uint_t mi_rxhwclnt_used; 460da14cebeSEric Cheng 461da14cebeSEric Cheng mac_capab_rings_t mi_rx_rings_cap; 462da14cebeSEric Cheng 463da14cebeSEric Cheng /* 464da14cebeSEric Cheng * TX groups and ring capability, SL Protected. 465da14cebeSEric Cheng */ 466da14cebeSEric Cheng mac_group_type_t mi_tx_group_type; /* grouping type */ 467da14cebeSEric Cheng uint_t mi_tx_group_count; 468da14cebeSEric Cheng uint_t mi_tx_group_free; 469da14cebeSEric Cheng mac_group_t *mi_tx_groups; 470da14cebeSEric Cheng mac_capab_rings_t mi_tx_rings_cap; 4710dc2366fSVenugopal Iyer uint_t mi_txrings_rsvd; 4720dc2366fSVenugopal Iyer uint_t mi_txrings_avail; 4730dc2366fSVenugopal Iyer uint_t mi_txhwclnt_avail; 4740dc2366fSVenugopal Iyer uint_t mi_txhwclnt_used; 475da14cebeSEric Cheng 476da14cebeSEric Cheng mac_ring_handle_t mi_default_tx_ring; 477da14cebeSEric Cheng 478da14cebeSEric Cheng /* 47948a4016cSRobert Mustacchi * Transceiver capabilities. SL protected. 48048a4016cSRobert Mustacchi */ 48148a4016cSRobert Mustacchi mac_capab_transceiver_t mi_transceiver; 48248a4016cSRobert Mustacchi 48348a4016cSRobert Mustacchi /* 484*4d210590SRobert Mustacchi * LED Capability information. SL protected. 485*4d210590SRobert Mustacchi */ 486*4d210590SRobert Mustacchi mac_led_mode_t mi_led_modes; 487*4d210590SRobert Mustacchi mac_capab_led_t mi_led; 488*4d210590SRobert Mustacchi 489*4d210590SRobert Mustacchi /* 490da14cebeSEric Cheng * MAC address list. SL protected. 491da14cebeSEric Cheng */ 492da14cebeSEric Cheng mac_address_t *mi_addresses; 493da14cebeSEric Cheng 494da14cebeSEric Cheng /* 495da14cebeSEric Cheng * This MAC's table of sub-flows 496da14cebeSEric Cheng */ 497da14cebeSEric Cheng flow_tab_t *mi_flow_tab; /* WO */ 498da14cebeSEric Cheng 499da14cebeSEric Cheng kstat_t *mi_ksp; /* WO */ 500da14cebeSEric Cheng uint_t mi_kstat_count; /* WO */ 501da14cebeSEric Cheng uint_t mi_nactiveclients; /* SL */ 502da14cebeSEric Cheng 503da14cebeSEric Cheng /* for broadcast and multicast support */ 504da14cebeSEric Cheng struct mac_mcast_addrs_s *mi_mcast_addrs; /* mi_rw_lock */ 505da14cebeSEric Cheng struct mac_bcast_grp_s *mi_bcast_grp; /* mi_rw_lock */ 506da14cebeSEric Cheng uint_t mi_bcast_ngrps; /* mi_rw_lock */ 507da14cebeSEric Cheng 508da14cebeSEric Cheng /* list of MAC clients which opened this MAC */ 509da14cebeSEric Cheng struct mac_client_impl_s *mi_clients_list; /* mi_rw_lock */ 510da14cebeSEric Cheng uint_t mi_nclients; /* mi_rw_lock */ 511ae6aa22aSVenugopal Iyer struct mac_client_impl_s *mi_single_active_client; /* mi_rw_lock */ 512da14cebeSEric Cheng 513da14cebeSEric Cheng uint32_t mi_margin; /* mi_rw_lock */ 514da14cebeSEric Cheng uint_t mi_sdu_min; /* mi_rw_lock */ 515da14cebeSEric Cheng uint_t mi_sdu_max; /* mi_rw_lock */ 5161eee170aSErik Nordmark uint_t mi_sdu_multicast; /* mi_rw_lock */ 517da14cebeSEric Cheng 518da14cebeSEric Cheng /* 519da14cebeSEric Cheng * Cache of factory MAC addresses provided by the driver. If 520da14cebeSEric Cheng * the driver doesn't provide multiple factory MAC addresses, 521da14cebeSEric Cheng * the mi_factory_addr is set to NULL, and mi_factory_addr_num 522da14cebeSEric Cheng * is set to zero. 523da14cebeSEric Cheng */ 524da14cebeSEric Cheng mac_factory_addr_t *mi_factory_addr; /* mi_rw_lock */ 525da14cebeSEric Cheng uint_t mi_factory_addr_num; /* mi_rw_lock */ 526da14cebeSEric Cheng 527da14cebeSEric Cheng /* for promiscuous mode support */ 528da14cebeSEric Cheng kmutex_t mi_promisc_lock; 529da14cebeSEric Cheng mac_cb_t *mi_promisc_list; /* mi_promisc_lock */ 530da14cebeSEric Cheng mac_cb_info_t mi_promisc_cb_info; /* mi_promisc_lock */ 531da14cebeSEric Cheng 532da14cebeSEric Cheng /* cache of rings over this mac_impl */ 533da14cebeSEric Cheng kmutex_t mi_ring_lock; 534da14cebeSEric Cheng mac_ring_t *mi_ring_freelist; /* mi_ring_lock */ 535da14cebeSEric Cheng 536da14cebeSEric Cheng /* 537da14cebeSEric Cheng * These are used for caching the properties, if any, for the 538da14cebeSEric Cheng * primary MAC client. If the MAC client is not yet in place 539da14cebeSEric Cheng * when the properties are set then we cache them here to be 540da14cebeSEric Cheng * applied to the MAC client when it is created. 541da14cebeSEric Cheng */ 542da14cebeSEric Cheng mac_resource_props_t mi_resource_props; /* SL */ 5434eaa4710SRishi Srivatsavai uint16_t mi_pvid; /* SL */ 544da14cebeSEric Cheng 545da14cebeSEric Cheng minor_t mi_minor; /* WO */ 546da14cebeSEric Cheng uint32_t mi_oref; /* SL */ 5475d460eafSCathy Zhou mac_capab_legacy_t mi_capab_legacy; /* WO */ 5485d460eafSCathy Zhou dev_t mi_phy_dev; /* WO */ 5495d460eafSCathy Zhou 550d62bc4baSyz147064 /* 551d62bc4baSyz147064 * List of margin value requests added by mac clients. This list is 552d62bc4baSyz147064 * sorted: the first one has the greatest value. 553d62bc4baSyz147064 */ 554d62bc4baSyz147064 mac_margin_req_t *mi_mmrp; 555a776d98eSRobert Mustacchi mac_mtu_req_t *mi_mtrp; 5560dc2366fSVenugopal Iyer char **mi_priv_prop; 5574045d941Ssowmini uint_t mi_priv_prop_count; 558da14cebeSEric Cheng 559da14cebeSEric Cheng /* 560da14cebeSEric Cheng * Hybrid I/O related definitions. 561da14cebeSEric Cheng */ 562da14cebeSEric Cheng mac_capab_share_t mi_share_capab; 563da14cebeSEric Cheng 5644eaa4710SRishi Srivatsavai /* 5654eaa4710SRishi Srivatsavai * Bridging hooks and limit values. Uses mutex and reference counts 5664eaa4710SRishi Srivatsavai * (bridging only) for data path. Limits need no synchronization. 5674eaa4710SRishi Srivatsavai */ 5684eaa4710SRishi Srivatsavai mac_handle_t mi_bridge_link; 5694eaa4710SRishi Srivatsavai kmutex_t mi_bridge_lock; 5704eaa4710SRishi Srivatsavai uint32_t mi_llimit; 5714eaa4710SRishi Srivatsavai uint32_t mi_ldecay; 5724eaa4710SRishi Srivatsavai 573da14cebeSEric Cheng /* This should be the last block in this structure */ 574da14cebeSEric Cheng #ifdef DEBUG 575da14cebeSEric Cheng #define MAC_PERIM_STACK_DEPTH 15 576da14cebeSEric Cheng int mi_perim_stack_depth; 577da14cebeSEric Cheng pc_t mi_perim_stack[MAC_PERIM_STACK_DEPTH]; 578da14cebeSEric Cheng #endif 579da14cebeSEric Cheng }; 580da14cebeSEric Cheng 5810dc2366fSVenugopal Iyer /* 5820dc2366fSVenugopal Iyer * The default TX group is the last one in the list. 5830dc2366fSVenugopal Iyer */ 5840dc2366fSVenugopal Iyer #define MAC_DEFAULT_TX_GROUP(mip) \ 5850dc2366fSVenugopal Iyer (mip)->mi_tx_groups + (mip)->mi_tx_group_count 5860dc2366fSVenugopal Iyer 5870dc2366fSVenugopal Iyer /* 5880dc2366fSVenugopal Iyer * The default RX group is the first one in the list 5890dc2366fSVenugopal Iyer */ 5900dc2366fSVenugopal Iyer #define MAC_DEFAULT_RX_GROUP(mip) (mip)->mi_rx_groups 5910dc2366fSVenugopal Iyer 5920dc2366fSVenugopal Iyer /* Reserved RX rings */ 5930dc2366fSVenugopal Iyer #define MAC_RX_RING_RESERVED(m, cnt) { \ 5940dc2366fSVenugopal Iyer ASSERT((m)->mi_rxrings_avail >= (cnt)); \ 5950dc2366fSVenugopal Iyer (m)->mi_rxrings_rsvd += (cnt); \ 5960dc2366fSVenugopal Iyer (m)->mi_rxrings_avail -= (cnt); \ 5970dc2366fSVenugopal Iyer } 5980dc2366fSVenugopal Iyer 5990dc2366fSVenugopal Iyer /* Released RX rings */ 6000dc2366fSVenugopal Iyer #define MAC_RX_RING_RELEASED(m, cnt) { \ 6010dc2366fSVenugopal Iyer ASSERT((m)->mi_rxrings_rsvd >= (cnt)); \ 6020dc2366fSVenugopal Iyer (m)->mi_rxrings_rsvd -= (cnt); \ 6030dc2366fSVenugopal Iyer (m)->mi_rxrings_avail += (cnt); \ 6040dc2366fSVenugopal Iyer } 6050dc2366fSVenugopal Iyer 6060dc2366fSVenugopal Iyer /* Reserved a RX group */ 6070dc2366fSVenugopal Iyer #define MAC_RX_GRP_RESERVED(m) { \ 6080dc2366fSVenugopal Iyer ASSERT((m)->mi_rxhwclnt_avail > 0); \ 6090dc2366fSVenugopal Iyer (m)->mi_rxhwclnt_avail--; \ 6100dc2366fSVenugopal Iyer (m)->mi_rxhwclnt_used++; \ 6110dc2366fSVenugopal Iyer } 6120dc2366fSVenugopal Iyer 6130dc2366fSVenugopal Iyer /* Released a RX group */ 6140dc2366fSVenugopal Iyer #define MAC_RX_GRP_RELEASED(m) { \ 6150dc2366fSVenugopal Iyer ASSERT((m)->mi_rxhwclnt_used > 0); \ 6160dc2366fSVenugopal Iyer (m)->mi_rxhwclnt_avail++; \ 6170dc2366fSVenugopal Iyer (m)->mi_rxhwclnt_used--; \ 6180dc2366fSVenugopal Iyer } 6190dc2366fSVenugopal Iyer 6200dc2366fSVenugopal Iyer /* Reserved TX rings */ 6210dc2366fSVenugopal Iyer #define MAC_TX_RING_RESERVED(m, cnt) { \ 6220dc2366fSVenugopal Iyer ASSERT((m)->mi_txrings_avail >= (cnt)); \ 6230dc2366fSVenugopal Iyer (m)->mi_txrings_rsvd += (cnt); \ 6240dc2366fSVenugopal Iyer (m)->mi_txrings_avail -= (cnt); \ 6250dc2366fSVenugopal Iyer } 6260dc2366fSVenugopal Iyer /* Released TX rings */ 6270dc2366fSVenugopal Iyer #define MAC_TX_RING_RELEASED(m, cnt) { \ 6280dc2366fSVenugopal Iyer ASSERT((m)->mi_txrings_rsvd >= (cnt)); \ 6290dc2366fSVenugopal Iyer (m)->mi_txrings_rsvd -= (cnt); \ 6300dc2366fSVenugopal Iyer (m)->mi_txrings_avail += (cnt); \ 6310dc2366fSVenugopal Iyer } 6320dc2366fSVenugopal Iyer 6330dc2366fSVenugopal Iyer /* Reserved a TX group */ 6340dc2366fSVenugopal Iyer #define MAC_TX_GRP_RESERVED(m) { \ 6350dc2366fSVenugopal Iyer ASSERT((m)->mi_txhwclnt_avail > 0); \ 6360dc2366fSVenugopal Iyer (m)->mi_txhwclnt_avail--; \ 6370dc2366fSVenugopal Iyer (m)->mi_txhwclnt_used++; \ 6380dc2366fSVenugopal Iyer } 6390dc2366fSVenugopal Iyer 6400dc2366fSVenugopal Iyer /* Released a TX group */ 6410dc2366fSVenugopal Iyer #define MAC_TX_GRP_RELEASED(m) { \ 6420dc2366fSVenugopal Iyer ASSERT((m)->mi_txhwclnt_used > 0); \ 6430dc2366fSVenugopal Iyer (m)->mi_txhwclnt_avail++; \ 6440dc2366fSVenugopal Iyer (m)->mi_txhwclnt_used--; \ 6450dc2366fSVenugopal Iyer } 6460dc2366fSVenugopal Iyer 647da14cebeSEric Cheng /* for mi_state_flags */ 648da14cebeSEric Cheng #define MIS_DISABLED 0x0001 649da14cebeSEric Cheng #define MIS_IS_VNIC 0x0002 650da14cebeSEric Cheng #define MIS_IS_AGGR 0x0004 651da14cebeSEric Cheng #define MIS_NOTIFY_DONE 0x0008 652da14cebeSEric Cheng #define MIS_EXCLUSIVE 0x0010 653da14cebeSEric Cheng #define MIS_EXCLUSIVE_HELD 0x0020 654da14cebeSEric Cheng #define MIS_LEGACY 0x0040 6554eaa4710SRishi Srivatsavai #define MIS_NO_ACTIVE 0x0080 6564eaa4710SRishi Srivatsavai #define MIS_POLL_DISABLE 0x0100 657ba2e4443Sseb 658ba2e4443Sseb #define mi_getstat mi_callbacks->mc_getstat 659ba2e4443Sseb #define mi_start mi_callbacks->mc_start 660ba2e4443Sseb #define mi_stop mi_callbacks->mc_stop 661d62bc4baSyz147064 #define mi_open mi_callbacks->mc_open 662d62bc4baSyz147064 #define mi_close mi_callbacks->mc_close 663ba2e4443Sseb #define mi_setpromisc mi_callbacks->mc_setpromisc 664ba2e4443Sseb #define mi_multicst mi_callbacks->mc_multicst 665ba2e4443Sseb #define mi_unicst mi_callbacks->mc_unicst 666ba2e4443Sseb #define mi_tx mi_callbacks->mc_tx 667ba2e4443Sseb #define mi_ioctl mi_callbacks->mc_ioctl 668ba2e4443Sseb #define mi_getcapab mi_callbacks->mc_getcapab 6697c478bd9Sstevel@tonic-gate 670da14cebeSEric Cheng typedef struct mac_notify_task_arg { 671da14cebeSEric Cheng mac_impl_t *mnt_mip; 672da14cebeSEric Cheng mac_notify_type_t mnt_type; 673da14cebeSEric Cheng mac_ring_t *mnt_ring; 674da14cebeSEric Cheng } mac_notify_task_arg_t; 675da14cebeSEric Cheng 676da14cebeSEric Cheng /* 677da14cebeSEric Cheng * The mac_perim_handle_t is an opaque type that encodes the 'mip' pointer 678da14cebeSEric Cheng * and whether internally a mac_open was done when acquiring the perimeter. 679da14cebeSEric Cheng */ 680da14cebeSEric Cheng #define MAC_ENCODE_MPH(mph, mh, need_close) \ 681da14cebeSEric Cheng (mph) = (mac_perim_handle_t)((uintptr_t)(mh) | need_close) 682da14cebeSEric Cheng 683da14cebeSEric Cheng #define MAC_DECODE_MPH(mph, mip, need_close) { \ 684da14cebeSEric Cheng mip = (mac_impl_t *)(((uintptr_t)mph) & ~0x1); \ 685da14cebeSEric Cheng (need_close) = ((uintptr_t)mph & 0x1); \ 686da14cebeSEric Cheng } 687da14cebeSEric Cheng 6880dc2366fSVenugopal Iyer /* 6890dc2366fSVenugopal Iyer * Type of property information that can be returned by a driver. 6900dc2366fSVenugopal Iyer * Valid flags of the pr_flags of the mac_prop_info_t data structure. 6910dc2366fSVenugopal Iyer */ 6920dc2366fSVenugopal Iyer #define MAC_PROP_INFO_DEFAULT 0x0001 6930dc2366fSVenugopal Iyer #define MAC_PROP_INFO_RANGE 0x0002 6940dc2366fSVenugopal Iyer #define MAC_PROP_INFO_PERM 0x0004 6950dc2366fSVenugopal Iyer 6960dc2366fSVenugopal Iyer /* 6970dc2366fSVenugopal Iyer * Property information. pr_flags is a combination of one of the 6980dc2366fSVenugopal Iyer * MAC_PROP_INFO_* flags, it is reset by the framework before invoking 6990dc2366fSVenugopal Iyer * the driver's prefix_propinfo() entry point. 7000dc2366fSVenugopal Iyer * 7010dc2366fSVenugopal Iyer * Drivers should use MAC_PROP_INFO_SET_*() macros to provide 7020dc2366fSVenugopal Iyer * information about a property. 7030dc2366fSVenugopal Iyer */ 7040dc2366fSVenugopal Iyer typedef struct mac_prop_info_state_s { 7050dc2366fSVenugopal Iyer uint8_t pr_flags; 7060dc2366fSVenugopal Iyer uint8_t pr_perm; 7070591ddd0SPrakash Jalan uint8_t pr_errno; 7080dc2366fSVenugopal Iyer void *pr_default; 7090dc2366fSVenugopal Iyer size_t pr_default_size; 7100dc2366fSVenugopal Iyer mac_propval_range_t *pr_range; 7110591ddd0SPrakash Jalan uint_t pr_range_cur_count; 7120dc2366fSVenugopal Iyer } mac_prop_info_state_t; 7130dc2366fSVenugopal Iyer 7140dc2366fSVenugopal Iyer #define MAC_PROTECT_ENABLED(mcip, type) \ 7150dc2366fSVenugopal Iyer (((mcip)->mci_flent-> \ 7160dc2366fSVenugopal Iyer fe_resource_props.mrp_mask & MRP_PROTECT) != 0 && \ 7170dc2366fSVenugopal Iyer ((mcip)->mci_flent-> \ 7180dc2366fSVenugopal Iyer fe_resource_props.mrp_protect.mp_types & (type)) != 0) 7190dc2366fSVenugopal Iyer 720da14cebeSEric Cheng typedef struct mac_client_impl_s mac_client_impl_t; 721da14cebeSEric Cheng 7227c478bd9Sstevel@tonic-gate extern void mac_init(void); 7237c478bd9Sstevel@tonic-gate extern int mac_fini(void); 7247c478bd9Sstevel@tonic-gate 7254045d941Ssowmini extern void mac_ndd_ioctl(mac_impl_t *, queue_t *, mblk_t *); 7260dc2366fSVenugopal Iyer extern boolean_t mac_ip_hdr_length_v6(ip6_t *, uint8_t *, uint16_t *, 7270dc2366fSVenugopal Iyer uint8_t *, ip6_frag_t **); 728da14cebeSEric Cheng 729da14cebeSEric Cheng extern mblk_t *mac_copymsgchain_cksum(mblk_t *); 730da14cebeSEric Cheng extern mblk_t *mac_fix_cksum(mblk_t *); 731da14cebeSEric Cheng extern void mac_packet_print(mac_handle_t, mblk_t *); 732da14cebeSEric Cheng extern void mac_rx_deliver(void *, mac_resource_handle_t, mblk_t *, 733da14cebeSEric Cheng mac_header_info_t *); 734da14cebeSEric Cheng extern void mac_tx_notify(mac_impl_t *); 735da14cebeSEric Cheng 736da14cebeSEric Cheng extern boolean_t mac_callback_find(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 737da14cebeSEric Cheng extern void mac_callback_add(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 738da14cebeSEric Cheng extern boolean_t mac_callback_remove(mac_cb_info_t *, mac_cb_t **, mac_cb_t *); 739da14cebeSEric Cheng extern void mac_callback_remove_wait(mac_cb_info_t *); 740da14cebeSEric Cheng extern void mac_callback_free(mac_cb_t *); 741da14cebeSEric Cheng extern mac_cb_t *mac_callback_walker_cleanup(mac_cb_info_t *, mac_cb_t **); 742da14cebeSEric Cheng 743da14cebeSEric Cheng /* in mac_bcast.c */ 744da14cebeSEric Cheng extern void mac_bcast_init(void); 745da14cebeSEric Cheng extern void mac_bcast_fini(void); 746da14cebeSEric Cheng extern mac_impl_t *mac_bcast_grp_mip(void *); 747da14cebeSEric Cheng extern int mac_bcast_add(mac_client_impl_t *, const uint8_t *, uint16_t, 748da14cebeSEric Cheng mac_addrtype_t); 749da14cebeSEric Cheng extern void mac_bcast_delete(mac_client_impl_t *, const uint8_t *, uint16_t); 750da14cebeSEric Cheng extern void mac_bcast_send(void *, void *, mblk_t *, boolean_t); 751da14cebeSEric Cheng extern void mac_bcast_grp_free(void *); 752da14cebeSEric Cheng extern void mac_bcast_refresh(mac_impl_t *, mac_multicst_t, void *, 753da14cebeSEric Cheng boolean_t); 754da14cebeSEric Cheng extern void mac_client_bcast_refresh(mac_client_impl_t *, mac_multicst_t, 755da14cebeSEric Cheng void *, boolean_t); 756da14cebeSEric Cheng 757da14cebeSEric Cheng /* 758da14cebeSEric Cheng * Grouping functions are used internally by MAC layer. 759da14cebeSEric Cheng */ 760da14cebeSEric Cheng extern int mac_group_addmac(mac_group_t *, const uint8_t *); 761da14cebeSEric Cheng extern int mac_group_remmac(mac_group_t *, const uint8_t *); 762da14cebeSEric Cheng extern int mac_rx_group_add_flow(mac_client_impl_t *, flow_entry_t *, 763da14cebeSEric Cheng mac_group_t *); 76463f531d1SSriharsha Basavapatna extern mblk_t *mac_hwring_tx(mac_ring_handle_t, mblk_t *); 7654eaa4710SRishi Srivatsavai extern mblk_t *mac_bridge_tx(mac_impl_t *, mac_ring_handle_t, mblk_t *); 7660dc2366fSVenugopal Iyer extern mac_group_t *mac_reserve_rx_group(mac_client_impl_t *, uint8_t *, 7670dc2366fSVenugopal Iyer boolean_t); 7680dc2366fSVenugopal Iyer extern void mac_release_rx_group(mac_client_impl_t *, mac_group_t *); 7690dc2366fSVenugopal Iyer extern int mac_rx_switch_group(mac_client_impl_t *, mac_group_t *, 7700dc2366fSVenugopal Iyer mac_group_t *); 771da14cebeSEric Cheng extern mac_ring_t *mac_reserve_tx_ring(mac_impl_t *, mac_ring_t *); 7720dc2366fSVenugopal Iyer extern mac_group_t *mac_reserve_tx_group(mac_client_impl_t *, boolean_t); 7730dc2366fSVenugopal Iyer extern void mac_release_tx_group(mac_client_impl_t *, mac_group_t *); 7740dc2366fSVenugopal Iyer extern void mac_tx_switch_group(mac_client_impl_t *, mac_group_t *, 7750dc2366fSVenugopal Iyer mac_group_t *); 7760dc2366fSVenugopal Iyer extern void mac_rx_switch_grp_to_sw(mac_group_t *); 777da14cebeSEric Cheng 778da14cebeSEric Cheng /* 779da14cebeSEric Cheng * MAC address functions are used internally by MAC layer. 780da14cebeSEric Cheng */ 781da14cebeSEric Cheng extern mac_address_t *mac_find_macaddr(mac_impl_t *, uint8_t *); 782da14cebeSEric Cheng extern boolean_t mac_check_macaddr_shared(mac_address_t *); 783da14cebeSEric Cheng extern int mac_update_macaddr(mac_address_t *, uint8_t *); 784da14cebeSEric Cheng extern void mac_freshen_macaddr(mac_address_t *, uint8_t *); 785da14cebeSEric Cheng extern void mac_retrieve_macaddr(mac_address_t *, uint8_t *); 786da14cebeSEric Cheng extern void mac_init_macaddr(mac_impl_t *); 787da14cebeSEric Cheng extern void mac_fini_macaddr(mac_impl_t *); 788da14cebeSEric Cheng 789da14cebeSEric Cheng /* 790da14cebeSEric Cheng * Flow construction/destruction routines. 791da14cebeSEric Cheng * Not meant to be used by mac clients. 792da14cebeSEric Cheng */ 793da14cebeSEric Cheng extern int mac_link_flow_init(mac_client_handle_t, flow_entry_t *); 794da14cebeSEric Cheng extern void mac_link_flow_clean(mac_client_handle_t, flow_entry_t *); 795da14cebeSEric Cheng 796da14cebeSEric Cheng /* 79708ac1c49SNicolas Droux * Fanout update routines called when the link speed of the NIC changes 79808ac1c49SNicolas Droux * or when a MAC client's share is unbound. 799da14cebeSEric Cheng */ 8000dc2366fSVenugopal Iyer extern void mac_fanout_recompute_client(mac_client_impl_t *, cpupart_t *); 801da14cebeSEric Cheng extern void mac_fanout_recompute(mac_impl_t *); 802da14cebeSEric Cheng 803da14cebeSEric Cheng /* 804da14cebeSEric Cheng * The following functions are used internally by the MAC layer to 805da14cebeSEric Cheng * add/remove/update flows associated with a mac_impl_t. They should 806da14cebeSEric Cheng * never be used directly by MAC clients. 807da14cebeSEric Cheng */ 808da14cebeSEric Cheng extern int mac_datapath_setup(mac_client_impl_t *, flow_entry_t *, uint32_t); 809da14cebeSEric Cheng extern void mac_datapath_teardown(mac_client_impl_t *, flow_entry_t *, 810da14cebeSEric Cheng uint32_t); 8110dc2366fSVenugopal Iyer extern void mac_rx_srs_group_setup(mac_client_impl_t *, flow_entry_t *, 8120dc2366fSVenugopal Iyer uint32_t); 8130dc2366fSVenugopal Iyer extern void mac_tx_srs_group_setup(mac_client_impl_t *, flow_entry_t *, 8140dc2366fSVenugopal Iyer uint32_t); 8150dc2366fSVenugopal Iyer extern void mac_rx_srs_group_teardown(flow_entry_t *, boolean_t); 8160dc2366fSVenugopal Iyer extern void mac_tx_srs_group_teardown(mac_client_impl_t *, flow_entry_t *, 817da14cebeSEric Cheng uint32_t); 818da14cebeSEric Cheng extern int mac_rx_classify_flow_quiesce(flow_entry_t *, void *); 819da14cebeSEric Cheng extern int mac_rx_classify_flow_restart(flow_entry_t *, void *); 820da14cebeSEric Cheng extern void mac_client_quiesce(mac_client_impl_t *); 821da14cebeSEric Cheng extern void mac_client_restart(mac_client_impl_t *); 822da14cebeSEric Cheng 823da14cebeSEric Cheng extern void mac_flow_update_priority(mac_client_impl_t *, flow_entry_t *); 824da14cebeSEric Cheng 825da14cebeSEric Cheng extern void mac_flow_rem_subflow(flow_entry_t *); 826da14cebeSEric Cheng extern void mac_rename_flow(flow_entry_t *, const char *); 827da14cebeSEric Cheng extern void mac_flow_set_name(flow_entry_t *, const char *); 828da14cebeSEric Cheng 829da14cebeSEric Cheng extern mblk_t *mac_add_vlan_tag(mblk_t *, uint_t, uint16_t); 830da14cebeSEric Cheng extern mblk_t *mac_add_vlan_tag_chain(mblk_t *, uint_t, uint16_t); 831da14cebeSEric Cheng extern mblk_t *mac_strip_vlan_tag_chain(mblk_t *); 832da14cebeSEric Cheng extern void mac_pkt_drop(void *, mac_resource_handle_t, mblk_t *, boolean_t); 833da14cebeSEric Cheng extern mblk_t *mac_rx_flow(mac_handle_t, mac_resource_handle_t, mblk_t *); 834da14cebeSEric Cheng 835da14cebeSEric Cheng extern void i_mac_share_alloc(mac_client_impl_t *); 836da14cebeSEric Cheng extern void i_mac_share_free(mac_client_impl_t *); 837da14cebeSEric Cheng extern void i_mac_perim_enter(mac_impl_t *); 838da14cebeSEric Cheng extern void i_mac_perim_exit(mac_impl_t *); 839da14cebeSEric Cheng extern int i_mac_perim_enter_nowait(mac_impl_t *); 840da14cebeSEric Cheng extern void i_mac_tx_srs_notify(mac_impl_t *, mac_ring_handle_t); 841da14cebeSEric Cheng extern int mac_hold(const char *, mac_impl_t **); 842da14cebeSEric Cheng extern void mac_rele(mac_impl_t *); 843da14cebeSEric Cheng extern int i_mac_disable(mac_impl_t *); 844da14cebeSEric Cheng extern void i_mac_notify(mac_impl_t *, mac_notify_type_t); 845da14cebeSEric Cheng extern void i_mac_notify_exit(mac_impl_t *); 846da14cebeSEric Cheng extern void mac_rx_group_unmark(mac_group_t *, uint_t); 847da14cebeSEric Cheng extern void mac_tx_client_flush(mac_client_impl_t *); 848da14cebeSEric Cheng extern void mac_tx_client_block(mac_client_impl_t *); 849da14cebeSEric Cheng extern void mac_tx_client_unblock(mac_client_impl_t *); 8500dc2366fSVenugopal Iyer extern void mac_tx_invoke_callbacks(mac_client_impl_t *, mac_tx_cookie_t); 851d91a22bfSGirish Moodalbail extern int i_mac_promisc_set(mac_impl_t *, boolean_t); 852da14cebeSEric Cheng extern void i_mac_promisc_walker_cleanup(mac_impl_t *); 853da14cebeSEric Cheng extern mactype_t *mactype_getplugin(const char *); 854da14cebeSEric Cheng extern void mac_addr_factory_init(mac_impl_t *); 855da14cebeSEric Cheng extern void mac_addr_factory_fini(mac_impl_t *); 8560dc2366fSVenugopal Iyer extern void mac_register_priv_prop(mac_impl_t *, char **); 857da14cebeSEric Cheng extern void mac_unregister_priv_prop(mac_impl_t *); 858da14cebeSEric Cheng extern int mac_init_rings(mac_impl_t *, mac_ring_type_t); 859da14cebeSEric Cheng extern void mac_free_rings(mac_impl_t *, mac_ring_type_t); 8600dc2366fSVenugopal Iyer extern void mac_compare_ddi_handle(mac_group_t *, uint_t, mac_ring_t *); 861da14cebeSEric Cheng 862da14cebeSEric Cheng extern int mac_start_group(mac_group_t *); 863da14cebeSEric Cheng extern void mac_stop_group(mac_group_t *); 864da14cebeSEric Cheng extern int mac_start_ring(mac_ring_t *); 865da14cebeSEric Cheng extern void mac_stop_ring(mac_ring_t *); 86608ac1c49SNicolas Droux extern int mac_add_macaddr(mac_impl_t *, mac_group_t *, uint8_t *, boolean_t); 867da14cebeSEric Cheng extern int mac_remove_macaddr(mac_address_t *); 868da14cebeSEric Cheng 8690dc2366fSVenugopal Iyer extern void mac_set_group_state(mac_group_t *, mac_group_state_t); 8700dc2366fSVenugopal Iyer extern void mac_group_add_client(mac_group_t *, mac_client_impl_t *); 8710dc2366fSVenugopal Iyer extern void mac_group_remove_client(mac_group_t *, mac_client_impl_t *); 8720dc2366fSVenugopal Iyer 873da14cebeSEric Cheng extern int i_mac_group_add_ring(mac_group_t *, mac_ring_t *, int); 874da14cebeSEric Cheng extern void i_mac_group_rem_ring(mac_group_t *, mac_ring_t *, boolean_t); 8750dc2366fSVenugopal Iyer extern int mac_group_ring_modify(mac_client_impl_t *, mac_group_t *, 8760dc2366fSVenugopal Iyer mac_group_t *); 8774eaa4710SRishi Srivatsavai extern void mac_poll_state_change(mac_handle_t, boolean_t); 8784eaa4710SRishi Srivatsavai 8790dc2366fSVenugopal Iyer extern mac_group_state_t mac_group_next_state(mac_group_t *, 8800dc2366fSVenugopal Iyer mac_client_impl_t **, mac_group_t *, boolean_t); 8810dc2366fSVenugopal Iyer 88225ec3e3dSEric Cheng extern mblk_t *mac_protect_check(mac_client_handle_t, mblk_t *); 88325ec3e3dSEric Cheng extern int mac_protect_set(mac_client_handle_t, mac_resource_props_t *); 88425ec3e3dSEric Cheng extern boolean_t mac_protect_enabled(mac_client_handle_t, uint32_t); 88525ec3e3dSEric Cheng extern int mac_protect_validate(mac_resource_props_t *); 88625ec3e3dSEric Cheng extern void mac_protect_update(mac_resource_props_t *, mac_resource_props_t *); 8871aec9edfSCody Peter Mello extern void mac_protect_update_mac_token(mac_client_impl_t *); 8881aec9edfSCody Peter Mello extern void mac_protect_intercept_dynamic(mac_client_impl_t *, mblk_t *); 8891aec9edfSCody Peter Mello extern void mac_protect_flush_dynamic(mac_client_impl_t *); 8900dc2366fSVenugopal Iyer extern void mac_protect_cancel_timer(mac_client_impl_t *); 8910dc2366fSVenugopal Iyer extern void mac_protect_init(mac_client_impl_t *); 8920dc2366fSVenugopal Iyer extern void mac_protect_fini(mac_client_impl_t *); 8930dc2366fSVenugopal Iyer 8940dc2366fSVenugopal Iyer extern int mac_set_resources(mac_handle_t, mac_resource_props_t *); 8950dc2366fSVenugopal Iyer extern void mac_get_resources(mac_handle_t, mac_resource_props_t *); 8960dc2366fSVenugopal Iyer extern void mac_get_effective_resources(mac_handle_t, mac_resource_props_t *); 897a124e365SRobert Mustacchi extern void mac_set_promisc_filtered(mac_client_handle_t, boolean_t); 898a124e365SRobert Mustacchi extern boolean_t mac_get_promisc_filtered(mac_client_handle_t); 8990dc2366fSVenugopal Iyer 9000dc2366fSVenugopal Iyer extern cpupart_t *mac_pset_find(mac_resource_props_t *, boolean_t *); 9010dc2366fSVenugopal Iyer extern void mac_set_pool_effective(boolean_t, cpupart_t *, 9020dc2366fSVenugopal Iyer mac_resource_props_t *, mac_resource_props_t *); 9030dc2366fSVenugopal Iyer extern void mac_set_rings_effective(mac_client_impl_t *); 9040dc2366fSVenugopal Iyer extern mac_client_impl_t *mac_check_primary_relocation(mac_client_impl_t *, 9050dc2366fSVenugopal Iyer boolean_t); 90625ec3e3dSEric Cheng 9074eaa4710SRishi Srivatsavai /* Global callbacks into the bridging module (when loaded) */ 9084eaa4710SRishi Srivatsavai extern mac_bridge_tx_t mac_bridge_tx_cb; 9094eaa4710SRishi Srivatsavai extern mac_bridge_rx_t mac_bridge_rx_cb; 9104eaa4710SRishi Srivatsavai extern mac_bridge_ref_t mac_bridge_ref_cb; 9114eaa4710SRishi Srivatsavai extern mac_bridge_ls_t mac_bridge_ls_cb; 9124eaa4710SRishi Srivatsavai 91348a4016cSRobert Mustacchi /* 91448a4016cSRobert Mustacchi * MAC Transceiver related functions 91548a4016cSRobert Mustacchi */ 91648a4016cSRobert Mustacchi struct mac_transceiver_info { 91748a4016cSRobert Mustacchi boolean_t mti_present; 91848a4016cSRobert Mustacchi boolean_t mti_usable; 91948a4016cSRobert Mustacchi }; 92048a4016cSRobert Mustacchi 92148a4016cSRobert Mustacchi extern void mac_transceiver_init(mac_impl_t *); 92248a4016cSRobert Mustacchi extern int mac_transceiver_count(mac_handle_t, uint_t *); 92348a4016cSRobert Mustacchi extern int mac_transceiver_info(mac_handle_t, uint_t, boolean_t *, boolean_t *); 92448a4016cSRobert Mustacchi extern int mac_transceiver_read(mac_handle_t, uint_t, uint_t, void *, size_t, 92548a4016cSRobert Mustacchi off_t, size_t *); 9260dc2366fSVenugopal Iyer 927*4d210590SRobert Mustacchi /* 928*4d210590SRobert Mustacchi * MAC LED related functions 929*4d210590SRobert Mustacchi */ 930*4d210590SRobert Mustacchi #define MAC_LED_ALL (MAC_LED_DEFAULT | MAC_LED_OFF | MAC_LED_IDENT | \ 931*4d210590SRobert Mustacchi MAC_LED_ON) 932*4d210590SRobert Mustacchi extern void mac_led_init(mac_impl_t *); 933*4d210590SRobert Mustacchi extern int mac_led_get(mac_handle_t, mac_led_mode_t *, mac_led_mode_t *); 934*4d210590SRobert Mustacchi extern int mac_led_set(mac_handle_t, mac_led_mode_t); 935*4d210590SRobert Mustacchi 9367c478bd9Sstevel@tonic-gate #ifdef __cplusplus 9377c478bd9Sstevel@tonic-gate } 9387c478bd9Sstevel@tonic-gate #endif 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate #endif /* _SYS_MAC_IMPL_H */ 941