root/usr/src/uts/common/io/bnxe/577xx/drivers/common/include/vm/vfpf_if.h
#ifndef VF_PF_SW_IF_H
#define VF_PF_SW_IF_H


/* 
 * common flags - right now it duplicates the #defines in the PF code -
 * TODO: put in another common header file
 */
#define SW_VFPF_QUEUE_FLG_TPA                   0x0001
#define SW_VFPF_QUEUE_FLG_CACHE_ALIGN           0x0002
#define SW_VFPF_QUEUE_FLG_STATS         0x0004
#define SW_VFPF_QUEUE_FLG_OV                    0x0008
#define SW_VFPF_QUEUE_FLG_VLAN                  0x0010
#define SW_VFPF_QUEUE_FLG_COS                   0x0020
#define SW_VFPF_QUEUE_FLG_HC            0x0040
#define SW_VFPF_QUEUE_FLG_DHC           0x0080

#define SW_VFPF_QUEUE_DROP_IP_CS_ERR    (1 << 0)
#define SW_VFPF_QUEUE_DROP_TCP_CS_ERR   (1 << 1)
#define SW_VFPF_QUEUE_DROP_TTL0         (1 << 2)
#define SW_VFPF_QUEUE_DROP_UDP_CS_ERR   (1 << 3)

#define SW_VFPF_VFDEF_INFO_AUX_DIRECT_DQ   0x01

enum {
        SW_PFVF_STATUS_WAITING = 0,
        SW_PFVF_STATUS_SUCCESS,
        SW_PFVF_STATUS_FAILURE,
        SW_PFVF_STATUS_NOT_SUPPORTED,
    SW_PFVF_STATUS_MISMATCH_PF_VF_VERSION,
    SW_PFVF_STATUS_NO_RESOURCE,
    SW_PFVF_STATUS_MISMATCH_FW_HSI
};

/*  Headers */
struct vf_pf_msg_hdr {
        u16 opcode;

#define PFVF_IF_VERSION            1
        u8  if_ver;
        u8  opcode_ver;
        u32 resp_msg_offset;
};

struct pf_vf_msg_hdr {
        u8 status;
        u8 opcode_ver;
        u16 opcode;
};

/* simple response */
struct pf_vf_msg_resp {
        struct pf_vf_msg_hdr    hdr;
};


/* Acquire */
struct vf_pf_msg_acquire {
        struct vf_pf_msg_hdr hdr;

        struct sw_vf_pf_vfdev_info
        {
                /* the following fields are for debug purposes */
                u8  vf_id;              /* ME register value */
                u8  vf_os;              /* e.g. Linux, W2K8 */
        u8  vf_aux;
        u8  fp_hsi_ver;
        u32 vf_fw_hsi_version;  /* e.g. 6.0.12 */
        } vfdev_info;

        struct sw_vf_pf_resc_request
        {
                u8  num_rxqs;
                u8  num_txqs;
                u8  num_sbs;
                u8  num_mac_filters;
                u8  num_vlan_filters;
                u8  num_mc_filters;
        u8  reserved1;
        u8  reserved2;

        /* TODO: future:
                statistics resc?, other resc?   */
        } resc_request;
};


/* simple operation request on queue */
struct vf_pf_msg_q_op {
        struct vf_pf_msg_hdr    hdr;
        u8                      vf_qid;
        u8                      padding[3];
};

struct vf_pf_msg_rss {
        struct vf_pf_msg_hdr    hdr;
        u32                                     rss_flags;

        /* Number hash bits to take into an account */
        u8                                      rss_result_mask;

        u8                                              ind_table_size;
        u8                                              rss_key_size;

        /* Indirection table */
        u8                                      ind_table[T_ETH_INDIRECTION_TABLE_SIZE];

        /* RSS hash values */
        u32                                     rss_key[10];
};

struct vf_pf_msg_rsc {
    struct vf_pf_msg_hdr    hdr;
    u32                     rsc_ipv4_state;
    u32                     rsc_ipv6_state;
};

