nxge_hio.h revision da14cebe459d3275048785f25bd869cb09b5307f
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_NXGE_NXGE_HIO_H
#define _SYS_NXGE_NXGE_HIO_H
#ifdef __cplusplus
extern "C" {
#endif
#include <nxge_mac.h>
#include <nxge_ipp.h>
#include <nxge_fflp.h>
#include <sys/mac_provider.h>
#if defined(sun4v)
#include <sys/vnet_res.h>
#endif
#define isLDOMservice(nxge) \
(nxge->environs == SOLARIS_SERVICE_DOMAIN)
#define isLDOMguest(nxge) \
(nxge->environs == SOLARIS_GUEST_DOMAIN)
#define isLDOMs(nxge) \
(isLDOMservice(nxge) || isLDOMguest(nxge))
/* ------------------------------------------------------------------ */
typedef uint8_t nx_rdc_t;
typedef uint8_t nx_tdc_t;
typedef uint64_t res_map_t;
typedef uint64_t hv_rv_t;
typedef hv_rv_t (*vr_assign)(uint64_t, uint64_t, uint32_t *);
typedef hv_rv_t (*vr_unassign)(uint32_t);
typedef hv_rv_t (*vr_getinfo)(uint32_t, uint64_t *, uint64_t *);
typedef struct {
vr_assign assign;
vr_unassign unassign;
vr_getinfo getinfo;
} nxhv_vr_fp_t;
typedef hv_rv_t (*vrlp_conf)(uint64_t, uint64_t, uint64_t, uint64_t);
typedef hv_rv_t (*vrlp_info)(uint64_t, uint64_t, uint64_t *, uint64_t *);
typedef hv_rv_t (*dc_assign)(uint32_t, uint64_t, uint64_t *);
typedef hv_rv_t (*dc_unassign)(uint32_t, uint64_t);
typedef hv_rv_t (*dc_getstate)(uint32_t, uint64_t, uint64_t *);
typedef hv_rv_t (*dc_get_map)(uint32_t, uint64_t *);
typedef hv_rv_t (*dc_getinfo)(uint32_t, uint64_t, uint64_t *, uint64_t *);
typedef struct {
dc_assign assign;
dc_unassign unassign;
dc_getstate getstate;
dc_get_map get_map;
vrlp_conf lp_conf;
vrlp_info lp_info;
dc_getinfo getinfo;
} nxhv_dc_fp_t;
#if defined(sun4v)
typedef struct {
vio_net_resource_reg_t __register;
vio_net_resource_unreg_t unregister;
vio_net_callbacks_t cb;
} nx_vio_fp_t;
#endif
typedef struct {
boolean_t ldoms;
nxhv_vr_fp_t vr;
nxhv_dc_fp_t tx;
nxhv_dc_fp_t rx;
#if defined(sun4v)
nx_vio_fp_t vio;
#endif
} nxhv_fp_t;
/* ------------------------------------------------------------------ */
#define NXGE_VR_SR_MAX 8 /* There are 8 subregions (SR). */
typedef enum {
NXGE_HIO_TYPE_SERVICE, /* We are a service domain driver. */
NXGE_HIO_TYPE_GUEST /* We are a guest domain driver. */
} nxge_hio_type_t;
typedef enum {
FUNC0_MNT,
FUNC0_VIR = 0x1000000,
FUNC1_MNT = 0x2000000,
FUNC1_VIR = 0x3000000,
FUNC2_MNT = 0x4000000,
FUNC2_VIR = 0x5000000,
FUNC3_MNT = 0x6000000,
FUNC3_VIR = 0x7000000
} vr_base_address_t;
#define VR_STEP 0x2000000
#define VR_VC_STEP 0x0004000
typedef enum { /* 0-8 */
FUNC0_VIR0,
FUNC0_VIR1,
FUNC1_VIR0,
FUNC1_VIR1,
FUNC2_VIR0,
FUNC2_VIR1,
FUNC3_VIR0,
FUNC3_VIR1,
FUNC_VIR_MAX
} vr_region_t;
typedef enum {
VP_CHANNEL_0,
VP_CHANNEL_1,
VP_CHANNEL_2,
VP_CHANNEL_3,
VP_CHANNEL_4,
VP_CHANNEL_5,
VP_CHANNEL_6,
VP_CHANNEL_7,
VP_CHANNEL_MAX
} vp_channel_t;
typedef enum {
VP_BOUND_TX = 1,
VP_BOUND_RX
} vpc_type_t;
#define VP_VC_OFFSET(channel) (channel << 10)
#define VP_RDC_OFFSET (1 << 9)
typedef enum {
RXDMA_CFIG1 = 0,
RXDMA_CFIG2 = 8,
RBR_CFIG_A = 0x10,
RBR_CFIG_B = 0x18,
RBR_KICK = 0x20,
RBR_STAT = 0x28,
RBR_HDH = 0x30,
RBR_HDL = 0x38,
RCRCFIG_A = 0x40,
RCRCFIG_B = 0x48,
RCRSTAT_A = 0x50,
RCRSTAT_B = 0x58,
RCRSTAT_C = 0x60,
RX_DMA_ENT_MSK = 0x68,
RX_DMA_CTL_STAT = 0x70,
RCR_FLSH = 0x78,
RXMISC = 0x90,
RX_DMA_CTL_STAT_DBG = 0x98
} rdc_csr_offset_t;
typedef enum {
Tx_RNG_CFIG = 0,
Tx_RNG_HDL = 0x10,
Tx_RNG_KICK = 0x18,
Tx_ENT_MASK = 0x20,
Tx_CS = 0x28,
TxDMA_MBH = 0x30,
TxDMA_MBL = 0x38,
TxDMA_PRE_ST = 0x40,
Tx_RNG_ERR_LOGH = 0x48,
Tx_RNG_ERR_LOGL = 0x50,
TDMC_INTR_DBG = 0x60,
Tx_CS_DBG = 0x68
} tdc_csr_offset_t;
/*
* -------------------------------------------------------------
* These definitions are used to handle the virtual PIO_LDSV
* space of a VR.
* -------------------------------------------------------------
*/
#define VLDG_OFFSET 0x2000
#define VLDG_SLL 5
typedef enum {
PIO_LDSV0, /* ldf_0, 0-63 */
PIO_LDSV1, /* ldf_1, 0-63 */
PIO_LDSV2, /* ldf_0 & ldf_1, 64-69 */
PIO_LDGIMGN /* arm/timer */
} pio_ld_op_t;
#define VR_INTR_BLOCK_SIZE 8
#define HIO_INTR_BLOCK_SIZE 4
/* ------------------------------------------------------------------ */
typedef struct {
const char *name;
int offset;
} dmc_reg_name_t;
typedef struct {
uintptr_t nxge;
dc_map_t map;
} nx_rdc_tbl_t;
typedef struct nxge_hio_vr {
uintptr_t nxge;
uint32_t cookie; /* The HV cookie. */
uintptr_t address;
size_t size;
vr_region_t region; /* 1 of 8 regions. */
int rdc_tbl; /* 1 of 8 RDC tables. */
int tdc_tbl; /* 1 of 8 TDC tables. */
ether_addr_t altmac; /* The alternate MAC address. */
int slot; /* According to nxge_m_mmac_add(). */
#if defined(sun4v)
vio_net_handle_t vhp; /* The handle given to us by the vnet. */
#endif
nxge_grp_t rx_group;
nxge_grp_t tx_group;
} nxge_hio_vr_t;
typedef nxge_status_t (*dc_init_t)(nxge_t *, int);
typedef void (*dc_uninit_t)(nxge_t *, int);
typedef struct {
uint32_t number; /* The LDG number assigned to this DC. */
uint64_t index; /* Bits 7:5 of the (virtual) PIO_LDSV. */
uint64_t ldsv; /* The logical device number */
uint64_t map; /* Currently unused */
int vector; /* The DDI vector number (index) */
} hio_ldg_t;
/*
* -------------------------------------------------------------
* The service domain driver makes use of both <index>, the index
* into a VR's virtual page, and <channel>, the absolute channel
* number, what we will call here the physical channel number.
*
* The guest domain will set both fields to the same value, since
* it doesn't know any better. And if a service domain owns a
* DMA channel, it will also set both fields to the same value,
* since it is not using a VR per se.
* -------------------------------------------------------------
*/
typedef struct nx_dc {
struct nx_dc *next;
nxge_hio_vr_t *vr; /* The VR belonged to. */
vp_channel_t page; /* VP_CHANNEL_0 - VP_CHANNEL_7 */
nxge_channel_t channel; /* 1 of 16/24 channels */
/*
* <channel> has its normal meaning. <page> refers to the
* virtual page of the VR that <channel> has been bound to.
* Therefore, in the service domain, <page> & <channel>
* are almost always different. While in a guest domain,
* they are always the same.
*/
vpc_type_t type; /* VP_BOUND_XX */
dc_init_t init; /* nxge_init_xxdma_channel() */
dc_uninit_t uninit; /* nxge_uninit_xxdma_channel() */
nxge_grp_t *group; /* The group belonged to. */
uint32_t cookie; /* The HV cookie. */
hio_ldg_t ldg;
boolean_t interrupting; /* Interrupt enabled? */
} nxge_hio_dc_t;
typedef struct {
nxge_hio_type_t type;
kmutex_t lock;
int vrs;
unsigned sequence;
nxhv_fp_t hio;
/* vr[0] is reserved for the service domain. */
nxge_hio_vr_t vr[NXGE_VR_SR_MAX]; /* subregion map */
nxge_hio_dc_t rdc[NXGE_MAX_RDCS];
nxge_hio_dc_t tdc[NXGE_MAX_TDCS];
nx_rdc_tbl_t rdc_tbl[NXGE_MAX_RDC_GROUPS];
} nxge_hio_data_t;
/*
* -------------------------------------------------------------
* prototypes
* -------------------------------------------------------------
*/
extern void nxge_get_environs(nxge_t *);
extern int nxge_hio_init(nxge_t *);
extern void nxge_hio_uninit(nxge_t *);
extern int nxge_dci_map(nxge_t *, vpc_type_t, int);
/*
* ---------------------------------------------------------------------
* These are the general-purpose DMA channel group functions. That is,
* these functions are used to manage groups of TDCs or RDCs in an HIO
* environment.
*
* But is also expected that in the future they will be able to manage
* Crossbow groups.
* ---------------------------------------------------------------------
*/
extern nxge_grp_t *nxge_grp_add(nxge_t *, nxge_grp_type_t);
extern void nxge_grp_remove(nxge_t *, nxge_grp_t *);
extern int nxge_grp_dc_add(nxge_t *, nxge_grp_t *, vpc_type_t, int);
extern void nxge_grp_dc_remove(nxge_t *, vpc_type_t, int);
extern nxge_hio_dc_t *nxge_grp_dc_find(nxge_t *, vpc_type_t, int);
extern void nxge_delay(int);
extern const char *nxge_ddi_perror(int);
/*
* ---------------------------------------------------------------------
* These are the Sun4v HIO function prototypes.
* ---------------------------------------------------------------------
*/
extern void nxge_hio_group_get(void *arg, mac_ring_type_t type, int group,
mac_group_info_t *infop, mac_group_handle_t ghdl);
extern int nxge_hio_share_alloc(void *arg, mac_share_handle_t *shandle);
extern void nxge_hio_share_free(mac_share_handle_t shandle);
extern void nxge_hio_share_query(mac_share_handle_t shandle,
mac_ring_type_t type, mac_ring_handle_t *rings, uint_t *n_rings);
extern int nxge_hio_share_add_group(mac_share_handle_t,
mac_group_driver_t);
extern int nxge_hio_share_rem_group(mac_share_handle_t,
mac_group_driver_t);
extern int nxge_hio_share_bind(mac_share_handle_t, uint64_t cookie,
uint64_t *rcookie);
extern void nxge_hio_share_unbind(mac_share_handle_t);
/* nxge_hio_guest.c */
extern void nxge_hio_unregister(nxge_t *);
extern int nxge_guest_regs_map(nxge_t *);
extern void nxge_guest_regs_map_free(nxge_t *);
extern int nxge_hio_vr_add(nxge_t *nxge);
extern int nxge_hio_vr_release(nxge_t *nxge);
extern nxge_status_t nxge_tdc_lp_conf(p_nxge_t, int);
extern nxge_status_t nxge_rdc_lp_conf(p_nxge_t, int);
extern void nxge_hio_start_timer(nxge_t *);
/* nxge_intr.c */
extern nxge_status_t nxge_hio_intr_init(nxge_t *);
extern void nxge_hio_intr_uninit(nxge_t *);
extern nxge_status_t nxge_intr_add(nxge_t *, vpc_type_t, int);
extern nxge_status_t nxge_intr_remove(nxge_t *, vpc_type_t, int);
extern nxge_status_t nxge_hio_intr_add(nxge_t *, vpc_type_t, int);
extern nxge_status_t nxge_hio_intr_remove(nxge_t *, vpc_type_t, int);
extern nxge_status_t nxge_hio_intr_add(nxge_t *, vpc_type_t, int);
extern nxge_status_t nxge_hio_intr_rem(nxge_t *, int);
extern hv_rv_t nxge_hio_ldsv_add(nxge_t *, nxge_hio_dc_t *);
extern void nxge_hio_ldsv_im(nxge_t *, nxge_ldg_t *, pio_ld_op_t, uint64_t *);
extern void nxge_hio_ldgimgn(nxge_t *, nxge_ldg_t *);
/* nxge_hv.c */
extern void nxge_hio_hv_init(nxge_t *);
/* nxge_mac.c */
extern int nxge_hio_hostinfo_get_rdc_table(p_nxge_t);
extern int nxge_hio_hostinfo_init(nxge_t *, nxge_hio_vr_t *, ether_addr_t *);
extern void nxge_hio_hostinfo_uninit(nxge_t *, nxge_hio_vr_t *);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_NXGE_NXGE_HIO_H */