nxge_hio_guest.c revision ef523517a9229b22f61e722d44116e21a7a2675a
/*
* 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
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
*
* This file manages the virtualization resources for a guest domain.
*
*/
/*
* nxge_guest_regs_map
*
* Map in a guest domain's register set(s).
*
* Arguments:
* nxge
*
* Notes:
* Note that we set <is_vraddr> to TRUE.
*
* Context:
* Guest domain
*/
};
int
{
int rv;
/* So we can allocate properly-aligned memory. */
return (NXGE_ERROR);
}
if (rv != DDI_SUCCESS) {
return (NXGE_ERROR);
}
/* NPI_REG_ADD_HANDLE_SET() */
/* NPI_VREG_ADD_HANDLE_SET() */
/*
* We do NOT set the PCI, MSI-X, 2nd Virtualization,
* or FCODE reg variables.
*/
return (NXGE_OK);
}
void
{
"==> nxge_unmap_regs: device registers"));
}
}
}
#if defined(sun4v)
/*
* -------------------------------------------------------------
* Local prototypes
* -------------------------------------------------------------
*/
static nxge_hio_dc_t *nxge_guest_dc_alloc(
static void nxge_check_guest_state(nxge_hio_vr_t *);
/*
* nxge_hio_vr_add
*
* If we have been given a virtualization region (VR),
* then initialize it.
*
* Arguments:
* nxge
*
* Notes:
*
* Context:
* Guest domain
*/
/* ARGSUSED */
int
{
int *reg_val;
int i;
/*
* Can't add VR to the service domain from which we came.
*/
return (DDI_FAILURE);
}
/*
* Get our HV cookie.
*/
return (DDI_FAILURE);
}
if (hv_rv != 0) {
"vr->getinfo() failed"));
return (DDI_FAILURE);
}
/*
* In the guest domain, we can use any VR data structure
* we want, because we're not supposed to know which VR
* the service domain has allocated to us.
*
* In the current version, the least significant nybble of
* the cookie is the VR region, but that could change
* very easily.
*
* In the future, a guest may have more than one VR allocated
* to it, which is why we go through this exercise.
*/
break;
}
}
if (vr_index == FUNC_VIR_MAX) {
"no VRs available"));
"nxge_hio_vr_add(%d): cookie(0x%x)\n",
return (DDI_FAILURE);
}
/*
* This is redundant data, but useful nonetheless. It helps
* us to keep track of which RDCs & TDCs belong to us.
*/
/*
* See nxge_intr.c.
*/
"nxge_hio_intr_init() failed"));
return (DDI_FAILURE);
}
/*
* Now we find out which RDCs & TDCs have been allocated to us.
*/
/*
* The map we get back is a bitmap of the
* virtual Tx DMA channels we own -
* they are NOT real channel numbers.
*/
if (hv_rv != 0) {
"tx->get_map() failed"));
return (DDI_FAILURE);
}
/*
* For each channel, mark these two fields
* while we have the VR data structure.
*/
for (i = 0; i < VP_CHANNEL_MAX; i++) {
if ((1 << i) & tx_map) {
if (dc == 0) {
"DC add failed"));
return (DDI_FAILURE);
}
}
}
}
/*
* I repeat, the map we get back is a bitmap of
* the virtual Rx DMA channels we own -
* they are NOT real channel numbers.
*/
if (hv_rv != 0) {
"rx->get_map() failed"));
return (DDI_FAILURE);
}
/*
* For each channel, mark these two fields
* while we have the VR data structure.
*/
for (i = 0; i < VP_CHANNEL_MAX; i++) {
if ((1 << i) & rx_map) {
if (dc == 0) {
"DC add failed"));
return (DDI_FAILURE);
}
}
}
}
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*
* nxge_guest_dc_alloc
*
* Find a free nxge_hio_dc_t data structure.
*
* Arguments:
* nxge
* type TRANSMIT or RECEIVE.
*
* Notes:
*
* Context:
* Guest domain
*/
{
int limit, i;
/*
* In the guest domain, there may be more than one VR.
* each one of which will be using the same slots, or
* virtual channel numbers. So the <nhd>'s rdc & tdc
* tables must be shared.
*/
if (type == NXGE_TRANSMIT_GROUP) {
} else {
}
return (dc);
}
}
return (0);
}
/*
* res_map_parse
*
* Parse a resource map. The resources are DMA channels, receive
* or transmit, depending on <type>.
*
* Arguments:
* nxge
* type Transmit or receive.
* res_map The resource map to parse.
*
* Notes:
*
* Context:
* Guest domain
*/
void
{
/* Slots are numbered 0 - 7. */
/* Count the number of bits in the bitmap. */
count++;
if (count == 1)
mask <<= 1;
}
/*
* A guest domain has one Tx & one Rx group, so far.
* In the future, there may be more than one.
*/
if (type == NXGE_TRANSMIT_GROUP) {
/*
* Pointless in a guest domain. This bitmap is used
* in only one place: nxge_txc_init(),
* a service-domain-only function.
*/
} else {
}
}
/*
* nxge_hio_vr_release
*
* Release a virtualization region (VR).
*
* Arguments:
* nxge
*
* Notes:
* We must uninitialize all DMA channels associated with the VR, too.
*
* The service domain will re-initialize these DMA channels later.
* See nxge_hio.c:nxge_hio_share_free() for details.
*
* Context:
* Guest domain
*/
int
{
int vr_index;
return (NXGE_OK);
}
/*
* Uninitialize interrupts.
*/
/*
* Uninitialize the receive DMA channels.
*/
/*
* Uninitialize the transmit DMA channels.
*/
/*
* Remove both groups. Assumption: only two groups!
*/
/*
* Clean up.
*/
break;
}
}
return (NXGE_OK);
}
#if defined(NIU_LP_WORKAROUND)
/*
* nxge_tdc_lp_conf
*
* Configure the logical pages for a TDC.
*
* Arguments:
* nxge
* channel The TDC to configure.
*
* Notes:
*
* Context:
* Guest domain
*/
int channel)
{
/* This shouldn't happen. */
return (NXGE_OK);
}
return (NXGE_ERROR);
/*
* Initialize logical page 0 for data buffers.
*
* <orig_ioaddr_pp> & <orig_alength> are initialized in
* nxge_main.c:nxge_dma_mem_alloc().
*/
if (hv_rv != 0) {
"<== nxge_tdc_lp_conf: channel %d "
"(page 0 data buf) hv: %d "
"ioaddr_pp $%p size 0x%llx ",
return (NXGE_ERROR | hv_rv);
}
"==> nxge_tdc_lp_conf: channel %d "
"(page 0 data buf) hv_rv 0x%llx "
"set ioaddr_pp $%p set size 0x%llx "
"get ra ioaddr_pp $%p get size 0x%llx ",
/*
* Initialize logical page 1 for control buffers.
*/
if (hv_rv != 0) {
"<== nxge_tdc_lp_conf: channel %d "
"(page 1 cntl buf) hv_rv 0x%llx "
"ioaddr_pp $%p size 0x%llx ",
return (NXGE_ERROR | hv_rv);
}
"==> nxge_tdc_lp_conf: channel %d "
"(page 1 cntl buf) hv_rv 0x%llx "
"set ioaddr_pp $%p set size 0x%llx "
"get ra ioaddr_pp $%p get size 0x%llx ",
return (NXGE_OK);
}
/*
* nxge_rdc_lp_conf
*
* Configure an RDC's logical pages.
*
* Arguments:
* nxge
* channel The RDC to configure.
*
* Notes:
*
* Context:
* Guest domain
*/
int channel)
{
return (NXGE_OK);
}
return (NXGE_ERROR);
/*
* Initialize logical page 0 for data buffers.
*
* <orig_ioaddr_pp> & <orig_alength> are initialized in
* nxge_main.c:nxge_dma_mem_alloc().
*/
if (hv_rv != 0) {
"<== nxge_rdc_lp_conf: channel %d "
"(page 0 data buf) hv_rv 0x%llx "
"ioaddr_pp $%p size 0x%llx ",
return (NXGE_ERROR | hv_rv);
}
"==> nxge_rdc_lp_conf: channel %d "
"(page 0 data buf) hv_rv 0x%llx "
"set ioaddr_pp $%p set size 0x%llx "
"get ra ioaddr_pp $%p get size 0x%llx ",
/*
* Initialize logical page 1 for control buffers.
*/
if (hv_rv != 0) {
"<== nxge_rdc_lp_conf: channel %d "
"(page 1 cntl buf) hv_rv 0x%llx "
"ioaddr_pp $%p size 0x%llx ",
return (NXGE_ERROR | hv_rv);
}
"==> nxge_rdc_lp_conf: channel %d "
"(page 1 cntl buf) hv_rv 0x%llx "
"set ioaddr_pp $%p set size 0x%llx "
"get ra ioaddr_pp $%p get size 0x%llx ",
return (NXGE_OK);
}
#endif /* defined(NIU_LP_WORKAROUND) */
/*
* This value is in milliseconds.
*/
/*
* nxge_hio_start_timer
*
* Start the timer which checks for Tx hangs.
*
* Arguments:
* nxge
*
* Notes:
* This function is called from nxge_attach().
*
* This function kicks off the guest domain equivalent of
* nxge_check_hw_state(). It is called only once, from attach.
*
* Context:
* Guest domain
*/
void
{
int region;
/*
* Find our VR data structure. (We are currently assuming
* one VR per guest domain. That may change in the future.)
*/
break;
}
if (region == NXGE_VR_SR_MAX) {
return;
}
}
/*
* nxge_check_guest_state
*
* Essentially, check for Tx hangs. In the future, if we are
* polling the hardware, we may do so here.
*
* Arguments:
* vr The virtualization region (VR) data structure.
*
* Notes:
* This function is the guest domain equivalent of
* nxge_check_hw_state(). Since we have no hardware to
* check, we simply call nxge_check_tx_hang().
*
* Context:
* Guest domain
*/
void
{
nxge->nxge_timerid = 0;
}
}
{
/*
* Validate state of guest interface before
* proceeeding.
*/
if (!isLDOMguest(nxge))
return (NXGE_ERROR);
return (NXGE_ERROR);
/*
* In guest domain, always and only dealing with
* group 0 for an instance of nxge.
*/
/*
* Look to arm the the RDCs for the group.
*/
/*
* Get the RDC.
*/
return (NXGE_ERROR);
/*
* Get the RDC's ldg group.
*/
return (NXGE_ERROR);
/*
* Set the state of the group.
*/
}
}
return (NXGE_OK);
}
{
/*
* Validate state of guest interface before
* proceeeding.
*/
if (!isLDOMguest(nxge))
return (NXGE_ERROR);
return (NXGE_ERROR);
/*
* In guest domain, always and only dealing with
* group 0 for an instance of nxge.
*/
/*
* Get the PIO handle.
*/
/*
* If this channel is in the map, then enable
* it.
*/
/*
* Enable the RDC and clear the empty bit.
*/
if (rval != NPI_SUCCESS)
return (NXGE_ERROR);
channel);
}
}
return (NXGE_OK);
}
#endif /* defined(sun4v) */