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