nxge_fflp.c revision adfcba552dfc70ff685a2e8703fe1761b244f3e8
/*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <npi_fflp.h>
#include <npi_mac.h>
#include <nxge_defs.h>
#include <nxge_flow.h>
#include <nxge_fflp.h>
#include <nxge_impl.h>
#include <nxge_fflp_hash.h>
#include <nxge_common.h>
/*
* Function prototypes
*/
tcam_entry_t *);
tcam_entry_t *);
tcam_entry_t *);
/*
* functions used outside this file
*/
{
(struct tcam_entry *)&tcam_rdptr);
if (status & NPI_FAILURE) {
" nxge_tcam_dump_entry:"
" tcam read failed at location %d ", location));
return (NXGE_ERROR);
}
" key: %llx %llx %llx %llx \n"
" mask: %llx %llx %llx %llx \n"
" ASC RAM %llx \n", location,
return (NXGE_OK);
}
void
{
int *lptr;
int location;
uint32_t start_location = 0;
"nxge_tcam_dump: Invalid location %d \n", location));
return;
}
if (location == -1) {
start_location = 0;
} else {
}
}
/*
* nxge_fflp_vlan_table_invalidate_all
* invalidates the vlan RDC table entries.
* INPUT
* nxge soft state data structure
* Return
* NXGE_OK
* NXGE_ERROR
*
*/
static nxge_status_t
{
if (rs != NPI_SUCCESS) {
"VLAN Table invalidate failed for vlan id %d ",
vlan_id));
return (NXGE_ERROR | rs);
}
}
return (NXGE_OK);
}
/*
* The following functions are used by other modules to init
* the fflp module.
* these functions are the basic API used to init
* the fflp modules (tcam, fcram etc ......)
*
* The TCAM search future would be disabled by default.
*/
static nxge_status_t
{
if (rs != NPI_SUCCESS) {
return (NXGE_ERROR | rs);
}
if (rs != NPI_SUCCESS) {
"failed TCAM Access cfg\n"));
return (NXGE_ERROR | rs);
}
/* disable configurable classes */
/* disable the configurable ethernet classes; */
for (class = TCAM_CLASS_ETYPE_1;
if (rs != NPI_SUCCESS) {
"TCAM USR Ether Class config failed."));
return (NXGE_ERROR | rs);
}
}
/* disable the configurable ip classes; */
for (class = TCAM_CLASS_IP_USER_4;
if (rs != NPI_SUCCESS) {
"TCAM USR IP Class cnfg failed."));
return (NXGE_ERROR | rs);
}
}
return (NXGE_OK);
}
/*
* nxge_fflp_tcam_invalidate_all
* invalidates all the tcam entries.
* INPUT
* nxge soft state data structure
* Return
* NXGE_OK
* NXGE_ERROR
*
*/
static nxge_status_t
{
"==> nxge_fflp_tcam_invalidate_all"));
" nxge_fflp_tcam_invalidate_all:"
return (NXGE_ERROR);
}
if (rs != NPI_SUCCESS) {
"TCAM invalidate failed at loc %d ", location));
return (NXGE_ERROR | rs);
}
}
"<== nxge_fflp_tcam_invalidate_all"));
return (NXGE_OK);
}
/*
* nxge_fflp_fcram_entry_invalidate_all
* invalidates all the FCRAM entries.
* INPUT
* nxge soft state data structure
* Return
* NXGE_OK
* NXGE_ERROR
*
*/
static nxge_status_t
{
/*
* (1) configure and enable partition 0 with no relocation
* (2) Assume the FCRAM is used as IPv4 exact match entry cells
* (3) Invalidate these cells by clearing the valid bit in
* the subareas 0 and 4
* (4) disable the partition
*
*/
if (rs != NPI_SUCCESS) {
return (NXGE_ERROR | rs);
}
if (rs != NPI_SUCCESS) {
"failed partition enable\n"));
return (NXGE_ERROR | rs);
}
fc.hash_hdr_valid = 0;
increment = sizeof (hash_ipv4_t);
if (rs != NPI_SUCCESS) {
"failed write"
"at location %x ",
location));
return (NXGE_ERROR | rs);
}
}
return (NXGE_OK);
}
static nxge_status_t
{
int partition;
/*
* Recommended values are needed.
*/
if (rs != NPI_SUCCESS) {
return (NXGE_ERROR | rs);
}
if (rs != NPI_SUCCESS) {
"configuration \n"));
return (NXGE_ERROR | rs);
}
if (rs != NPI_SUCCESS) {
"failed FCRAM refresh cfg"));
return (NXGE_ERROR);
}
/* disable all the partitions until explicitly enabled */
if (rs != NPI_SUCCESS) {
"failed FCRAM partition"
" enable for partition %d ", partition));
return (NXGE_ERROR | rs);
}
}
return (NXGE_OK);
}
{
" nxge_logical_mac_assign_rdc_table"
" unconfigured alt MAC addr %d ", alt_mac));
return (NXGE_ERROR);
}
if (rs != NPI_SUCCESS) {
"failed Assign RDC table"));
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
{
switch (nxgep->function_num) {
case 0:
case 1:
&mac_rdc);
break;
case 2:
case 3:
&mac_rdc);
break;
default:
"failed Assign RDC table (invalid function #)"));
return (NXGE_ERROR);
}
if (rs != NPI_SUCCESS) {
"failed Assign RDC table"));
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
/*
* Initialize hostinfo registers for alternate MAC addresses and
* multicast MAC address.
*/
{
int i;
switch (nxgep->function_num) {
case 0:
case 1:
/*
* Tests indicate that it is OK not to re-initialize the
* hostinfo registers for the XMAC's alternate MAC
* addresses. But that is necessary for BMAC (case 2
* and case 3 below)
*/
break;
case 2:
case 3:
for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
break;
default:
"failed Assign RDC table (invalid funcion #)"));
return (NXGE_ERROR);
}
if (rs != NPI_SUCCESS) {
"failed Assign RDC table"));
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
{
return (status);
}
{
if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
" failed FCRAM init. "));
return (status);
}
}
"failed TCAM init."));
return (status);
}
if (rs != NPI_SUCCESS) {
"failed LLCSNAP enable. "));
return (NXGE_ERROR | rs);
}
if (rs != NPI_SUCCESS) {
"failed CAM Error Check enable. "));
return (NXGE_ERROR | rs);
}
/* init the hash generators */
if (rs != NPI_SUCCESS) {
"failed H1 Poly Init. "));
return (NXGE_ERROR | rs);
}
if (rs != NPI_SUCCESS) {
"failed H2 Poly Init. "));
return (NXGE_ERROR | rs);
}
/* invalidate TCAM entries */
"failed TCAM Entry Invalidate. "));
return (status);
}
/* invalidate FCRAM entries */
if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
"failed FCRAM Entry Invalidate."));
return (status);
}
}
/* invalidate VLAN RDC tables */
"failed VLAN Table Invalidate. "));
return (status);
}
return (NXGE_OK);
}
{
fcfg.ip_opts_exist = 0;
if (rs & NPI_FFLP_ERROR) {
" opt %x for class %d failed ",
class_config, l3_class));
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
{
if (rs & NPI_FFLP_ERROR) {
" opt %x for class %d failed ",
class_config, l3_class));
return (NXGE_ERROR | rs);
}
if (fcfg.use_portnum)
" nxge_cfg_ip_cls_flow_key_get %x", ccfg));
*class_config = ccfg;
" <== nxge_cfg_ip_cls_flow_key_get"));
return (NXGE_OK);
}
static nxge_status_t
{
if (rs & NPI_FFLP_ERROR) {
" opt %x for class %d failed ",
class_config, class));
return (NXGE_ERROR | rs);
}
if (cfg.lookup_enable)
if (cfg.use_ip_daddr)
*class_config = ccfg;
" ==> nxge_cfg_tcam_ip_class %x", ccfg));
return (NXGE_OK);
}
static nxge_status_t
{
cfg.lookup_enable = 0;
cfg.use_ip_daddr = 0;
if (class_config & NXGE_CLASS_DISCARD)
if (rs & NPI_FFLP_ERROR) {
" opt %x for class %d failed ",
class_config, class));
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
{
if (rs & NPI_FFLP_ERROR) {
" nxge_fflp_init_h1 %x failed ", h1));
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
{
if (rs & NPI_FFLP_ERROR) {
" nxge_fflp_init_h2 %x failed ", h2));
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
{
int alloc_size;
"nxge_classify_init_sw already init"));
return (NXGE_OK);
}
/* Init SW structures */
/* init data structures, based on HW type */
if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
/*
* check if fcram based classification is required and init the
* flow storage
*/
}
/* Init defaults */
/*
* add hacks required for HW shortcomings for example, code to handle
* fragmented packets
*/
return (NXGE_OK);
}
{
int alloc_size;
int fsize;
fsize = sizeof (tcam_flow_spec_t);
if (classify_ptr->tcam_entries) {
}
return (NXGE_OK);
}
/*
* Figures out the location where the TCAM entry is
* to be inserted.
*
* The current implementation is just a place holder and it
* returns the next tcam location.
* The real location determining algorithm would consider
* the priority, partition etc ... before deciding which
* location to insert.
*
*/
/* ARGSUSED */
static tcam_location_t
{
"nxge_get_tcam_location: location %d next %d \n",
return (location);
}
/*
* Figures out the RDC Group for the entry
*
* The current implementation is just a place holder and it
* returns 0.
* The real location determining algorithm would consider
* the partition etc ... before deciding w
*
*/
/* ARGSUSED */
static uint8_t
{
int use_port_rdc_grp = 0;
"nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
return (rdc_grp);
}
/* ARGSUSED */
static uint8_t
{
}
/* ARGSUSED */
static void
{
}
static void
{
} else {
}
}
/* ARGSUSED */
static void
{
}
/* ARGSUSED */
static void
{
}
static void
{
} else {
}
}
static void
{
} else {
}
}
{
int ft_size = sizeof (flow_template_t);
case FSPEC_TCPIP4:
break;
case FSPEC_UDPIP4:
break;
default:
return (NXGE_ERROR);
}
return (NXGE_OK);
}
{
" nxge_add_fcram_entry failed "));
return (status);
}
return (NXGE_OK);
}
/*
* Already decided this flow goes into the tcam
*/
{
tcam_location_t location = 0;
case FSPEC_TCPIP4:
break;
case FSPEC_UDPIP4:
break;
case FSPEC_TCPIP6:
break;
case FSPEC_UDPIP6:
break;
case FSPEC_SCTPIP4:
break;
case FSPEC_SCTPIP6:
break;
default:
return (NXGE_OK);
}
" nxge_add_tcam_entry write"
" nxge_add_tcam_entry: common hardware not set",
return (NXGE_ERROR);
}
if (rs & NPI_FFLP_ERROR) {
" nxge_add_tcam_entry write"
" failed for location %d", location));
return (NXGE_ERROR | rs);
}
if (channel_cookie == -1)
if (rs & NPI_FFLP_ERROR) {
" nxge_add_tcam_entry write"
" failed for ASC RAM location %d", location));
return (NXGE_ERROR | rs);
}
sizeof (tcam_entry_t));
return (NXGE_OK);
}
static nxge_status_t
{
class = 0;
" nxge_tcam_handle_ip_fragment:"
" common hardware not set",
return (NXGE_ERROR);
}
if (rs & NPI_FFLP_ERROR) {
" nxge_tcam_handle_ip_fragment "
" tcam_entry write"
" failed for location %d", location));
return (NXGE_ERROR);
}
if (rs & NPI_FFLP_ERROR) {
" nxge_tcam_handle_ip_fragment "
" tcam_entry write"
" failed for ASC RAM location %d", location));
return (NXGE_ERROR);
}
sizeof (tcam_entry_t));
for (class = TCAM_CLASS_TCP_IPV4;
if (status & NPI_FFLP_ERROR) {
"nxge_tcam_handle_ip_fragment "
"nxge_fflp_ip_class_config failed "
return (NXGE_ERROR);
}
}
if (rs & NPI_FFLP_ERROR) {
"nxge_tcam_handle_ip_fragment "
" nxge_fflp_config_tcam_enable failed"));
return (NXGE_ERROR);
}
return (NXGE_OK);
}
/* ARGSUSED */
static int
{
return (0);
}
{
int insert_hash = 0;
if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
/* determine whether to do TCAM or Hash flow */
}
if (insert_hash) {
} else {
}
return (status);
}
void
{
"nxge_put_tcam addr fs $%p type %x offset %x",
}
{
if (rs & NPI_FFLP_ERROR) {
" nxge_fflp_config_tcam_enable failed"));
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
{
" ==> nxge_fflp_config_tcam_disable"));
if (rs & NPI_FFLP_ERROR) {
" nxge_fflp_config_tcam_disable failed"));
return (NXGE_ERROR | rs);
}
" <== nxge_fflp_config_tcam_disable"));
return (NXGE_OK);
}
{
" ==> nxge_fflp_config_hash_lookup_enable"));
if (rs != NPI_SUCCESS) {
" nxge_fflp_config_hash_lookup_enable"
"failed FCRAM partition"
" enable for partition %d ", partition));
return (NXGE_ERROR | rs);
}
}
" <== nxge_fflp_config_hash_lookup_enable"));
return (NXGE_OK);
}
{
" ==> nxge_fflp_config_hash_lookup_disable"));
if (rs != NPI_SUCCESS) {
" nxge_fflp_config_hash_lookup_disable"
" failed FCRAM partition"
" disable for partition %d ", partition));
return (NXGE_ERROR | rs);
}
}
" <== nxge_fflp_config_hash_lookup_disable"));
return (NXGE_OK);
}
{
" ==> nxge_fflp_config_llc_snap_enable"));
if (rs & NPI_FFLP_ERROR) {
" nxge_fflp_config_llc_snap_enable failed"));
return (NXGE_ERROR | rs);
}
" <== nxge_fflp_config_llc_snap_enable"));
return (NXGE_OK);
}
{
" ==> nxge_fflp_config_llc_snap_disable"));
if (rs & NPI_FFLP_ERROR) {
" nxge_fflp_config_llc_snap_disable failed"));
return (NXGE_ERROR | rs);
}
" <== nxge_fflp_config_llc_snap_disable"));
return (NXGE_OK);
}
{
uint8_t class_enable = 0;
ver = 1;
class_enable = 1;
if (rs & NPI_FFLP_ERROR) {
" nxge_fflp_ip_usr_class_config"
" for class %d failed ", class));
return (NXGE_ERROR | rs);
}
if (class_enable)
else
if (rs & NPI_FFLP_ERROR) {
" nxge_fflp_ip_usr_class_config"
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
{
if (class_config != config) {
}
if (t_status & NPI_FFLP_ERROR) {
" nxge_fflp_ip_class_config %x"
return (t_status);
}
if (f_status & NPI_FFLP_ERROR) {
" nxge_fflp_ip_class_config %x"
return (f_status);
}
return (NXGE_OK);
}
{
t_class_config = f_class_config = 0;
if (t_status & NPI_FFLP_ERROR) {
" nxge_fflp_ip_class_config_get "
" for class %d tcam failed", class));
return (t_status);
}
if (f_status & NPI_FFLP_ERROR) {
" nxge_fflp_ip_class_config_get "
" for class %d flow key failed", class));
return (f_status);
}
" nxge_fflp_ip_class_config tcam %x flow %x",
return (NXGE_OK);
}
{
#ifdef NXGE_DEBUG
#endif
for (class = TCAM_CLASS_TCP_IPV4;
#ifndef NXGE_DEBUG
#else
if (status & NPI_FFLP_ERROR) {
"nxge_fflp_ip_class_config failed "
" class %d config %x ",
class, class_config));
}
#endif
}
return (NXGE_OK);
}
{
" nxge_fflp_config_vlan_table"
" vlan id is not configured %d", vlan_id));
return (NXGE_ERROR);
}
" nxge_fflp_config_vlan_table:"
return (NXGE_ERROR);
}
if (rs & NPI_FFLP_ERROR) {
"nxge_fflp_config_vlan_table failed "
" Port %d vlan_id %d rdc_grp %d",
return (NXGE_ERROR | rs);
}
return (NXGE_OK);
}
{
int i;
int num_macs;
"nxge_fflp_set_hash1 Failed"));
return (NXGE_ERROR);
}
"nxge_fflp_set_hash2 Failed"));
return (NXGE_ERROR);
}
/* configure vlan tables */
#if defined(__i386)
#else
#endif
for (i = 0; i < cfgd_vlans; i++) {
"nxge_fflp_config_vlan_table Failed"));
return (NXGE_ERROR);
}
}
}
/* config MAC addresses */
#if defined(__i386)
#else
#endif
alt_mac);
"nxge_logical_mac_assign_rdc_table"
" Failed"));
return (NXGE_ERROR);
}
}
}
/* Config Hash values */
/* config classess */
"nxge_fflp_ip_class_config_all Failed"));
return (NXGE_ERROR);
}
return (NXGE_OK);
}
{
"nxge_classify_init_hw already init"));
return (NXGE_OK);
}
/* Now do a real configuration */
"nxge_fflp_update_hw failed"));
return (NXGE_ERROR);
}
/* Init RDC tables? ? who should do that? rxdma or fflp ? */
/* attach rdc table to the MAC port. */
"nxge_main_mac_assign_rdc_table failed"));
return (NXGE_ERROR);
}
"nxge_multicast_mac_assign_rdc_table failed"));
return (NXGE_ERROR);
}
"nxge_tcam_handle_ip_fragment failed"));
return (NXGE_ERROR);
}
return (NXGE_OK);
}
{
/*
* need to read the fflp error registers to figure out what the error
* is
*/
" vlan table parity error on port %d"
" addr: 0x%x data: 0x%x",
" vlan table multiple errors on port %d",
portn));
}
}
" TCAM ECC error on port %d"
" TCAM entry: 0x%x syndrome: 0x%x",
statsp->tcam_ecc_err++;
} else {
" TCAM Parity error on port %d"
" addr: 0x%x parity value: 0x%x",
}
" TCAM Multiple errors on port %d", portn));
} else {
" TCAM PIO error on port %d",
portn));
}
}
" FCRAM PIO ECC error on port %d"
" rdc group: %d Hash Table addr: 0x%x"
" syndrome: 0x%x",
}
}
char *multi_str = "";
char *multi_bit_str = "";
multi_str = "multiple";
}
multi_bit_str = "multiple bits";
}
" FCRAM %s lookup %s ECC error on port %d"
" H1: 0x%x Subarea: 0x%x Syndrome: 0x%x",
}
return (NXGE_OK);
}