root/usr/src/uts/sun4v/sys/vsw.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*
 * This header file contains the data structures which the
 * virtual switch (vsw) uses to communicate with its clients and
 * the outside world.
 */

#ifndef _VSW_H
#define _VSW_H

#ifdef  __cplusplus
extern "C" {
#endif

#include <sys/vio_mailbox.h>
#include <sys/vnet_common.h>
#include <sys/ethernet.h>
#include <sys/mac_client.h>
#include <sys/vio_util.h>
#include <sys/vgen_stats.h>
#include <sys/vsw_ldc.h>
#include <sys/vsw_hio.h>
#include <sys/callb.h>

#define DRV_NAME        "vsw"

/*
 * Only support ETHER mtu at moment.
 */
#define VSW_MTU         ETHERMAX

/* ID of the source of a frame being switched */
#define VSW_PHYSDEV             1       /* physical device associated */
#define VSW_VNETPORT            2       /* port connected to vnet (over ldc) */
#define VSW_LOCALDEV            4       /* vsw configured as an eth interface */

/*
 * Number of hash chains in the multicast forwarding database.
 */
#define         VSW_NCHAINS     8

/* Number of descriptors -  must be power of 2 */
#define         VSW_NUM_DESCRIPTORS     512

/*
 * State of interface if switch plumbed as network device.
 */
#define         VSW_IF_REG      0x1     /* interface was registered */
#define         VSW_IF_UP       0x2     /* Interface UP */
#define         VSW_IF_PROMISC  0x4     /* Interface in promiscious mode */

#define         VSW_U_P(state)  \
                        (state == (VSW_IF_UP | VSW_IF_PROMISC))

/*
 * Switching modes.
 */
#define         VSW_LAYER2              0x1     /* Layer 2 - MAC switching */
#define         VSW_LAYER2_PROMISC      0x2     /* Layer 2 + promisc mode */
#define         VSW_LAYER3              0x4     /* Layer 3 - IP switching */

#define         NUM_SMODES      3       /* number of switching modes */

#define VSW_PRI_ETH_DEFINED(vswp)       ((vswp)->pri_num_types != 0)

typedef enum {
        VSW_SWTHR_STOP = 0x1
} sw_thr_flags_t;

typedef enum {
        PROG_init = 0x00,
        PROG_locks = 0x01,
        PROG_readmd = 0x02,
        PROG_fdb = 0x04,
        PROG_mfdb = 0x08,
        PROG_taskq = 0x10,
        PROG_rxp_taskq = 0x20,
        PROG_swmode = 0x40,
        PROG_macreg = 0x80,
        PROG_mdreg = 0x100
} vsw_attach_progress_t;

/*
 * vlan-id information.
 */
typedef struct vsw_vlanid {
        uint16_t                vl_vid;         /* vlan-id */
        mac_unicast_handle_t    vl_muh;         /* mac unicast handle */
        boolean_t               vl_set;         /* set? */
} vsw_vlanid_t;

/*
 * vsw instance state information.
 */
typedef struct  vsw {
        int                     instance;       /* instance # */
        dev_info_t              *dip;           /* associated dev_info */
        uint64_t                regprop;        /* "reg" property */
        vsw_attach_progress_t   attach_progress; /* attach progress flags */
        struct vsw              *next;          /* next in list */
        char                    physname[LIFNAMSIZ];    /* phys-dev */
        uint8_t                 smode;          /* switching mode */
        kmutex_t                sw_thr_lock;    /* setup switching thr lock */
        kcondvar_t              sw_thr_cv;      /* cv for setup switching thr */
        kthread_t               *sw_thread;     /* setup switching thread */
        sw_thr_flags_t          sw_thr_flags;   /* setup switching thr flags */
        uint32_t                switching_setup_done; /* setup switching done */
        int                     mac_open_retries; /* mac_open() retry count */
        vsw_port_list_t         plist;          /* associated ports */
        ddi_taskq_t             *taskq_p;       /* VIO ctrl msg taskq */
        mod_hash_t              *fdb_hashp;     /* forwarding database */
        uint32_t                fdb_nchains;    /* # of hash chains in fdb */
        mod_hash_t              *vlan_hashp;    /* vlan hash table */
        uint32_t                vlan_nchains;   /* # of vlan hash chains */
        uint32_t                mtu;            /* mtu of the device */
        uint32_t                max_frame_size; /* max frame size supported */
        uint32_t                mtu_physdev_orig; /* orig mtu of the physdev */

        mod_hash_t              *mfdb;          /* multicast FDB */
        krwlock_t               mfdbrw;         /* rwlock for mFDB */

        ddi_taskq_t             *rxp_taskq;     /* VIO rx pool taskq */
        void                    (*vsw_switch_frame)
                                        (struct vsw *, mblk_t *, int,
                                        vsw_port_t *, mac_resource_handle_t);

        /* mac layer */
        kmutex_t                mac_lock;       /* protect mh */
        mac_handle_t            mh;
        krwlock_t               maccl_rwlock;   /* protect fields below */
        mac_client_handle_t     mch;            /* mac client handle */
        mac_unicast_handle_t    muh;            /* mac unicast handle */
        mac_notify_handle_t     mnh;            /* mac notify handle */

        boolean_t               recfg_reqd;     /* Reconfig of addrs needed */

        /* mac layer switching flag */
        boolean_t               mac_cl_switching;

        /* Machine Description updates  */
        mdeg_node_spec_t        *inst_spec;
        mdeg_handle_t           mdeg_hdl;
        mdeg_handle_t           mdeg_port_hdl;

        /* if configured as an ethernet interface */
        mac_handle_t            if_mh;          /* MAC handle */
        struct ether_addr       if_addr;        /* interface address */
        krwlock_t               if_lockrw;
        uint8_t                 if_state;       /* interface state */

        boolean_t               addr_set;       /* is addr set to HW */

        /* multicast addresses when configured as eth interface */
        kmutex_t                mca_lock;       /* multicast lock */
        mcst_addr_t             *mcap;          /* list of multicast addrs */

        uint32_t                pri_num_types;  /* # of priority eth types */
        uint16_t                *pri_types;     /* priority eth types */
        vio_mblk_pool_t         *pri_tx_vmp;    /* tx priority mblk pool */
        uint16_t                default_vlan_id; /* default vlan id */
        uint16_t                pvid;   /* port vlan id (untagged) */
        vsw_vlanid_t            *vids;  /* vlan ids (tagged) */
        uint16_t                nvids;  /* # of vids */
        uint32_t                vids_size; /* size alloc'd for vids list */

        /* HybridIO related fields */
        boolean_t               hio_capable;    /* Phys dev HIO capable */
        vsw_hio_t               vhio;           /* HybridIO info */
        callb_id_t              hio_reboot_cb_id; /* Reboot callb ID */
        callb_id_t              hio_panic_cb_id; /* Panic callb ID */

        /* Link-state related fields */
        boolean_t               phys_no_link_update; /* no link-update supp */
        boolean_t               pls_update;     /* phys link state update ? */
        link_state_t            phys_link_state;    /* physical link state */

        /* bandwidth related fields */
        uint64_t                bandwidth;      /* bandwidth limit */
} vsw_t;

/*
 * The flags that are used by vsw_mac_rx().
 */
typedef enum {
        VSW_MACRX_PROMISC = 0x01,
        VSW_MACRX_COPYMSG = 0x02,
        VSW_MACRX_FREEMSG = 0x04
} vsw_macrx_flags_t;


#ifdef DEBUG

extern int vswdbg;
extern void vswdebug(vsw_t *vswp, const char *fmt, ...);

#define D1(...)         \
if (vswdbg & 0x01)      \
        vswdebug(__VA_ARGS__)

#define D2(...)         \
if (vswdbg & 0x02)      \
        vswdebug(__VA_ARGS__)

#define D3(...)         \
if (vswdbg & 0x04)      \
        vswdebug(__VA_ARGS__)

#define DWARN(...)      \
if (vswdbg & 0x08)      \
        vswdebug(__VA_ARGS__)

#define DERR(...)       \
if (vswdbg & 0x10)      \
        vswdebug(__VA_ARGS__)

#else

#define DERR(...)       if (0)  do { } while (0)
#define DWARN(...)      if (0)  do { } while (0)
#define D1(...)         if (0)  do { } while (0)
#define D2(...)         if (0)  do { } while (0)
#define D3(...)         if (0)  do { } while (0)

#endif  /* DEBUG */


#ifdef  __cplusplus
}
#endif

#endif  /* _VSW_H */