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