#include <npi_fflp.h>
#include <nxge_common.h>
#define GET_TCAM_CLASS_OFFSET(cls) \
(FFLP_TCAM_CLS_BASE_OFFSET + (cls - 2) * 8)
#define GET_TCAM_KEY_OFFSET(cls) \
(FFLP_TCAM_KEY_BASE_OFFSET + (cls - 4) * 8)
#define GET_FLOW_KEY_OFFSET(cls) \
(FFLP_FLOW_KEY_BASE_OFFSET + (cls - 4) * 8)
#define HASHTBL_PART_REG_STEP 8192
#define HASHTBL_PART_REG_VIR_OFFSET 0x2100
#define HASHTBL_PART_REG_VIR_STEP 0x4000
#define GET_HASHTBL_PART_OFFSET_NVIR(partid, reg) \
((partid * HASHTBL_PART_REG_STEP) + reg)
#define GET_HASHTBL_PART_OFFSET(handle, partid, reg) \
(handle.is_vraddr ? \
(((partid & 0x1) * HASHTBL_PART_REG_VIR_STEP) + \
(reg & 0x8) + (HASHTBL_PART_REG_VIR_OFFSET)) : \
(partid * HASHTBL_PART_REG_STEP) + reg)
#define FFLP_PART_OFFSET(partid, reg) ((partid * 8) + reg)
#define FFLP_VLAN_OFFSET(vid, reg) ((vid * 8) + reg)
#define TCAM_COMPLETION_TRY_COUNT 10
#define BIT_ENABLE 0x1
#define BIT_DISABLE 0x0
#define FCRAM_PARTITION_VALID(partid) \
((partid < NXGE_MAX_RDC_GRPS))
#define FFLP_VLAN_VALID(vid) \
((vid > 0) && (vid < NXGE_MAX_VLANS))
#define FFLP_PORT_VALID(port) \
((port < MAX_PORTS_PER_NXGE))
#define FFLP_RDC_TABLE_VALID(table) \
((table < NXGE_MAX_RDC_GRPS))
#define TCAM_L3_USR_CLASS_VALID(class) \
((class >= TCAM_CLASS_IP_USER_4) && (class <= TCAM_CLASS_IP_USER_7))
#define TCAM_L2_USR_CLASS_VALID(class) \
((class == TCAM_CLASS_ETYPE_1) || (class == TCAM_CLASS_ETYPE_2))
#define TCAM_L3_CLASS_VALID(class) \
((class >= TCAM_CLASS_IP_USER_4) && (class <= TCAM_CLASS_SCTP_IPV6))
#define TCAM_L3_CLASS_VALID_RFNL(class) \
((TCAM_L3_CLASS_VALID(class)) || class == TCAM_CLASS_IPV6_FRAG)
#define TCAM_CLASS_VALID(class) \
((class >= TCAM_CLASS_ETYPE_1) && (class <= TCAM_CLASS_RARP))
uint64_t fflp_fzc_offset[] = {
FFLP_ENET_VLAN_TBL_REG, FFLP_L2_CLS_ENET1_REG, FFLP_L2_CLS_ENET2_REG,
FFLP_TCAM_KEY_IP_USR4_REG, FFLP_TCAM_KEY_IP_USR5_REG,
FFLP_TCAM_KEY_IP_USR6_REG, FFLP_TCAM_KEY_IP_USR7_REG,
FFLP_TCAM_KEY_IP4_TCP_REG, FFLP_TCAM_KEY_IP4_UDP_REG,
FFLP_TCAM_KEY_IP4_AH_ESP_REG, FFLP_TCAM_KEY_IP4_SCTP_REG,
FFLP_TCAM_KEY_IP6_TCP_REG, FFLP_TCAM_KEY_IP6_UDP_REG,
FFLP_TCAM_KEY_IP6_AH_ESP_REG, FFLP_TCAM_KEY_IP6_SCTP_REG,
FFLP_TCAM_KEY_0_REG, FFLP_TCAM_KEY_1_REG, FFLP_TCAM_KEY_2_REG,
FFLP_TCAM_KEY_3_REG, FFLP_TCAM_MASK_0_REG, FFLP_TCAM_MASK_1_REG,
FFLP_TCAM_MASK_2_REG, FFLP_TCAM_MASK_3_REG, FFLP_TCAM_CTL_REG,
FFLP_VLAN_PAR_ERR_REG, FFLP_TCAM_ERR_REG, HASH_LKUP_ERR_LOG1_REG,
HASH_LKUP_ERR_LOG2_REG, FFLP_FCRAM_ERR_TST0_REG,
FFLP_FCRAM_ERR_TST1_REG, FFLP_FCRAM_ERR_TST2_REG, FFLP_ERR_MSK_REG,
FFLP_CFG_1_REG, FFLP_DBG_TRAIN_VCT_REG, FFLP_TCP_CFLAG_MSK_REG,
FFLP_FCRAM_REF_TMR_REG, FFLP_FLOW_KEY_IP_USR4_REG,
FFLP_FLOW_KEY_IP_USR5_REG, FFLP_FLOW_KEY_IP_USR6_REG,
FFLP_FLOW_KEY_IP_USR7_REG, FFLP_FLOW_KEY_IP4_TCP_REG,
FFLP_FLOW_KEY_IP4_UDP_REG, FFLP_FLOW_KEY_IP4_AH_ESP_REG,
FFLP_FLOW_KEY_IP4_SCTP_REG, FFLP_FLOW_KEY_IP6_TCP_REG,
FFLP_FLOW_KEY_IP6_UDP_REG, FFLP_FLOW_KEY_IP6_AH_ESP_REG,
FFLP_FLOW_KEY_IP6_SCTP_REG, FFLP_H1POLY_REG, FFLP_H2POLY_REG,
FFLP_FLW_PRT_SEL_REG
};
const char *fflp_fzc_name[] = {
"FFLP_ENET_VLAN_TBL_REG", "FFLP_L2_CLS_ENET1_REG",
"FFLP_L2_CLS_ENET2_REG", "FFLP_TCAM_KEY_IP_USR4_REG",
"FFLP_TCAM_KEY_IP_USR5_REG", "FFLP_TCAM_KEY_IP_USR6_REG",
"FFLP_TCAM_KEY_IP_USR7_REG", "FFLP_TCAM_KEY_IP4_TCP_REG",
"FFLP_TCAM_KEY_IP4_UDP_REG", "FFLP_TCAM_KEY_IP4_AH_ESP_REG",
"FFLP_TCAM_KEY_IP4_SCTP_REG", "FFLP_TCAM_KEY_IP6_TCP_REG",
"FFLP_TCAM_KEY_IP6_UDP_REG", "FFLP_TCAM_KEY_IP6_AH_ESP_REG",
"FFLP_TCAM_KEY_IP6_SCTP_REG", "FFLP_TCAM_KEY_0_REG",
"FFLP_TCAM_KEY_1_REG", "FFLP_TCAM_KEY_2_REG", "FFLP_TCAM_KEY_3_REG",
"FFLP_TCAM_MASK_0_REG", "FFLP_TCAM_MASK_1_REG", "FFLP_TCAM_MASK_2_REG",
"FFLP_TCAM_MASK_3_REG", "FFLP_TCAM_CTL_REG", "FFLP_VLAN_PAR_ERR_REG",
"FFLP_TCAM_ERR_REG", "HASH_LKUP_ERR_LOG1_REG",
"HASH_LKUP_ERR_LOG2_REG", "FFLP_FCRAM_ERR_TST0_REG",
"FFLP_FCRAM_ERR_TST1_REG", "FFLP_FCRAM_ERR_TST2_REG",
"FFLP_ERR_MSK_REG", "FFLP_CFG_1_REG", "FFLP_DBG_TRAIN_VCT_REG",
"FFLP_TCP_CFLAG_MSK_REG", "FFLP_FCRAM_REF_TMR_REG",
"FFLP_FLOW_KEY_IP_USR4_REG", "FFLP_FLOW_KEY_IP_USR5_REG",
"FFLP_FLOW_KEY_IP_USR6_REG", "FFLP_FLOW_KEY_IP_USR7_REG",
"FFLP_FLOW_KEY_IP4_TCP_REG", "FFLP_FLOW_KEY_IP4_UDP_REG",
"FFLP_FLOW_KEY_IP4_AH_ESP_REG", "FFLP_FLOW_KEY_IP4_SCTP_REG",
"FFLP_FLOW_KEY_IP6_TCP_REG", "FFLP_FLOW_KEY_IP6_UDP_REG",
"FFLP_FLOW_KEY_IP6_AH_ESP_REG",
"FFLP_FLOW_KEY_IP6_SCTP_REG", "FFLP_H1POLY_REG", "FFLP_H2POLY_REG",
"FFLP_FLW_PRT_SEL_REG"
};
uint64_t fflp_reg_offset[] = {
FFLP_HASH_TBL_ADDR_REG, FFLP_HASH_TBL_DATA_REG,
FFLP_HASH_TBL_DATA_LOG_REG
};
const char *fflp_reg_name[] = {
"FFLP_HASH_TBL_ADDR_REG", "FFLP_HASH_TBL_DATA_REG",
"FFLP_HASH_TBL_DATA_LOG_REG"
};
npi_status_t
npi_fflp_dump_regs(npi_handle_t handle)
{
uint64_t value;
int num_regs, i;
num_regs = sizeof (fflp_fzc_offset) / sizeof (uint64_t);
NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
"\nFFLP_FZC Register Dump \n"));
for (i = 0; i < num_regs; i++) {
REG_PIO_READ64(handle, fflp_fzc_offset[i], &value);
NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
" %8llx %s\t %8llx \n",
fflp_fzc_offset[i], fflp_fzc_name[i], value));
}
NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
"\nFFLP Register Dump\n"));
num_regs = sizeof (fflp_reg_offset) / sizeof (uint64_t);
for (i = 0; i < num_regs; i++) {
REG_PIO_READ64(handle, fflp_reg_offset[i], &value);
NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
" %8llx %s\t %8llx \n",
fflp_reg_offset[i], fflp_reg_name[i], value));
}
NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
"\n FFLP Register Dump done\n"));
return (NPI_SUCCESS);
}
void
npi_fflp_vlan_tbl_dump(npi_handle_t handle)
{
uint64_t offset;
vlan_id_t vlan_id;
uint64_t value;
vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
"\nVlan Table Dump \n"));
NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
"VID\t Offset\t Value\n"));
for (vlan_id = start; vlan_id < stop; vlan_id++) {
offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
REG_PIO_READ64(handle, offset, &value);
NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
"%x\t %llx\t %llx\n", vlan_id, offset, value));
}
}
static uint64_t
npi_fflp_tcam_check_completion(npi_handle_t handle, tcam_op_t op_type);
static uint64_t
npi_fflp_tcam_check_completion(npi_handle_t handle, tcam_op_t op_type)
{
uint32_t try_counter, tcam_delay = 10;
tcam_ctl_t tctl;
try_counter = TCAM_COMPLETION_TRY_COUNT;
switch (op_type) {
case TCAM_RWC_STAT:
READ_TCAM_REG_CTL(handle, &tctl.value);
while ((try_counter) &&
(tctl.bits.ldw.stat != TCAM_CTL_RWC_RWC_STAT)) {
try_counter--;
NXGE_DELAY(tcam_delay);
READ_TCAM_REG_CTL(handle, &tctl.value);
}
if (!try_counter) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" TCAM RWC_STAT operation"
" failed to complete \n"));
return (NPI_FFLP_TCAM_HW_ERROR);
}
tctl.value = 0;
break;
case TCAM_RWC_MATCH:
READ_TCAM_REG_CTL(handle, &tctl.value);
while ((try_counter) &&
(tctl.bits.ldw.match != TCAM_CTL_RWC_RWC_MATCH)) {
try_counter--;
NXGE_DELAY(tcam_delay);
READ_TCAM_REG_CTL(handle, &tctl.value);
}
if (!try_counter) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" TCAM Match operation"
"failed to find match \n"));
tctl.value = NPI_TCAM_COMP_NO_MATCH;
}
break;
default:
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" Invalid TCAM completion Request \n"));
return (NPI_FFLP_ERROR |
NPI_TCAM_ERROR | OPCODE_INVALID);
}
return (tctl.value);
}
npi_status_t
npi_fflp_tcam_entry_invalidate(npi_handle_t handle, tcam_location_t location)
{
tcam_ctl_t tctl, tctl_stat;
WRITE_TCAM_REG_MASK0(handle, 0xffULL);
WRITE_TCAM_REG_KEY0(handle, 0x0ULL);
tctl.value = 0;
tctl.bits.ldw.location = location;
tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_WR;
WRITE_TCAM_REG_CTL(handle, tctl.value);
tctl_stat.value = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
if (tctl_stat.value & NPI_FAILURE)
return (NPI_FFLP_TCAM_HW_ERROR);
return (NPI_SUCCESS);
}
int
npi_fflp_tcam_entry_match(npi_handle_t handle, tcam_entry_t *tcam_ptr)
{
uint64_t tcam_stat = 0;
tcam_ctl_t tctl, tctl_stat;
WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0);
WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1);
WRITE_TCAM_REG_MASK2(handle, tcam_ptr->mask2);
WRITE_TCAM_REG_MASK3(handle, tcam_ptr->mask3);
WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0);
WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1);
WRITE_TCAM_REG_KEY2(handle, tcam_ptr->key2);
WRITE_TCAM_REG_KEY3(handle, tcam_ptr->key3);
tctl.value = 0;
tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_CMP;
WRITE_TCAM_REG_CTL(handle, tctl.value);
tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
if (tcam_stat & NPI_FAILURE) {
return ((uint32_t)tcam_stat);
}
tctl_stat.value = npi_fflp_tcam_check_completion(handle,
TCAM_RWC_MATCH);
if (tctl_stat.bits.ldw.match == TCAM_CTL_RWC_RWC_MATCH) {
return (uint32_t)(tctl_stat.bits.ldw.location);
}
return ((uint32_t)tctl_stat.value);
}
npi_status_t
npi_fflp_tcam_entry_read(npi_handle_t handle,
tcam_location_t location,
struct tcam_entry *tcam_ptr)
{
uint64_t tcam_stat;
tcam_ctl_t tctl;
tctl.value = 0;
tctl.bits.ldw.location = location;
tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_RD;
WRITE_TCAM_REG_CTL(handle, tctl.value);
tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
if (tcam_stat & NPI_FAILURE) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
"TCAM read failed loc %d \n", location));
return (NPI_FFLP_TCAM_RD_ERROR);
}
READ_TCAM_REG_MASK0(handle, &tcam_ptr->mask0);
READ_TCAM_REG_MASK1(handle, &tcam_ptr->mask1);
READ_TCAM_REG_MASK2(handle, &tcam_ptr->mask2);
READ_TCAM_REG_MASK3(handle, &tcam_ptr->mask3);
READ_TCAM_REG_KEY0(handle, &tcam_ptr->key0);
READ_TCAM_REG_KEY1(handle, &tcam_ptr->key1);
READ_TCAM_REG_KEY2(handle, &tcam_ptr->key2);
READ_TCAM_REG_KEY3(handle, &tcam_ptr->key3);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_tcam_entry_write(npi_handle_t handle,
tcam_location_t location,
tcam_entry_t *tcam_ptr)
{
uint64_t tcam_stat;
tcam_ctl_t tctl;
WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0);
WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1);
WRITE_TCAM_REG_MASK2(handle, tcam_ptr->mask2);
WRITE_TCAM_REG_MASK3(handle, tcam_ptr->mask3);
WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0);
WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1);
WRITE_TCAM_REG_KEY2(handle, tcam_ptr->key2);
WRITE_TCAM_REG_KEY3(handle, tcam_ptr->key3);
NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
" tcam write: location %x\n"
" key: %llx %llx %llx %llx \n"
" mask: %llx %llx %llx %llx \n",
location, tcam_ptr->key0, tcam_ptr->key1,
tcam_ptr->key2, tcam_ptr->key3,
tcam_ptr->mask0, tcam_ptr->mask1,
tcam_ptr->mask2, tcam_ptr->mask3));
tctl.value = 0;
tctl.bits.ldw.location = location;
tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_WR;
NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
" tcam write: ctl value %llx \n", tctl.value));
WRITE_TCAM_REG_CTL(handle, tctl.value);
tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
if (tcam_stat & NPI_FAILURE) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
"TCAM Write failed loc %d \n", location));
return (NPI_FFLP_TCAM_WR_ERROR);
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_tcam_asc_ram_entry_write(npi_handle_t handle,
tcam_location_t location,
uint64_t ram_data)
{
uint64_t tcam_stat = 0;
tcam_ctl_t tctl;
WRITE_TCAM_REG_KEY1(handle, ram_data);
tctl.value = 0;
tctl.bits.ldw.location = location;
tctl.bits.ldw.rwc = TCAM_CTL_RWC_RAM_WR;
NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
" tcam ascr write: location %x data %llx ctl value %llx \n",
location, ram_data, tctl.value));
WRITE_TCAM_REG_CTL(handle, tctl.value);
tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
if (tcam_stat & NPI_FAILURE) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
"TCAM RAM write failed loc %d \n", location));
return (NPI_FFLP_ASC_RAM_WR_ERROR);
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_tcam_asc_ram_entry_read(npi_handle_t handle,
tcam_location_t location,
uint64_t *ram_data)
{
uint64_t tcam_stat;
tcam_ctl_t tctl;
tctl.value = 0;
tctl.bits.ldw.location = location;
tctl.bits.ldw.rwc = TCAM_CTL_RWC_RAM_RD;
WRITE_TCAM_REG_CTL(handle, tctl.value);
tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
if (tcam_stat & NPI_FAILURE) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
"TCAM RAM read failed loc %d \n", location));
return (NPI_FFLP_ASC_RAM_RD_ERROR);
}
READ_TCAM_REG_KEY1(handle, ram_data);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_entry_write(npi_handle_t handle, part_id_t partid,
uint32_t location, fcram_entry_t *fcram_ptr,
fcram_entry_format_t format)
{
int num_subareas = 0;
uint64_t addr_reg, data_reg;
int subarea;
int autoinc;
hash_tbl_addr_t addr;
switch (format) {
case FCRAM_ENTRY_OPTIM:
if (location % 8) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" FCRAM_ENTRY_OOPTIM Write:"
" unaligned location %llx \n",
location));
return (NPI_FFLP_FCRAM_LOC_INVALID);
}
num_subareas = 1;
autoinc = 0;
break;
case FCRAM_ENTRY_EX_IP4:
if (location % 32) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" FCRAM_ENTRY_EX_IP4 Write:"
" unaligned location %llx \n",
location));
return (NPI_FFLP_FCRAM_LOC_INVALID);
}
num_subareas = 4;
autoinc = 1;
break;
case FCRAM_ENTRY_EX_IP6:
if (location % 64) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" FCRAM_ENTRY_EX_IP6 Write:"
" unaligned location %llx \n",
location));
return (NPI_FFLP_FCRAM_LOC_INVALID);
}
num_subareas = 7;
autoinc = 1;
break;
default:
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fcram_entry_write:"
" unknown format param location %llx\n",
location));
return (NPI_FFLP_ERROR | NPI_FCRAM_ERROR | OPCODE_INVALID);
}
addr.value = 0;
addr.bits.ldw.autoinc = autoinc;
addr.bits.ldw.addr = location;
addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_ADDR_REG);
data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_DATA_REG);
REG_PIO_WRITE64(handle, addr_reg, addr.value);
for (subarea = 0; subarea < num_subareas; subarea++) {
REG_PIO_WRITE64(handle, data_reg, fcram_ptr->value[subarea]);
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_entry_read(npi_handle_t handle, part_id_t partid,
uint32_t location, fcram_entry_t *fcram_ptr,
fcram_entry_format_t format)
{
int num_subareas = 0;
uint64_t addr_reg, data_reg;
int subarea, autoinc;
hash_tbl_addr_t addr;
switch (format) {
case FCRAM_ENTRY_OPTIM:
if (location % 8) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" FCRAM_ENTRY_OOPTIM Read:"
" unaligned location %llx \n",
location));
return (NPI_FFLP_FCRAM_LOC_INVALID);
}
num_subareas = 1;
autoinc = 0;
break;
case FCRAM_ENTRY_EX_IP4:
if (location % 32) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" FCRAM_ENTRY_EX_IP4 READ:"
" unaligned location %llx \n",
location));
return (NPI_FFLP_FCRAM_LOC_INVALID);
}
num_subareas = 4;
autoinc = 1;
break;
case FCRAM_ENTRY_EX_IP6:
if (location % 64) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" FCRAM_ENTRY_EX_IP6 READ:"
" unaligned location %llx \n",
location));
return (NPI_FFLP_FCRAM_LOC_INVALID);
}
num_subareas = 7;
autoinc = 1;
break;
default:
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fcram_entry_read:"
" unknown format param location %llx\n",
location));
return (NPI_FFLP_SW_PARAM_ERROR);
}
addr.value = 0;
addr.bits.ldw.autoinc = autoinc;
addr.bits.ldw.addr = location;
addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_ADDR_REG);
data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_DATA_REG);
REG_PIO_WRITE64(handle, addr_reg, addr.value);
for (subarea = 0; subarea < num_subareas; subarea++) {
REG_PIO_READ64(handle, data_reg, &fcram_ptr->value[subarea]);
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_entry_invalidate(npi_handle_t handle, part_id_t partid,
uint32_t location)
{
hash_tbl_addr_t addr;
uint64_t addr_reg, data_reg;
hash_hdr_t hdr;
if (location % 8) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" FCRAM_ENTRY_Invalidate:"
" unaligned location %llx \n",
location));
return (NPI_FFLP_FCRAM_LOC_INVALID);
}
addr.value = 0;
addr.bits.ldw.addr = location;
addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_ADDR_REG);
data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_DATA_REG);
REG_PIO_WRITE64(handle, addr_reg, addr.value);
REG_PIO_READ64(handle, data_reg, &hdr.value);
hdr.exact_hdr.valid = 0;
REG_PIO_WRITE64(handle, data_reg, hdr.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_subarea_write(npi_handle_t handle, part_id_t partid,
uint32_t location, uint64_t data)
{
hash_tbl_addr_t addr;
uint64_t addr_reg, data_reg;
if (location % 8) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fcram_subarea_write:"
" unaligned location %llx \n",
location));
return (NPI_FFLP_FCRAM_LOC_INVALID);
}
addr.value = 0;
addr.bits.ldw.addr = location;
addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_ADDR_REG);
data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_DATA_REG);
REG_PIO_WRITE64(handle, addr_reg, addr.value);
REG_PIO_WRITE64(handle, data_reg, data);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_subarea_read(npi_handle_t handle, part_id_t partid,
uint32_t location, uint64_t *data)
{
hash_tbl_addr_t addr;
uint64_t addr_reg, data_reg;
if (location % 8) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fcram_subarea_read:"
" unaligned location %llx \n",
location));
return (NPI_FFLP_FCRAM_LOC_INVALID);
}
addr.value = 0;
addr.bits.ldw.addr = location;
addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_ADDR_REG);
data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
FFLP_HASH_TBL_DATA_REG);
REG_PIO_WRITE64(handle, addr_reg, addr.value);
REG_PIO_READ64(handle, data_reg, data);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_fcram_partition(npi_handle_t handle, part_id_t partid,
uint8_t base_mask, uint8_t base_reloc)
{
flow_prt_sel_t sel;
uint64_t offset;
ASSERT(FCRAM_PARTITION_VALID(partid));
if (!FCRAM_PARTITION_VALID(partid)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_fcram_partition:"
" Invalid Partition %d \n",
partid));
return (NPI_FFLP_FCRAM_PART_INVALID);
}
offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
sel.value = 0;
sel.bits.ldw.mask = base_mask;
sel.bits.ldw.base = base_reloc;
sel.bits.ldw.ext = BIT_DISABLE;
REG_PIO_WRITE64(handle, offset, sel.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_fcram_partition_enable (npi_handle_t handle, part_id_t partid)
{
flow_prt_sel_t sel;
uint64_t offset;
ASSERT(FCRAM_PARTITION_VALID(partid));
if (!FCRAM_PARTITION_VALID(partid)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fcram_partition enable:"
" Invalid Partition %d \n",
partid));
return (NPI_FFLP_FCRAM_PART_INVALID);
}
offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
REG_PIO_READ64(handle, offset, &sel.value);
sel.bits.ldw.ext = BIT_ENABLE;
REG_PIO_WRITE64(handle, offset, sel.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_fcram_partition_disable(npi_handle_t handle, part_id_t partid)
{
flow_prt_sel_t sel;
uint64_t offset;
ASSERT(FCRAM_PARTITION_VALID(partid));
if (!FCRAM_PARTITION_VALID(partid)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fcram_partition disable:"
" Invalid Partition %d \n",
partid));
return (NPI_FFLP_FCRAM_PART_INVALID);
}
offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
REG_PIO_READ64(handle, offset, &sel.value);
sel.bits.ldw.ext = BIT_DISABLE;
REG_PIO_WRITE64(handle, offset, sel.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_cam_errorcheck_disable(npi_handle_t handle)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.errordis = BIT_ENABLE;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_cam_errorcheck_enable(npi_handle_t handle)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.errordis = BIT_DISABLE;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_llcsnap_enable(npi_handle_t handle)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.llcsnap = BIT_ENABLE;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_llcsnap_disable(npi_handle_t handle)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.llcsnap = BIT_DISABLE;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_fcram_refresh_time(npi_handle_t handle, uint32_t min_time,
uint32_t max_time, uint32_t sys_time)
{
uint64_t offset;
fcram_ref_tmr_t refresh_timer_reg;
uint16_t max, min;
offset = FFLP_FCRAM_REF_TMR_REG;
max = max_time * sys_time;
min = min_time * sys_time;
max = FCRAM_REFRESH_DEFAULT_MAX_TIME;
min = FCRAM_REFRESH_DEFAULT_MIN_TIME;
REG_PIO_READ64(handle, offset, &refresh_timer_reg.value);
refresh_timer_reg.bits.ldw.min = min;
refresh_timer_reg.bits.ldw.max = max;
REG_PIO_WRITE64(handle, offset, refresh_timer_reg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_get_lookup_err_log(npi_handle_t handle,
hash_lookup_err_log_t *err_stat)
{
hash_lookup_err_log1_t err_log1;
hash_lookup_err_log2_t err_log2;
uint64_t err_log1_offset, err_log2_offset;
err_log1.value = 0;
err_log2.value = 0;
err_log1_offset = HASH_LKUP_ERR_LOG1_REG;
err_log2_offset = HASH_LKUP_ERR_LOG2_REG;
REG_PIO_READ64(handle, err_log1_offset, &err_log1.value);
REG_PIO_READ64(handle, err_log2_offset, &err_log2.value);
if (err_log1.value) {
err_stat->lookup_err = BIT_ENABLE;
err_stat->syndrome = err_log2.bits.ldw.syndrome;
err_stat->subarea = err_log2.bits.ldw.subarea;
err_stat->h1 = err_log2.bits.ldw.h1;
err_stat->multi_bit = err_log1.bits.ldw.mult_bit;
err_stat->multi_lkup = err_log1.bits.ldw.mult_lk;
err_stat->ecc_err = err_log1.bits.ldw.ecc_err;
err_stat->uncor_err = err_log1.bits.ldw.cu;
} else {
err_stat->lookup_err = BIT_DISABLE;
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_get_pio_err_log(npi_handle_t handle, part_id_t partid,
hash_pio_err_log_t *err_stat)
{
hash_tbl_data_log_t err_log;
uint64_t offset;
ASSERT(FCRAM_PARTITION_VALID(partid));
if (!FCRAM_PARTITION_VALID(partid)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fcram_get_pio_err_log:"
" Invalid Partition %d \n",
partid));
return (NPI_FFLP_FCRAM_PART_INVALID);
}
offset = GET_HASHTBL_PART_OFFSET_NVIR(partid,
FFLP_HASH_TBL_DATA_LOG_REG);
REG_PIO_READ64(handle, offset, &err_log.value);
if (err_log.bits.ldw.pio_err == BIT_ENABLE) {
err_stat->pio_err = BIT_ENABLE;
err_stat->syndrome = err_log.bits.ldw.syndrome;
err_stat->addr = err_log.bits.ldw.fcram_addr;
err_log.value = 0;
REG_PIO_WRITE64(handle, offset, err_log.value);
} else {
err_stat->pio_err = BIT_DISABLE;
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_clr_pio_err_log(npi_handle_t handle, part_id_t partid)
{
uint64_t offset;
hash_tbl_data_log_t err_log;
ASSERT(FCRAM_PARTITION_VALID(partid));
if (!FCRAM_PARTITION_VALID(partid)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fcram_clr_pio_err_log:"
" Invalid Partition %d \n",
partid));
return (NPI_FFLP_FCRAM_PART_INVALID);
}
offset = GET_HASHTBL_PART_OFFSET_NVIR(partid,
FFLP_HASH_TBL_DATA_LOG_REG);
err_log.value = 0;
REG_PIO_WRITE64(handle, offset, err_log.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_tcam_get_err_log(npi_handle_t handle, tcam_err_log_t *err_stat)
{
tcam_err_t err_log;
uint64_t offset;
offset = FFLP_TCAM_ERR_REG;
err_log.value = 0;
REG_PIO_READ64(handle, offset, &err_log.value);
if (err_log.bits.ldw.err == BIT_ENABLE) {
err_stat->tcam_err = BIT_ENABLE;
if (err_log.bits.ldw.p_ecc) {
err_stat->parity_err = 0;
err_stat->ecc_err = 1;
} else {
err_stat->parity_err = 1;
err_stat->ecc_err = 0;
}
err_stat->syndrome = err_log.bits.ldw.syndrome;
err_stat->location = err_log.bits.ldw.addr;
err_stat->multi_lkup = err_log.bits.ldw.mult;
err_log.value = 0;
REG_PIO_WRITE64(handle, offset, err_log.value);
} else {
err_stat->tcam_err = 0;
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_tcam_clr_err_log(npi_handle_t handle)
{
tcam_err_t err_log;
uint64_t offset;
offset = FFLP_TCAM_ERR_REG;
err_log.value = 0;
REG_PIO_WRITE64(handle, offset, err_log.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_err_synd_test(npi_handle_t handle, uint8_t syndrome_bits)
{
uint64_t t0_offset;
fcram_err_tst0_t tst0;
t0_offset = FFLP_FCRAM_ERR_TST0_REG;
tst0.value = 0;
tst0.bits.ldw.syndrome_mask = syndrome_bits;
REG_PIO_WRITE64(handle, t0_offset, tst0.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_fcram_err_data_test(npi_handle_t handle, fcram_err_data_t *data)
{
uint64_t t1_offset, t2_offset;
fcram_err_tst1_t tst1;
fcram_err_tst2_t tst2;
t1_offset = FFLP_FCRAM_ERR_TST1_REG;
t2_offset = FFLP_FCRAM_ERR_TST2_REG;
tst1.value = 0;
tst2.value = 0;
tst1.bits.ldw.dat = data->bits.ldw.dat;
tst2.bits.ldw.dat = data->bits.hdw.dat;
REG_PIO_WRITE64(handle, t1_offset, tst1.value);
REG_PIO_WRITE64(handle, t2_offset, tst2.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_enet_vlan_table_assoc(npi_handle_t handle, uint8_t mac_portn,
vlan_id_t vlan_id, uint8_t rdc_table,
uint8_t priority)
{
fflp_enet_vlan_tbl_t cfg;
uint64_t offset;
uint8_t vlan_parity[8] = {0, 1, 1, 2, 1, 2, 2, 3};
uint8_t parity_bit;
ASSERT(FFLP_VLAN_VALID(vlan_id));
if (!FFLP_VLAN_VALID(vlan_id)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fflp_cfg_enet_vlan_table:"
" Invalid vlan ID %d \n",
vlan_id));
return (NPI_FFLP_VLAN_INVALID);
}
ASSERT(FFLP_PORT_VALID(mac_portn));
if (!FFLP_PORT_VALID(mac_portn)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fflp_cfg_enet_vlan_table:"
" Invalid port num %d \n",
mac_portn));
return (NPI_FFLP_PORT_INVALID);
}
ASSERT(FFLP_RDC_TABLE_VALID(rdc_table));
if (!FFLP_RDC_TABLE_VALID(rdc_table)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" fflp_cfg_enet_vlan_table:"
" Invalid RDC Table %d \n",
rdc_table));
return (NPI_FFLP_RDC_TABLE_INVALID);
}
offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
REG_PIO_READ64(handle, offset, &cfg.value);
switch (mac_portn) {
case 0:
cfg.bits.ldw.vlanrdctbln0 = rdc_table;
if (priority)
cfg.bits.ldw.vpr0 = BIT_ENABLE;
else
cfg.bits.ldw.vpr0 = BIT_DISABLE;
parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] +
vlan_parity[cfg.bits.ldw.vlanrdctbln1] +
cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1;
cfg.bits.ldw.parity0 = parity_bit & 0x1;
break;
case 1:
cfg.bits.ldw.vlanrdctbln1 = rdc_table;
if (priority)
cfg.bits.ldw.vpr1 = BIT_ENABLE;
else
cfg.bits.ldw.vpr1 = BIT_DISABLE;
parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] +
vlan_parity[cfg.bits.ldw.vlanrdctbln1] +
cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1;
cfg.bits.ldw.parity0 = parity_bit & 0x1;
break;
case 2:
cfg.bits.ldw.vlanrdctbln2 = rdc_table;
if (priority)
cfg.bits.ldw.vpr2 = BIT_ENABLE;
else
cfg.bits.ldw.vpr2 = BIT_DISABLE;
parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] +
vlan_parity[cfg.bits.ldw.vlanrdctbln3] +
cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3;
cfg.bits.ldw.parity1 = parity_bit & 0x1;
break;
case 3:
cfg.bits.ldw.vlanrdctbln3 = rdc_table;
if (priority)
cfg.bits.ldw.vpr3 = BIT_ENABLE;
else
cfg.bits.ldw.vpr3 = BIT_DISABLE;
parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] +
vlan_parity[cfg.bits.ldw.vlanrdctbln3] +
cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3;
cfg.bits.ldw.parity1 = parity_bit & 0x1;
break;
default:
return (NPI_FFLP_SW_PARAM_ERROR);
}
REG_PIO_WRITE64(handle, offset, cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_enet_vlan_table_set_pri(npi_handle_t handle, uint8_t mac_portn,
vlan_id_t vlan_id, uint8_t priority)
{
fflp_enet_vlan_tbl_t cfg;
uint64_t offset;
uint64_t old_value;
ASSERT(FFLP_VLAN_VALID(vlan_id));
if (!FFLP_VLAN_VALID(vlan_id)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" enet_vlan_table set pri:"
" Invalid vlan ID %d \n",
vlan_id));
return (NPI_FFLP_VLAN_INVALID);
}
ASSERT(FFLP_PORT_VALID(mac_portn));
if (!FFLP_PORT_VALID(mac_portn)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" enet_vlan_table set pri:"
" Invalid port num %d \n",
mac_portn));
return (NPI_FFLP_PORT_INVALID);
}
offset = FFLP_ENET_VLAN_TBL_REG + (vlan_id << 3);
REG_PIO_READ64(handle, offset, &cfg.value);
old_value = cfg.value;
switch (mac_portn) {
case 0:
if (priority)
cfg.bits.ldw.vpr0 = BIT_ENABLE;
else
cfg.bits.ldw.vpr0 = BIT_DISABLE;
break;
case 1:
if (priority)
cfg.bits.ldw.vpr1 = BIT_ENABLE;
else
cfg.bits.ldw.vpr1 = BIT_DISABLE;
break;
case 2:
if (priority)
cfg.bits.ldw.vpr2 = BIT_ENABLE;
else
cfg.bits.ldw.vpr2 = BIT_DISABLE;
break;
case 3:
if (priority)
cfg.bits.ldw.vpr3 = BIT_ENABLE;
else
cfg.bits.ldw.vpr3 = BIT_DISABLE;
break;
default:
return (NPI_FFLP_SW_PARAM_ERROR);
}
if (old_value != cfg.value) {
if (mac_portn > 1)
cfg.bits.ldw.parity1++;
else
cfg.bits.ldw.parity0++;
REG_PIO_WRITE64(handle, offset, cfg.value);
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_vlan_table_clear(npi_handle_t handle, vlan_id_t vlan_id)
{
uint64_t offset;
uint64_t clear = 0ULL;
vlan_id_t start_vlan = 0;
if ((vlan_id < start_vlan) || (vlan_id >= NXGE_MAX_VLANS)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" enet_vlan_table clear:"
" Invalid vlan ID %d \n",
vlan_id));
return (NPI_FFLP_VLAN_INVALID);
}
offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
REG_PIO_WRITE64(handle, offset, clear);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_vlan_tbl_get_err_log(npi_handle_t handle, vlan_tbl_err_log_t *err_stat)
{
vlan_par_err_t err_log;
uint64_t offset;
offset = FFLP_VLAN_PAR_ERR_REG;
err_log.value = 0;
REG_PIO_READ64(handle, offset, &err_log.value);
if (err_log.bits.ldw.err == BIT_ENABLE) {
err_stat->err = BIT_ENABLE;
err_stat->multi = err_log.bits.ldw.m_err;
err_stat->addr = err_log.bits.ldw.addr;
err_stat->data = err_log.bits.ldw.data;
err_log.value = 0;
REG_PIO_WRITE64(handle, offset, err_log.value);
} else {
err_stat->err = 0;
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_vlan_tbl_clr_err_log(npi_handle_t handle)
{
vlan_par_err_t err_log;
uint64_t offset;
offset = FFLP_VLAN_PAR_ERR_REG;
err_log.value = 0;
REG_PIO_WRITE64(handle, offset, err_log.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_enet_usr_cls_set(npi_handle_t handle,
tcam_class_t class, uint16_t enet_type)
{
uint64_t offset;
tcam_class_prg_ether_t cls_cfg;
cls_cfg.value = 0x0;
ASSERT(TCAM_L2_USR_CLASS_VALID(class));
if (!TCAM_L2_USR_CLASS_VALID(class)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_enet_usr_cls_set:"
" Invalid class %d \n",
class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_TCAM_CLASS_OFFSET(class);
cls_cfg.bits.ldw.etype = enet_type;
cls_cfg.bits.ldw.valid = BIT_DISABLE;
REG_PIO_WRITE64(handle, offset, cls_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_enet_usr_cls_enable(npi_handle_t handle, tcam_class_t class)
{
uint64_t offset;
tcam_class_prg_ether_t cls_cfg;
ASSERT(TCAM_L2_USR_CLASS_VALID(class));
if (!TCAM_L2_USR_CLASS_VALID(class)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_enet_usr_cls_enable:"
" Invalid class %d \n",
class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_TCAM_CLASS_OFFSET(class);
REG_PIO_READ64(handle, offset, &cls_cfg.value);
cls_cfg.bits.ldw.valid = BIT_ENABLE;
REG_PIO_WRITE64(handle, offset, cls_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_enet_usr_cls_disable(npi_handle_t handle, tcam_class_t class)
{
uint64_t offset;
tcam_class_prg_ether_t cls_cfg;
ASSERT(TCAM_L2_USR_CLASS_VALID(class));
if (!TCAM_L2_USR_CLASS_VALID(class)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_enet_usr_cls_disable:"
" Invalid class %d \n",
class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_TCAM_CLASS_OFFSET(class);
REG_PIO_READ64(handle, offset, &cls_cfg.value);
cls_cfg.bits.ldw.valid = BIT_DISABLE;
REG_PIO_WRITE64(handle, offset, cls_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_usr_cls_set(npi_handle_t handle, tcam_class_t class,
uint8_t tos, uint8_t tos_mask,
uint8_t proto, uint8_t ver)
{
uint64_t offset;
tcam_class_prg_ip_t ip_cls_cfg;
ASSERT(TCAM_L3_USR_CLASS_VALID(class));
if (!TCAM_L3_USR_CLASS_VALID(class)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_usr_cls_set:"
" Invalid class %d \n",
class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_TCAM_CLASS_OFFSET(class);
ip_cls_cfg.bits.ldw.pid = proto;
ip_cls_cfg.bits.ldw.ipver = ver;
ip_cls_cfg.bits.ldw.tos = tos;
ip_cls_cfg.bits.ldw.tosmask = tos_mask;
ip_cls_cfg.bits.ldw.valid = 0;
REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_usr_cls_set_iptun(npi_handle_t handle, tcam_class_t class,
uint8_t l4b0_val, uint8_t l4b0_msk,
uint16_t l4b23_val, uint8_t l4b23_sel)
{
uint64_t offset, val;
tcam_class_prg_ip_t ip_cls_cfg;
ASSERT(TCAM_L3_USR_CLASS_VALID(class));
if (!TCAM_L3_USR_CLASS_VALID(class)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_usr_cls_set:"
" Invalid class %d \n",
class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_TCAM_CLASS_OFFSET(class);
REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
val = 1;
ip_cls_cfg.value |= (val << L3_UCLS_L4_MODE_SH);
val = l4b0_val;
ip_cls_cfg.value |= (val << L3_UCLS_L4B0_VAL_SH);
val = l4b0_msk;
ip_cls_cfg.value |= (val << L3_UCLS_L4B0_MASK_SH);
val = l4b23_sel;
ip_cls_cfg.value |= (val << L3_UCLS_L4B23_SEL_SH);
val = l4b23_val;
ip_cls_cfg.value |= (val << L3_UCLS_L4B23_VAL_SH);
ip_cls_cfg.bits.ldw.valid = 0;
REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_usr_cls_get_iptun(npi_handle_t handle, tcam_class_t class,
uint8_t *l4b0_val, uint8_t *l4b0_msk,
uint16_t *l4b23_val, uint8_t *l4b23_sel)
{
uint64_t offset;
tcam_class_prg_ip_t ip_cls_cfg;
ASSERT(TCAM_L3_USR_CLASS_VALID(class));
if (!TCAM_L3_USR_CLASS_VALID(class)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_usr_cls_set:"
" Invalid class %d \n",
class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_TCAM_CLASS_OFFSET(class);
REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
*l4b0_val = (ip_cls_cfg.value >> L3_UCLS_L4B0_VAL_SH) &
L3_UCLS_L4B0_VAL_MSK;
*l4b0_msk = (ip_cls_cfg.value >> L3_UCLS_L4B0_MASK_SH) &
L3_UCLS_L4B0_MASK_MSK;
*l4b23_sel = (ip_cls_cfg.value >> L3_UCLS_L4B23_SEL_SH) &
L3_UCLS_L4B23_SEL_MSK;
*l4b23_val = (ip_cls_cfg.value >> L3_UCLS_L4B23_VAL_SH) &
L3_UCLS_L4B23_VAL_MSK;
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_usr_cls_enable(npi_handle_t handle, tcam_class_t class)
{
uint64_t offset;
tcam_class_prg_ip_t ip_cls_cfg;
ASSERT(TCAM_L3_USR_CLASS_VALID(class));
if (!TCAM_L3_USR_CLASS_VALID(class)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_usr_cls_enable:"
" Invalid class %d \n",
class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_TCAM_CLASS_OFFSET(class);
REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
ip_cls_cfg.bits.ldw.valid = 1;
REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_usr_cls_disable(npi_handle_t handle, tcam_class_t class)
{
uint64_t offset;
tcam_class_prg_ip_t ip_cls_cfg;
ASSERT(TCAM_L3_USR_CLASS_VALID(class));
if (!TCAM_L3_USR_CLASS_VALID(class)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_usr_cls_disable:"
" Invalid class %d \n",
class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_TCAM_CLASS_OFFSET(class);
REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
ip_cls_cfg.bits.ldw.valid = 0;
REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_cls_tcam_key(npi_handle_t handle,
tcam_class_t l3_class, tcam_key_cfg_t *cfg)
{
uint64_t offset;
tcam_class_key_ip_t tcam_cls_cfg;
ASSERT(TCAM_L3_CLASS_VALID(l3_class));
if (!(TCAM_L3_CLASS_VALID(l3_class))) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_cls_tcam_key:"
" Invalid class %d \n",
l3_class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
if ((cfg->use_ip_daddr) &&
(cfg->use_ip_saddr == cfg->use_ip_daddr)) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_cls_tcam_key:"
" Invalid configuration %x for class %d \n",
*cfg, l3_class));
return (NPI_FFLP_SW_PARAM_ERROR);
}
offset = GET_TCAM_KEY_OFFSET(l3_class);
tcam_cls_cfg.value = 0;
if (cfg->discard) {
tcam_cls_cfg.bits.ldw.discard = 1;
}
if (cfg->use_ip_saddr) {
tcam_cls_cfg.bits.ldw.ipaddr = 1;
}
if (cfg->use_ip_daddr) {
tcam_cls_cfg.bits.ldw.ipaddr = 0;
}
if (cfg->lookup_enable) {
tcam_cls_cfg.bits.ldw.tsel = 1;
}
REG_PIO_WRITE64(handle, offset, tcam_cls_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class,
flow_key_cfg_t *cfg)
{
uint64_t offset;
flow_class_key_ip_t flow_cfg_reg;
ASSERT(TCAM_L3_CLASS_VALID(l3_class));
if (!(TCAM_L3_CLASS_VALID(l3_class))) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_cls_flow_key:"
" Invalid class %d \n",
l3_class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_FLOW_KEY_OFFSET(l3_class);
flow_cfg_reg.value = 0;
if (cfg->use_proto) {
flow_cfg_reg.bits.ldw.proto = 1;
}
if (cfg->use_dport) {
flow_cfg_reg.bits.ldw.l4_1 = 2;
if (cfg->ip_opts_exist)
flow_cfg_reg.bits.ldw.l4_1 = 3;
}
if (cfg->use_sport) {
flow_cfg_reg.bits.ldw.l4_0 = 2;
if (cfg->ip_opts_exist)
flow_cfg_reg.bits.ldw.l4_0 = 3;
}
if (cfg->use_daddr) {
flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE;
}
if (cfg->use_saddr) {
flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE;
}
if (cfg->use_vlan) {
flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE;
}
if (cfg->use_l2da) {
flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE;
}
if (cfg->use_portnum) {
flow_cfg_reg.bits.ldw.port = BIT_ENABLE;
}
REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_cls_flow_key_get(npi_handle_t handle,
tcam_class_t l3_class,
flow_key_cfg_t *cfg)
{
uint64_t offset;
flow_class_key_ip_t flow_cfg_reg;
ASSERT(TCAM_L3_CLASS_VALID(l3_class));
if (!(TCAM_L3_CLASS_VALID(l3_class))) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_cls_flow_key:"
" Invalid class %d \n",
l3_class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_FLOW_KEY_OFFSET(l3_class);
cfg->use_proto = 0;
cfg->use_dport = 0;
cfg->use_sport = 0;
cfg->ip_opts_exist = 0;
cfg->use_daddr = 0;
cfg->use_saddr = 0;
cfg->use_vlan = 0;
cfg->use_l2da = 0;
cfg->use_portnum = 0;
REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
if (flow_cfg_reg.bits.ldw.proto) {
cfg->use_proto = 1;
}
if (flow_cfg_reg.bits.ldw.l4_1 == 2) {
cfg->use_dport = 1;
}
if (flow_cfg_reg.bits.ldw.l4_1 == 3) {
cfg->use_dport = 1;
cfg->ip_opts_exist = 1;
}
if (flow_cfg_reg.bits.ldw.l4_0 == 2) {
cfg->use_sport = 1;
}
if (flow_cfg_reg.bits.ldw.l4_0 == 3) {
cfg->use_sport = 1;
cfg->ip_opts_exist = 1;
}
if (flow_cfg_reg.bits.ldw.ipda) {
cfg->use_daddr = 1;
}
if (flow_cfg_reg.bits.ldw.ipsa) {
cfg->use_saddr = 1;
}
if (flow_cfg_reg.bits.ldw.vlan) {
cfg->use_vlan = 1;
}
if (flow_cfg_reg.bits.ldw.l2da) {
cfg->use_l2da = 1;
}
if (flow_cfg_reg.bits.ldw.port) {
cfg->use_portnum = 1;
}
NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
" npi_fflp_cfg_ip_cls_flow_get %llx \n",
flow_cfg_reg.value));
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_cls_flow_key_rfnl(npi_handle_t handle, tcam_class_t l3_class,
flow_key_cfg_t *cfg)
{
uint64_t offset;
flow_class_key_ip_t flow_cfg_reg;
ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_cls_flow_key_rfnl:"
" Invalid class %d \n",
l3_class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
if (l3_class == TCAM_CLASS_IPV6_FRAG) {
offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
} else {
offset = GET_FLOW_KEY_OFFSET(l3_class);
}
flow_cfg_reg.value = 0;
flow_cfg_reg.bits.ldw.l4_xor = cfg->l4_xor_sel;
if (cfg->use_l4_md)
flow_cfg_reg.bits.ldw.l4_mode = 1;
if (cfg->use_sym)
flow_cfg_reg.bits.ldw.sym = 1;
if (cfg->use_proto) {
flow_cfg_reg.bits.ldw.proto = 1;
}
if (cfg->use_dport) {
flow_cfg_reg.bits.ldw.l4_1 = 2;
if (cfg->ip_opts_exist)
flow_cfg_reg.bits.ldw.l4_1 = 3;
}
if (cfg->use_sport) {
flow_cfg_reg.bits.ldw.l4_0 = 2;
if (cfg->ip_opts_exist)
flow_cfg_reg.bits.ldw.l4_0 = 3;
}
if (cfg->use_daddr) {
flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE;
}
if (cfg->use_saddr) {
flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE;
}
if (cfg->use_vlan) {
flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE;
}
if (cfg->use_l2da) {
flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE;
}
if (cfg->use_portnum) {
flow_cfg_reg.bits.ldw.port = BIT_ENABLE;
}
REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_sym_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class,
boolean_t enable)
{
uint64_t offset;
flow_class_key_ip_t flow_cfg_reg;
ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_sym_ip_cls_flow_key:"
" Invalid class %d \n",
l3_class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
if (l3_class == TCAM_CLASS_IPV6_FRAG) {
offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
} else {
offset = GET_FLOW_KEY_OFFSET(l3_class);
}
REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
if (enable && flow_cfg_reg.bits.ldw.sym == 0) {
flow_cfg_reg.bits.ldw.sym = 1;
REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
} else if (!enable && flow_cfg_reg.bits.ldw.sym == 1) {
flow_cfg_reg.bits.ldw.sym = 0;
REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
}
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_cls_flow_key_get_rfnl(npi_handle_t handle,
tcam_class_t l3_class,
flow_key_cfg_t *cfg)
{
uint64_t offset;
flow_class_key_ip_t flow_cfg_reg;
ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_cls_flow_key_get_rfnl:"
" Invalid class %d \n",
l3_class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
if (l3_class == TCAM_CLASS_IPV6_FRAG) {
offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
} else {
offset = GET_FLOW_KEY_OFFSET(l3_class);
}
cfg->l4_xor_sel = 0;
cfg->use_l4_md = 0;
cfg->use_sym = 0;
cfg->use_proto = 0;
cfg->use_dport = 0;
cfg->use_sport = 0;
cfg->ip_opts_exist = 0;
cfg->use_daddr = 0;
cfg->use_saddr = 0;
cfg->use_vlan = 0;
cfg->use_l2da = 0;
cfg->use_portnum = 0;
REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
cfg->l4_xor_sel = flow_cfg_reg.bits.ldw.l4_xor;
if (flow_cfg_reg.bits.ldw.l4_mode)
cfg->use_l4_md = 1;
if (flow_cfg_reg.bits.ldw.sym)
cfg->use_sym = 1;
if (flow_cfg_reg.bits.ldw.proto) {
cfg->use_proto = 1;
}
if (flow_cfg_reg.bits.ldw.l4_1 == 2) {
cfg->use_dport = 1;
}
if (flow_cfg_reg.bits.ldw.l4_1 == 3) {
cfg->use_dport = 1;
cfg->ip_opts_exist = 1;
}
if (flow_cfg_reg.bits.ldw.l4_0 == 2) {
cfg->use_sport = 1;
}
if (flow_cfg_reg.bits.ldw.l4_0 == 3) {
cfg->use_sport = 1;
cfg->ip_opts_exist = 1;
}
if (flow_cfg_reg.bits.ldw.ipda) {
cfg->use_daddr = 1;
}
if (flow_cfg_reg.bits.ldw.ipsa) {
cfg->use_saddr = 1;
}
if (flow_cfg_reg.bits.ldw.vlan) {
cfg->use_vlan = 1;
}
if (flow_cfg_reg.bits.ldw.l2da) {
cfg->use_l2da = 1;
}
if (flow_cfg_reg.bits.ldw.port) {
cfg->use_portnum = 1;
}
NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
" npi_fflp_cfg_ip_cls_flow_get %llx \n",
flow_cfg_reg.value));
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_ip_cls_tcam_key_get(npi_handle_t handle,
tcam_class_t l3_class, tcam_key_cfg_t *cfg)
{
uint64_t offset;
tcam_class_key_ip_t tcam_cls_cfg;
ASSERT(TCAM_L3_CLASS_VALID(l3_class));
if (!(TCAM_L3_CLASS_VALID(l3_class))) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_ip_cls_tcam_key_get:"
" Invalid class %d \n",
l3_class));
return (NPI_FFLP_TCAM_CLASS_INVALID);
}
offset = GET_TCAM_KEY_OFFSET(l3_class);
REG_PIO_READ64(handle, offset, &tcam_cls_cfg.value);
cfg->discard = 0;
cfg->use_ip_saddr = 0;
cfg->use_ip_daddr = 1;
cfg->lookup_enable = 0;
if (tcam_cls_cfg.bits.ldw.discard)
cfg->discard = 1;
if (tcam_cls_cfg.bits.ldw.ipaddr) {
cfg->use_ip_saddr = 1;
cfg->use_ip_daddr = 0;
}
if (tcam_cls_cfg.bits.ldw.tsel) {
cfg->lookup_enable = 1;
}
NPI_DEBUG_MSG((handle.function, NPI_CTL,
" npi_fflp_cfg_ip_cls_tcam_key_get %llx \n",
tcam_cls_cfg.value));
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_fcram_access(npi_handle_t handle, uint8_t access_ratio)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
if (access_ratio > 0xf) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_fcram_access:"
" Invalid access ratio %d \n",
access_ratio));
return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
}
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.fflpinitdone = 0;
fflp_cfg.bits.ldw.fcramratio = access_ratio;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.fflpinitdone = 1;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_tcam_access(npi_handle_t handle, uint8_t access_ratio)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
if (access_ratio > 0xf) {
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_cfg_tcram_access:"
" Invalid access ratio %d \n",
access_ratio));
return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
}
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.fflpinitdone = 0;
fflp_cfg.bits.ldw.camratio = access_ratio;
fflp_cfg.bits.ldw.camlatency = TCAM_DEFAULT_LATENCY;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.fflpinitdone = 1;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_hash_h1poly(npi_handle_t handle, uint32_t init_value)
{
hash_h1poly_t h1_cfg;
uint64_t offset;
offset = FFLP_H1POLY_REG;
h1_cfg.value = 0;
h1_cfg.bits.ldw.init_value = init_value;
REG_PIO_WRITE64(handle, offset, h1_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_hash_h2poly(npi_handle_t handle, uint16_t init_value)
{
hash_h2poly_t h2_cfg;
uint64_t offset;
offset = FFLP_H2POLY_REG;
h2_cfg.value = 0;
h2_cfg.bits.ldw.init_value = init_value;
REG_PIO_WRITE64(handle, offset, h2_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_fcram_reset(npi_handle_t handle,
fflp_fcram_output_drive_t strength, fflp_fcram_qs_t qs)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
fflp_cfg.value = 0;
fflp_cfg.bits.ldw.pio_fio_rst = 1;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
NXGE_DELAY(5);
fflp_cfg.bits.ldw.pio_fio_rst = 0;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
fflp_cfg.bits.ldw.fcramqs = qs;
fflp_cfg.bits.ldw.fcramoutdr = strength;
fflp_cfg.bits.ldw.fflpinitdone = 1;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_init_done(npi_handle_t handle)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.fflpinitdone = 1;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_init_start(npi_handle_t handle)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.fflpinitdone = 0;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_tcam_enable(npi_handle_t handle)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.tcam_disable = 0;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_cfg_tcam_disable(npi_handle_t handle)
{
fflp_cfg_1_t fflp_cfg;
uint64_t offset;
offset = FFLP_CFG_1_REG;
REG_PIO_READ64(handle, offset, &fflp_cfg.value);
fflp_cfg.bits.ldw.tcam_disable = 1;
REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
return (NPI_SUCCESS);
}
npi_status_t
npi_fflp_event_mask_config(npi_handle_t handle, io_op_t op_mode,
fflp_event_mask_cfg_t *mask_cfgp)
{
int status = NPI_SUCCESS;
fflp_err_mask_t mask_reg;
switch (op_mode) {
case OP_GET:
REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value);
*mask_cfgp = mask_reg.value & FFLP_ERR_MASK_ALL;
break;
case OP_SET:
mask_reg.value = (~(*mask_cfgp) & FFLP_ERR_MASK_ALL);
REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
break;
case OP_UPDATE:
REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value);
mask_reg.value |= (~(*mask_cfgp) & FFLP_ERR_MASK_ALL);
REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
break;
case OP_CLEAR:
mask_reg.value = FFLP_ERR_MASK_ALL;
REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
break;
default:
NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
" npi_fflp_event_mask_config",
" eventmask <0x%x>", op_mode));
return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
}
return (status);
}
void
npi_fflp_vlan_error_get(npi_handle_t handle, p_vlan_par_err_t p_err)
{
REG_PIO_READ64(handle, FFLP_VLAN_PAR_ERR_REG, &p_err->value);
}
void
npi_fflp_vlan_error_clear(npi_handle_t handle)
{
vlan_par_err_t p_err;
p_err.value = 0;
p_err.bits.ldw.m_err = 0;
p_err.bits.ldw.err = 0;
REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, p_err.value);
}
void
npi_fflp_tcam_error_get(npi_handle_t handle, p_tcam_err_t p_err)
{
REG_PIO_READ64(handle, FFLP_TCAM_ERR_REG, &p_err->value);
}
void
npi_fflp_tcam_error_clear(npi_handle_t handle)
{
tcam_err_t p_err;
p_err.value = 0;
p_err.bits.ldw.p_ecc = 0;
p_err.bits.ldw.mult = 0;
p_err.bits.ldw.err = 0;
REG_PIO_WRITE64(handle, FFLP_TCAM_ERR_REG, p_err.value);
}
void
npi_fflp_fcram_error_get(npi_handle_t handle,
p_hash_tbl_data_log_t p_err, uint8_t partition)
{
uint64_t offset;
offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192;
REG_PIO_READ64(handle, offset, &p_err->value);
}
void
npi_fflp_fcram_error_clear(npi_handle_t handle, uint8_t partition)
{
hash_tbl_data_log_t p_err;
uint64_t offset;
p_err.value = 0;
p_err.bits.ldw.pio_err = 0;
offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192;
REG_PIO_WRITE64(handle, offset,
p_err.value);
}
void
npi_fflp_fcram_error_log1_get(npi_handle_t handle,
p_hash_lookup_err_log1_t log1)
{
REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG1_REG,
&log1->value);
}
void
npi_fflp_fcram_error_log2_get(npi_handle_t handle,
p_hash_lookup_err_log2_t log2)
{
REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG2_REG,
&log2->value);
}