struct sw_hw_sb_info {
        u8 hw_sb_id;    /* aka absolute igu id, used to ack the sb */
        u8 sb_qid;      /* used to update DHC for sb */
};

struct pf_vf_msg_acquire_resp {
        struct pf_vf_msg_hdr hdr;
        
        struct sw_pf_vf_pfdev_info
        {
                u32 chip_num;
                
                u32 pf_cap;
                #define PFVF_CAP_RSS        0x00000001
                #define PFVF_CAP_DHC        0x00000002
                #define PFVF_CAP_TPA        0x00000004
                #define PFVF_DEBUG          0x80000000
                
                u16 db_size;
                u8  indices_per_sb;
                u8  padding;
        } pfdev_info;

        struct sw_pf_vf_resc
        {  
                /* 
                 * in case of status NO_RESOURCE in message hdr, pf will fill
                 * this struct with suggested amount of resources for next
                 * acquire request 
                 */
        
                #define PFVF_MAX_QUEUES_PER_VF         16
                #define PFVF_MAX_SBS_PER_VF            16
                struct sw_hw_sb_info hw_sbs[PFVF_MAX_SBS_PER_VF];
                u8      hw_qid[PFVF_MAX_QUEUES_PER_VF];
                u8      num_rxqs;
                u8      num_txqs;
                u8      num_sbs;
                u8      num_mac_filters;
                u8      num_vlan_filters;
                u8      num_mc_filters;
                u8  igu_test_cnt;
                u8  igu_cnt;
                u8      permanent_mac_addr[8];
                u8      current_mac_addr[8];
        /* TODO: stats resc? cid for the ramrod? stats_id? spq prod id? */
        } resc;
};

/* Init VF */
struct vf_pf_msg_init_vf {
        struct vf_pf_msg_hdr hdr;
        
        u64 sb_addr[PFVF_MAX_SBS_PER_VF]; /* vf_sb based */
        u64 spq_addr;
        u64 stats_addr;
};

/* Setup Queue */
struct vf_pf_msg_setup_q {
        struct vf_pf_msg_hdr hdr;
        u8 vf_qid;                      /* index in hw_qid[] */

        u8 param_valid;
        #define VFPF_RXQ_VALID          0x01
        #define VFPF_TXQ_VALID          0x02

        u16 padding;

        struct sw_vf_pf_rxq_params {
                /* physical addresses */
                u64 rcq_addr;
                u64 rcq_np_addr;
                u64 rxq_addr;
                u64 sge_addr;
                
                /* sb + hc info */
                u8  vf_sb;              /* index in hw_sbs[] */
                u8  sb_index;           /* Index in the SB */
                u16 hc_rate;            /* desired interrupts per sec. */
                                        /* valid iff VFPF_QUEUE_FLG_HC */
                /* rx buffer info */
                u16 mtu;
                u16 buf_sz;
                u16 flags;              /* VFPF_QUEUE_FLG_X flags */
                u16 stat_id;            /* valid iff VFPF_QUEUE_FLG_STATS */

                /* valid iff VFPF_QUEUE_FLG_TPA */
                u16 sge_buf_sz;         
                u16 tpa_agg_sz;
                u8 max_sge_pkt;

                u8 drop_flags;          /* VFPF_QUEUE_DROP_X, for Linux all should 
                                         * be turned off, see setup_rx_queue() 
                                         * for reference
                                         */

                u8 cache_line_log;      /* VFPF_QUEUE_FLG_CACHE_ALIGN 
                                         * see init_rx_queue()
                                         */
                u8 padding;
        } rxq;

        struct sw_vf_pf_txq_params {
                /* physical addresses */
                u64 txq_addr;

                /* sb + hc info */
                u8  vf_sb;              /* index in hw_sbs[] */
                u8  sb_index;           /* Index in the SB */
                u16 hc_rate;            /* desired interrupts per sec. */
                                        /* valid iff VFPF_QUEUE_FLG_HC */
                u32 flags;              /* VFPF_QUEUE_FLG_X flags */
                u16 stat_id;            /* valid iff VFPF_QUEUE_FLG_STATS */
                u8  traffic_type;       /* see in setup_context() */
                u8  padding;
        } txq;
};


