hxge_virtual.c revision dc10a9c2a5a49452cc30c6a110b64e5e074e37b3
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <hxge_impl.h>
#include <hxge_vmac.h>
#include <hxge_pfc.h>
#include <hpi_pfc.h>
static void hxge_use_cfg_hydra_properties(p_hxge_t);
static void hxge_use_cfg_dma_config(p_hxge_t);
static void hxge_use_cfg_class_config(p_hxge_t);
static void hxge_set_hw_dma_config(p_hxge_t);
static void hxge_set_hw_class_config(p_hxge_t);
extern uint16_t hxge_rcr_timeout;
extern uint16_t hxge_rcr_threshold;
extern uint32_t hxge_rbr_size;
extern uint32_t hxge_rcr_size;
extern uint_t hxge_rx_intr();
extern uint_t hxge_tx_intr();
extern uint_t hxge_vmac_intr();
extern uint_t hxge_syserr_intr();
extern uint_t hxge_pfc_intr();
/*
* Entry point to populate configuration parameters into the master hxge
* data structure and to update the NDD parameter list.
*/
{
" hxge_get_config_properties: common hardware not set"));
return (HXGE_ERROR);
}
" hxge_get_config_properties: mac addr properties failed"));
return (status);
}
" ==> hxge_get_config_properties: Hydra"));
return (HXGE_OK);
}
static void
{
int i;
int *vlan_cfg_val;
char *prop;
int good_count = 0;
/*
* uint32_t array, each array entry specifying a VLAN id
*/
for (i = 0; i <= VLAN_ID_MAX; i++) {
}
return;
}
for (i = 0; i < vlan_cnt; i++) {
good_count++;
}
}
if (good_count != vlan_cnt) {
}
}
/*
* Read param_vlan_ids and param_implicit_vlan_id properties from either
* hxge.conf or OBP. Update the soft properties. Populate these
* properties into the hxge data structure.
*/
static void
{
int *vlan_cfg_val;
int status;
char *prop;
uint32_t implicit_vlan_id = 0;
int *int_prop_val;
&vlan_cfg_val, &vlan_cnt);
if (status == DDI_PROP_SUCCESS) {
}
prop, (int)implicit_vlan_id);
}
}
}
/*
* Read in the configuration parameters from either hxge.conf or OBP and
* populate the master data structure hxge.
* Use these parameters to update the soft properties and the ndd array.
*/
static void
{
(void) hxge_use_cfg_dma_config(hxgep);
(void) hxge_use_cfg_vlan_class_config(hxgep);
(void) hxge_use_cfg_class_config(hxgep);
/*
* Read in the hardware (fcode) properties and use these properties
* to update the ndd array.
*/
(void) hxge_get_param_soft_properties(hxgep);
}
/*
* Read param_accept_jumbo, param_rxdma_intr_time, and param_rxdma_intr_pkts
* from either hxge.conf or OBP.
* Update the soft properties.
* Populate these properties into the hxge data structure for latter use.
*/
static void
{
char *prop;
int *prop_val;
tx_ndmas = 4;
"p_cfgp 0x%llx max_tdcs %d hxgep->max_tdcs %d",
rx_ndmas = 4;
"p_cfgp 0x%llx max_rdcs %d hxgep->max_rdcs %d",
"p_cfgp 0x%016llx start_ldg %d hxgep->max_ldgs %d ",
/*
* add code for individual rdc properties
*/
}
}
}
}
}
}
}
static void
{
}
static void
{
/* Transmit DMA Channels */
/* Receive DMA Channels */
}
{
/* Receive DMA Channels */
return (status);
}
{
/* Receive DMA Channels */
return (status);
}
/*
* Read the L2 classes, L3 classes, and initial hash from either hxge.conf
* or OBP. Populate these properties into the hxge data structure for latter
* use. Note that we are not updating these soft properties.
*/
static void
{
int i, j;
int *int_prop_val;
char *prop;
int start_prop, end_prop;
/*
* L2 class configuration. User configurable ether types
*/
for (i = start_prop; i <= end_prop; i++) {
} else {
}
j = (i - start_prop) + TCAM_CLASS_ETYPE_1;
}
/*
* Use properties from either .conf or the NDD param array. Only bits
* 2 and 3 are significant
*/
for (i = start_prop; i <= end_prop; i++) {
} else {
}
j = (i - start_prop) + TCAM_CLASS_TCP_IPV4;
}
} else {
}
}
/*
* Interrupts related interface functions.
*/
{
if (!*navail_p) {
*nrequired_p = 0;
"<== hxge_ldgv_init:no avail"));
return (HXGE_ERROR);
}
/* each DMA channels */
/* vmac */
nldvs++;
/* pfc */
nldvs++;
/* nmac for the link status register only */
nldvs++;
/* system error interrupts. */
nldvs++;
/* No devices configured. */
"no logical devices or groups configured."));
return (HXGE_ERROR);
}
}
"==> hxge_ldgv_init: maxldvs %d maxldgs %d nldvs %d",
for (i = 0; i < maxldgs; i++) {
ptr->vldg_index = i;
"==> hxge_ldgv_init: maxldvs %d maxldgs %d ldg %d",
ptr++;
}
} else {
}
/*
* Receive DMA channels.
*/
nldvs = 0;
*nrequired_p = 0;
/*
* Start with RDC to configure logical devices for each group.
*/
/*
* If non-seq needs to change the following code
*/
ldvp->vdma_index = i;
ldvp->ldv_ldf_masks = 0;
nldvs++;
}
/*
* Transmit DMA channels.
*/
ldvp->vdma_index = i;
ldvp->ldv_ldf_masks = 0;
nldvs++;
}
/*
* VMAC
*/
ldvp->ldv_ldf_masks = 0;
ldv = HXGE_VMAC_LD;
nldvs++;
"==> hxge_ldgv_init: nldvs %d navail %d nrequired %d",
/*
* PFC
*/
ldvp->ldv_ldf_masks = 0;
ldv = HXGE_PFC_LD;
nldvs++;
"==> hxge_ldgv_init: nldvs %d navail %d nrequired %d",
/*
* NMAC
*/
ldvp->ldv_ldf_masks = 0;
ldv = HXGE_NMAC_LD;
nldvs++;
"==> hxge_ldgv_init: nldvs %d navail %d nrequired %d",
/*
* System error interrupts.
*/
ldvp->ldv_ldf_masks = 0;
/* Reset PEU error mask to allow PEU error interrupts */
/*
* Unmask the system interrupt states.
*/
nldvs++;
"==> hxge_ldgv_init: nldvs %d navail %d nrequired %d",
return (status);
}
{
"<== hxge_ldgv_uninit: no logical group configured."));
return (HXGE_OK);
}
}
}
return (HXGE_OK);
}
{
/*
* Configure the logical device group numbers, state vectors
* and interrupt masks for each logical device.
*/
/*
* Configure logical device masks and timers.
*/
return (status);
}
{
int i, j;
"<== hxge_intr_mask_mgmt: Null ldgvp"));
return (HXGE_ERROR);
}
"<== hxge_intr_mask_mgmt: Null ldgp or ldvp"));
return (HXGE_ERROR);
}
/* Initialize masks. */
"==> hxge_intr_mask_mgmt(Hydra): # ldv %d in group %d",
"==> hxge_intr_mask_mgmt: set ldv # %d "
if (rs != HPI_SUCCESS) {
"<== hxge_intr_mask_mgmt: set mask failed "
" rs 0x%x ldv %d mask 0x%x",
return (HXGE_ERROR | rs);
}
"==> hxge_intr_mask_mgmt: set mask OK "
" rs 0x%x ldv %d mask 0x%x",
}
}
/* Configure timer and arm bit */
if (rs != HPI_SUCCESS) {
"<== hxge_intr_mask_mgmt: set timer failed "
" rs 0x%x dg %d timer 0x%x",
return (HXGE_ERROR | rs);
}
"==> hxge_intr_mask_mgmt: set timer OK "
" rs 0x%x ldg %d timer 0x%x",
}
return (HXGE_OK);
}
{
int i, j;
"==> hxge_intr_mask_mgmt_set (%d)", on));
"==> hxge_intr_mask_mgmt_set: Null ldgvp"));
return (HXGE_ERROR);
}
"<== hxge_intr_mask_mgmt_set: Null ldgp or ldvp"));
return (HXGE_ERROR);
}
/* set masks. */
"==> hxge_intr_mask_mgmt_set: flag %d ldg %d"
"==> hxge_intr_mask_mgmt_set: "
"for %d %d flag %d", i, j, on));
if (on) {
ldvp->ldv_ldf_masks = 0;
"==> hxge_intr_mask_mgmt_set: "
"ON mask off"));
} else {
"==> hxge_intr_mask_mgmt_set:mask on"));
}
/*
* Bringup - NMAC constantly interrupts since hydrad
* is not available yet. When hydrad is available
* and handles the interrupts, we will delete the
* following two lines
*/
if (rs != HPI_SUCCESS) {
"==> hxge_intr_mask_mgmt_set: "
"set mask failed rs 0x%x ldv %d mask 0x%x",
return (HXGE_ERROR | rs);
}
"==> hxge_intr_mask_mgmt_set: flag %d"
"set mask OK ldv %d mask 0x%x",
}
}
/* set the arm bit */
}
if (rs != HPI_SUCCESS) {
"<== hxge_intr_mask_mgmt_set: "
"set timer failed rs 0x%x ldg %d timer 0x%x",
return (HXGE_ERROR | rs);
}
"==> hxge_intr_mask_mgmt_set: OK (flag %d) "
"set timer ldg %d timer 0x%x",
}
return (HXGE_OK);
}
/*
* For Big Endian systems, the mac address will be from OBP. For Little
* Endian (x64) systems, it will be retrieved from the card since it cannot
* be programmed into PXE.
* This function also populates the MMAC parameters.
*/
static hxge_status_t
{
(void) hxge_pfc_mac_addrs_get(hxgep);
/*
* Get the number of MAC addresses the Hydra supports per blade.
*/
} else {
"hxge_get_mac_addr_properties: get macs failed"));
return (HXGE_ERROR);
}
/*
* Initialize alt. mac addr. in the mac pool
*/
"hxge_get_mac_addr_properties: init mmac failed"));
return (HXGE_ERROR);
}
return (HXGE_OK);
}
static void
{
/* Assign the group number for each device. */
"==> hxge_ldgv_setup: ldv %d endldg %d ldg %d, ldvp $%p",
*ngrps += 1;
"==> hxge_ldgv_setup: ngrps %d", *ngrps));
}
"==> hxge_ldgv_setup: ldvp $%p ngrps %d",
++*ldvp;
} else {
*ngrps += 1;
"ldv %d endldg %d ldg %d, ldvp $%p",
"==> hxge_ldgv_setup: new ngrps %d", *ngrps));
}
"ldg %d nldvs %d ldv %d ldvp $%p endldg %d ngrps %d",
}
/*
* Note: This function assumes the following distribution of mac
* addresses for a hydra blade:
*
* -------------
* 0| |0 - local-mac-address for blade
* -------------
* | |1 - Start of alt. mac addr. for blade
* | |
* | |
* | |15
* --------------
*/
static hxge_status_t
{
int slot;
/* Set flags for unique MAC */
/*
* Initialze all other mac addr. to "AVAILABLE" state.
* Clear flags of all alternate MAC slots.
*/
}
/* Exclude the factory mac address */
/* Initialize the first two parameters for mmac kstat */
return (HXGE_OK);
}
/*ARGSUSED*/
{
} else {
}
return (DDI_INTR_CLAIMED);
}