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