/* Set Queue Filters */
struct vf_pf_q_mac_vlan_filter {
        u32 flags;
        #define VFPF_Q_FILTER_DEST_MAC_PRESENT  0x01
        #define VFPF_Q_FILTER_VLAN_TAG_PRESENT  0x02

        #define VFPF_Q_FILTER_SET_MAC                   0x100
        
        u8  dest_mac[6];
        u16 vlan_tag;
};

struct vf_pf_msg_set_q_filters {
        struct vf_pf_msg_hdr hdr;

        u32 flags;
        #define VFPF_SET_Q_FILTERS_MAC_VLAN_CHANGED     0x01
        #define VFPF_SET_Q_FILTERS_MULTICAST_CHANGED    0x02
        #define VFPF_SET_Q_FILTERS_RX_MASK_CHANGED      0x04
        
        u8 vf_qid;                      /* index in hw_qid[] */
        u8 n_mac_vlan_filters;
        u8 n_multicast;
        u8 padding;
        
        #define PFVF_MAX_MAC_FILTERS                    16
        #define PFVF_MAX_VLAN_FILTERS                   16
//      #define PFVF_MAX_MAC_FILTERS                    1
//      #define PFVF_MAX_VLAN_FILTERS                   1
        #define PFVF_MAX_FILTERS                        (PFVF_MAX_MAC_FILTERS +\
                                                         PFVF_MAX_VLAN_FILTERS)
        struct vf_pf_q_mac_vlan_filter filters[PFVF_MAX_FILTERS];
        
        #define PFVF_MAX_MULTICAST_PER_VF               32
//      #define PFVF_MAX_MULTICAST_PER_VF               1
        u8  multicast[PFVF_MAX_MULTICAST_PER_VF][6];
        
        u32 rx_mask;
        #define VFPF_RX_MASK_ACCEPT_NONE                0x00000000
        #define VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST     0x00000001
        #define VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST   0x00000002
        #define VFPF_RX_MASK_ACCEPT_ALL_UNICAST         0x00000004
        #define VFPF_RX_MASK_ACCEPT_ALL_MULTICAST       0x00000008
        #define VFPF_RX_MASK_ACCEPT_BROADCAST           0x00000010
        /* TODO: #define VFPF_RX_MASK_ACCEPT_ANY_VLAN   0x00000020 */
};


/* close VF (disable VF) */
struct vf_pf_msg_close_vf {
        struct vf_pf_msg_hdr    hdr;
        u16                     vf_id;  /* for debug */
        u16                     padding;                        
};

/* rlease the VF's acquired resources */
struct vf_pf_msg_release_vf {
        struct vf_pf_msg_hdr    hdr;
        u16                     vf_id;  /* for debug */
        u16                     padding;
};


union vf_pf_msg {
        struct vf_pf_msg_hdr            hdr;
        struct vf_pf_msg_acquire        acquire;
        struct vf_pf_msg_init_vf        init_vf;
        struct vf_pf_msg_close_vf       close_vf;
        struct vf_pf_msg_q_op           q_op;
        struct vf_pf_msg_setup_q        setup_q;
        struct vf_pf_msg_set_q_filters  set_q_filters;
        struct vf_pf_msg_release_vf     release_vf;
        struct vf_pf_msg_rss            update_rss;
    struct vf_pf_msg_rsc        update_rsc;
};


union pf_vf_msg {
        struct pf_vf_msg_resp           resp;
        struct pf_vf_msg_acquire_resp   acquire_resp;
};

typedef struct {
        u32 req_sz;
        u32 resp_sz;
} msg_sz_t;

#define PFVF_OP_VER_MAX(op_arry)  (sizeof(op_arry)/sizeof(*op_arry) - 1)

