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 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_NXGE_NXGE_HIO_H 28 #define _SYS_NXGE_NXGE_HIO_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include <nxge_mac.h> 35 #include <nxge_ipp.h> 36 #include <nxge_fflp.h> 37 #include <sys/mac_provider.h> 38 39 #define isLDOMservice(nxge) \ 40 (nxge->environs == SOLARIS_SERVICE_DOMAIN) 41 #define isLDOMguest(nxge) \ 42 (nxge->environs == SOLARIS_GUEST_DOMAIN) 43 #define isLDOMs(nxge) \ 44 (isLDOMservice(nxge) || isLDOMguest(nxge)) 45 46 #define NXGE_HIO_SHARE_MIN_CHANNELS 2 47 #define NXGE_HIO_SHARE_MAX_CHANNELS 2 48 49 /* ------------------------------------------------------------------ */ 50 typedef uint8_t nx_rdc_t; 51 typedef uint8_t nx_tdc_t; 52 53 typedef uint64_t res_map_t; 54 55 typedef uint64_t hv_rv_t; 56 57 typedef hv_rv_t (*vr_assign)(uint64_t, uint64_t, uint32_t *); 58 typedef hv_rv_t (*vr_unassign)(uint32_t); 59 typedef hv_rv_t (*vr_getinfo)(uint32_t, uint64_t *, uint64_t *); 60 61 /* HV 2.0 API group functions */ 62 typedef hv_rv_t (*vr_cfgh_assign)(uint64_t, uint64_t, uint64_t, uint32_t *); 63 typedef hv_rv_t (*vrlp_cfgh_conf)(uint64_t, uint64_t, uint64_t, uint64_t, 64 uint64_t); 65 typedef hv_rv_t (*vrlp_cfgh_info)(uint64_t, uint64_t, uint64_t, uint64_t *, 66 uint64_t *); 67 68 69 typedef struct { 70 vr_assign assign; /* HV Major 1 interface */ 71 vr_cfgh_assign cfgh_assign; /* HV Major 2 interface */ 72 vr_unassign unassign; 73 vr_getinfo getinfo; 74 } nxhv_vr_fp_t; 75 76 typedef hv_rv_t (*vrlp_conf)(uint64_t, uint64_t, uint64_t, uint64_t); 77 typedef hv_rv_t (*vrlp_info)(uint64_t, uint64_t, uint64_t *, uint64_t *); 78 79 typedef hv_rv_t (*dc_assign)(uint32_t, uint64_t, uint64_t *); 80 typedef hv_rv_t (*dc_unassign)(uint32_t, uint64_t); 81 typedef hv_rv_t (*dc_getstate)(uint32_t, uint64_t, uint64_t *); 82 typedef hv_rv_t (*dc_get_map)(uint32_t, uint64_t *); 83 84 typedef hv_rv_t (*dc_getinfo)(uint32_t, uint64_t, uint64_t *, uint64_t *); 85 86 typedef struct { 87 dc_assign assign; 88 dc_unassign unassign; 89 dc_getstate getstate; 90 dc_get_map get_map; 91 92 vrlp_conf lp_conf; /* HV Major 1 interface */ 93 vrlp_info lp_info; /* HV Major 1 interface */ 94 vrlp_cfgh_conf lp_cfgh_conf; /* HV Major 2 interface */ 95 vrlp_cfgh_info lp_cfgh_info; /* HV Major 2 interface */ 96 dc_getinfo getinfo; 97 } nxhv_dc_fp_t; 98 99 typedef struct { 100 boolean_t ldoms; 101 nxhv_vr_fp_t vr; 102 nxhv_dc_fp_t tx; 103 nxhv_dc_fp_t rx; 104 } nxhv_fp_t; 105 106 /* ------------------------------------------------------------------ */ 107 #define NXGE_VR_SR_MAX 8 /* There are 8 subregions (SR). */ 108 109 typedef enum { 110 NXGE_HIO_TYPE_SERVICE = 0x80, /* We are a service domain driver. */ 111 NXGE_HIO_TYPE_GUEST /* We are a guest domain driver. */ 112 } nxge_hio_type_t; 113 114 typedef enum { 115 FUNC0_MNT, 116 FUNC0_VIR = 0x1000000, 117 FUNC1_MNT = 0x2000000, 118 FUNC1_VIR = 0x3000000, 119 FUNC2_MNT = 0x4000000, 120 FUNC2_VIR = 0x5000000, 121 FUNC3_MNT = 0x6000000, 122 FUNC3_VIR = 0x7000000 123 } vr_base_address_t; 124 125 #define VR_STEP 0x2000000 126 #define VR_VC_STEP 0x0004000 127 128 typedef enum { /* 0-8 */ 129 FUNC0_VIR0, 130 FUNC0_VIR1, 131 FUNC1_VIR0, 132 FUNC1_VIR1, 133 FUNC2_VIR0, 134 FUNC2_VIR1, 135 FUNC3_VIR0, 136 FUNC3_VIR1, 137 FUNC_VIR_MAX 138 } vr_region_t; 139 140 typedef enum { 141 VP_CHANNEL_0, 142 VP_CHANNEL_1, 143 VP_CHANNEL_2, 144 VP_CHANNEL_3, 145 VP_CHANNEL_4, 146 VP_CHANNEL_5, 147 VP_CHANNEL_6, 148 VP_CHANNEL_7, 149 VP_CHANNEL_MAX 150 } vp_channel_t; 151 152 typedef enum { 153 VP_BOUND_TX = 1, 154 VP_BOUND_RX 155 } vpc_type_t; 156 157 #define VP_VC_OFFSET(channel) (channel << 10) 158 #define VP_RDC_OFFSET (1 << 9) 159 160 typedef enum { 161 RXDMA_CFIG1 = 0, 162 RXDMA_CFIG2 = 8, 163 RBR_CFIG_A = 0x10, 164 RBR_CFIG_B = 0x18, 165 RBR_KICK = 0x20, 166 RBR_STAT = 0x28, 167 RBR_HDH = 0x30, 168 RBR_HDL = 0x38, 169 RCRCFIG_A = 0x40, 170 RCRCFIG_B = 0x48, 171 RCRSTAT_A = 0x50, 172 RCRSTAT_B = 0x58, 173 RCRSTAT_C = 0x60, 174 RX_DMA_ENT_MSK = 0x68, 175 RX_DMA_CTL_STAT = 0x70, 176 RCR_FLSH = 0x78, 177 RXMISC = 0x90, 178 RX_DMA_CTL_STAT_DBG = 0x98 179 180 } rdc_csr_offset_t; 181 182 typedef enum { 183 Tx_RNG_CFIG = 0, 184 Tx_RNG_HDL = 0x10, 185 Tx_RNG_KICK = 0x18, 186 Tx_ENT_MASK = 0x20, 187 Tx_CS = 0x28, 188 TxDMA_MBH = 0x30, 189 TxDMA_MBL = 0x38, 190 TxDMA_PRE_ST = 0x40, 191 Tx_RNG_ERR_LOGH = 0x48, 192 Tx_RNG_ERR_LOGL = 0x50, 193 TDMC_INTR_DBG = 0x60, 194 Tx_CS_DBG = 0x68 195 196 } tdc_csr_offset_t; 197 198 /* 199 * ------------------------------------------------------------- 200 * These definitions are used to handle the virtual PIO_LDSV 201 * space of a VR. 202 * ------------------------------------------------------------- 203 */ 204 #define VLDG_OFFSET 0x2000 205 #define VLDG_SLL 5 206 207 typedef enum { 208 PIO_LDSV0, /* ldf_0, 0-63 */ 209 PIO_LDSV1, /* ldf_1, 0-63 */ 210 PIO_LDSV2, /* ldf_0 & ldf_1, 64-69 */ 211 PIO_LDGIMGN /* arm/timer */ 212 213 } pio_ld_op_t; 214 215 #define VR_INTR_BLOCK_SIZE 8 216 #define HIO_INTR_BLOCK_SIZE 4 217 218 /* ------------------------------------------------------------------ */ 219 typedef struct { 220 const char *name; 221 int offset; 222 } dmc_reg_name_t; 223 224 typedef struct { 225 uintptr_t nxge; 226 dc_map_t map; 227 228 } nx_rdc_tbl_t; 229 230 typedef struct nxge_hio_vr { 231 uintptr_t nxge; 232 233 uint32_t cookie; /* The HV cookie. */ 234 uintptr_t address; 235 size_t size; 236 vr_region_t region; /* 1 of 8 regions. */ 237 238 int rdc_tbl; /* 1 of 8 RDC tables. */ 239 int tdc_tbl; /* 1 of 8 TDC tables. */ 240 ether_addr_t altmac; /* The alternate MAC address. */ 241 int slot; /* According to nxge_m_mmac_add(). */ 242 243 nxge_grp_t rx_group; 244 nxge_grp_t tx_group; 245 246 } nxge_hio_vr_t; 247 248 typedef nxge_status_t (*dc_init_t)(nxge_t *, int); 249 typedef void (*dc_uninit_t)(nxge_t *, int); 250 251 typedef struct { 252 uint32_t number; /* The LDG number assigned to this DC. */ 253 uint64_t index; /* Bits 7:5 of the (virtual) PIO_LDSV. */ 254 255 uint64_t ldsv; /* The logical device number */ 256 uint64_t map; /* Currently unused */ 257 258 int vector; /* The DDI vector number (index) */ 259 } hio_ldg_t; 260 261 /* 262 * ------------------------------------------------------------- 263 * The service domain driver makes use of both <index>, the index 264 * into a VR's virtual page, and <channel>, the absolute channel 265 * number, what we will call here the physical channel number. 266 * 267 * The guest domain will set both fields to the same value, since 268 * it doesn't know any better. And if a service domain owns a 269 * DMA channel, it will also set both fields to the same value, 270 * since it is not using a VR per se. 271 * ------------------------------------------------------------- 272 */ 273 typedef struct nx_dc { 274 275 struct nx_dc *next; 276 277 nxge_hio_vr_t *vr; /* The VR belonged to. */ 278 279 vp_channel_t page; /* VP_CHANNEL_0 - VP_CHANNEL_7 */ 280 nxge_channel_t channel; /* 1 of 16/24 channels */ 281 /* 282 * <channel> has its normal meaning. <page> refers to the 283 * virtual page of the VR that <channel> has been bound to. 284 * Therefore, in the service domain, <page> & <channel> 285 * are almost always different. While in a guest domain, 286 * they are always the same. 287 */ 288 vpc_type_t type; /* VP_BOUND_XX */ 289 dc_init_t init; /* nxge_init_xxdma_channel() */ 290 dc_uninit_t uninit; /* nxge_uninit_xxdma_channel() */ 291 292 nxge_grp_t *group; /* The group belonged to. */ 293 uint32_t cookie; /* The HV cookie. */ 294 295 hio_ldg_t ldg; 296 boolean_t interrupting; /* Interrupt enabled? */ 297 298 } nxge_hio_dc_t; 299 300 typedef struct { 301 nxge_hio_type_t type; 302 303 kmutex_t lock; 304 int vrs; 305 unsigned sequence; 306 307 nxhv_fp_t hio; 308 309 /* vr[0] is reserved for the service domain. */ 310 nxge_hio_vr_t vr[NXGE_VR_SR_MAX]; /* subregion map */ 311 nxge_hio_dc_t rdc[NXGE_MAX_RDCS]; 312 nxge_hio_dc_t tdc[NXGE_MAX_TDCS]; 313 314 nx_rdc_tbl_t rdc_tbl[NXGE_MAX_RDC_GROUPS]; 315 316 } nxge_hio_data_t; 317 318 /* 319 * ------------------------------------------------------------- 320 * prototypes 321 * ------------------------------------------------------------- 322 */ 323 extern void nxge_get_environs(nxge_t *); 324 extern int nxge_hio_init(nxge_t *); 325 extern void nxge_hio_uninit(nxge_t *); 326 327 extern int nxge_dci_map(nxge_t *, vpc_type_t, int); 328 329 /* 330 * --------------------------------------------------------------------- 331 * These are the general-purpose DMA channel group functions. That is, 332 * these functions are used to manage groups of TDCs or RDCs in an HIO 333 * environment. 334 * 335 * But is also expected that in the future they will be able to manage 336 * Crossbow groups. 337 * --------------------------------------------------------------------- 338 */ 339 extern nxge_grp_t *nxge_grp_add(nxge_t *, nxge_grp_type_t); 340 extern void nxge_grp_remove(nxge_t *, nxge_grp_t *); 341 extern int nxge_grp_dc_add(nxge_t *, nxge_grp_t *, vpc_type_t, int); 342 extern void nxge_grp_dc_remove(nxge_t *, vpc_type_t, int); 343 extern nxge_hio_dc_t *nxge_grp_dc_find(nxge_t *, vpc_type_t, int); 344 345 extern void nxge_delay(int); 346 extern const char *nxge_ddi_perror(int); 347 348 /* 349 * --------------------------------------------------------------------- 350 * These are the Sun4v HIO function prototypes. 351 * --------------------------------------------------------------------- 352 */ 353 extern void nxge_hio_group_get(void *arg, mac_ring_type_t type, int group, 354 mac_group_info_t *infop, mac_group_handle_t ghdl); 355 extern int nxge_hio_share_alloc(void *arg, mac_share_handle_t *shandle); 356 extern void nxge_hio_share_free(mac_share_handle_t shandle); 357 extern void nxge_hio_share_query(mac_share_handle_t shandle, 358 mac_ring_type_t type, mac_ring_handle_t *rings, uint_t *n_rings); 359 extern int nxge_hio_share_add_group(mac_share_handle_t, 360 mac_group_driver_t); 361 extern int nxge_hio_share_rem_group(mac_share_handle_t, 362 mac_group_driver_t); 363 extern int nxge_hio_share_bind(mac_share_handle_t, uint64_t cookie, 364 uint64_t *rcookie); 365 extern void nxge_hio_share_unbind(mac_share_handle_t); 366 extern int nxge_hio_rxdma_bind_intr(nxge_t *, rx_rcr_ring_t *, int); 367 368 /* nxge_hio_guest.c */ 369 extern void nxge_hio_unregister(nxge_t *); 370 371 extern int nxge_guest_regs_map(nxge_t *); 372 extern void nxge_guest_regs_map_free(nxge_t *); 373 374 extern int nxge_hio_vr_add(nxge_t *nxge); 375 extern int nxge_hio_vr_release(nxge_t *nxge); 376 377 extern nxge_status_t nxge_tdc_lp_conf(p_nxge_t, int); 378 extern nxge_status_t nxge_rdc_lp_conf(p_nxge_t, int); 379 380 extern void nxge_hio_start_timer(nxge_t *); 381 382 /* nxge_intr.c */ 383 extern nxge_status_t nxge_hio_intr_init(nxge_t *); 384 extern void nxge_hio_intr_uninit(nxge_t *); 385 386 extern nxge_status_t nxge_intr_add(nxge_t *, vpc_type_t, int); 387 extern nxge_status_t nxge_intr_remove(nxge_t *, vpc_type_t, int); 388 389 extern nxge_status_t nxge_hio_intr_add(nxge_t *, vpc_type_t, int); 390 extern nxge_status_t nxge_hio_intr_remove(nxge_t *, vpc_type_t, int); 391 392 extern nxge_status_t nxge_hio_intr_add(nxge_t *, vpc_type_t, int); 393 extern nxge_status_t nxge_hio_intr_rem(nxge_t *, int); 394 395 extern hv_rv_t nxge_hio_ldsv_add(nxge_t *, nxge_hio_dc_t *); 396 397 extern void nxge_hio_ldsv_im(nxge_t *, nxge_ldg_t *, pio_ld_op_t, uint64_t *); 398 extern void nxge_hio_ldgimgn(nxge_t *, nxge_ldg_t *); 399 400 /* nxge_hv.c */ 401 extern void nxge_hio_hv_init(nxge_t *); 402 403 /* nxge_mac.c */ 404 extern int nxge_hio_hostinfo_get_rdc_table(p_nxge_t); 405 extern int nxge_hio_hostinfo_init(nxge_t *, nxge_hio_vr_t *, ether_addr_t *); 406 extern void nxge_hio_hostinfo_uninit(nxge_t *, nxge_hio_vr_t *); 407 408 #ifdef __cplusplus 409 } 410 #endif 411 412 #endif /* _SYS_NXGE_NXGE_HIO_H */ 413