static const msg_sz_t acquire_req_sz[] = {
        /* sizeof(vf_pf_msg_acquire) - offsetof(struct vf_pf_msg_acquire, fieldX), */
        {sizeof(struct vf_pf_msg_acquire),
        sizeof(struct pf_vf_msg_acquire_resp)}
};
#define PFVF_ACQUIRE_VER  PFVF_OP_VER_MAX(acquire_req_sz)       

static const msg_sz_t init_vf_req_sz[] = {
        {sizeof(struct vf_pf_msg_init_vf), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_INIT_VF_VER  PFVF_OP_VER_MAX(init_vf_req_sz)

static const msg_sz_t setup_q_req_sz[] = {
        {sizeof(struct vf_pf_msg_setup_q), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_SETUP_Q_VER  PFVF_OP_VER_MAX(setup_q_req_sz)

static const msg_sz_t set_q_filters_req_sz[] = {
        {sizeof(struct vf_pf_msg_set_q_filters), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_SET_Q_FILTERS_VER  PFVF_OP_VER_MAX(set_q_filters_req_sz)

static const msg_sz_t activate_q_req_sz[] = {
        {sizeof(struct vf_pf_msg_q_op), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_ACTIVATE_Q_VER  PFVF_OP_VER_MAX(activate_q_req_sz)

static const msg_sz_t deactivate_q_req_sz[] = {
        {sizeof(struct vf_pf_msg_q_op), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_DEACTIVATE_Q_VER  PFVF_OP_VER_MAX(deactivate_q_req_sz)

static const msg_sz_t teardown_q_req_sz[] = {
        {sizeof(struct vf_pf_msg_q_op), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_TEARDOWN_Q_VER  PFVF_OP_VER_MAX(teardown_q_req_sz)

static const msg_sz_t close_vf_req_sz[] = {
        {sizeof(struct vf_pf_msg_close_vf), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_CLOSE_VF_VER  PFVF_OP_VER_MAX(close_vf_req_sz)

static const msg_sz_t release_vf_req_sz[] = {
        {sizeof(struct vf_pf_msg_release_vf), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_RELEASE_VF_VER  PFVF_OP_VER_MAX(release_vf_req_sz)

static const msg_sz_t update_rss_req_sz[] = {
        {sizeof(struct vf_pf_msg_rss), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_UPDATE_RSS_VER  PFVF_OP_VER_MAX(update_rss_req_sz)

static const msg_sz_t update_rsc_req_sz[] = {
    {sizeof(struct vf_pf_msg_rsc), sizeof(struct pf_vf_msg_resp)}
};
#define PFVF_UPDATE_RSC_VER  PFVF_OP_VER_MAX(update_rsc_req_sz)

enum {
        PFVF_OP_ACQUIRE = 0,
        PFVF_OP_INIT_VF,
        PFVF_OP_SETUP_Q,
        PFVF_OP_SET_Q_FILTERS,
        PFVF_OP_ACTIVATE_Q,
        PFVF_OP_DEACTIVATE_Q,
        PFVF_OP_TEARDOWN_Q,
        PFVF_OP_CLOSE_VF,
        PFVF_OP_RELEASE_VF,
        PFVF_OP_UPDATE_RSS,
    PFVF_OP_UPDATE_RSC,
        PFVF_OP_MAX
};


/** To get size of message of the type X(request or response)
 *  for the op_code Y of the version Z one should use
 *
 *  op_code_req_sz[Y][Z].req_sz/resp_sz
 ******************************************************************/
/* const msg_sz_t* op_codes_req_sz[] = {
        (const msg_sz_t*)acquire_req_sz,
        (const msg_sz_t*)init_vf_req_sz,
        (const msg_sz_t*)setup_q_req_sz,
        (const msg_sz_t*)set_q_filters_req_sz,
        (const msg_sz_t*)activate_q_req_sz,
        (const msg_sz_t*)deactivate_q_req_sz,
        (const msg_sz_t*)teardown_q_req_sz,
        (const msg_sz_t*)close_vf_req_sz,
        (const msg_sz_t*)release_vf_req_sz
}; */

#endif /* VF_PF_SW_IF_H */