xref: /onnv-gate/usr/src/uts/common/io/nxge/npi/npi_fflp.c (revision 11304:3092d1e303d6)
13859Sml29623 /*
23859Sml29623  * CDDL HEADER START
33859Sml29623  *
43859Sml29623  * The contents of this file are subject to the terms of the
53859Sml29623  * Common Development and Distribution License (the "License").
63859Sml29623  * You may not use this file except in compliance with the License.
73859Sml29623  *
83859Sml29623  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93859Sml29623  * or http://www.opensolaris.org/os/licensing.
103859Sml29623  * See the License for the specific language governing permissions
113859Sml29623  * and limitations under the License.
123859Sml29623  *
133859Sml29623  * When distributing Covered Code, include this CDDL HEADER in each
143859Sml29623  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153859Sml29623  * If applicable, add the following below this CDDL HEADER, with the
163859Sml29623  * fields enclosed by brackets "[]" replaced with your own identifying
173859Sml29623  * information: Portions Copyright [yyyy] [name of copyright owner]
183859Sml29623  *
193859Sml29623  * CDDL HEADER END
203859Sml29623  */
213859Sml29623 /*
22*11304SJanie.Lu@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
233859Sml29623  * Use is subject to license terms.
243859Sml29623  */
253859Sml29623 
263859Sml29623 #include <npi_fflp.h>
273859Sml29623 #include <nxge_common.h>
283859Sml29623 
293859Sml29623 /* macros to compute calss configuration register offset */
303859Sml29623 
313859Sml29623 #define	  GET_TCAM_CLASS_OFFSET(cls) \
323859Sml29623 	(FFLP_TCAM_CLS_BASE_OFFSET + (cls - 2) * 8)
333859Sml29623 #define	  GET_TCAM_KEY_OFFSET(cls) \
343859Sml29623 	(FFLP_TCAM_KEY_BASE_OFFSET + (cls - 4) * 8)
353859Sml29623 #define	  GET_FLOW_KEY_OFFSET(cls) \
363859Sml29623 	(FFLP_FLOW_KEY_BASE_OFFSET + (cls - 4) * 8)
373859Sml29623 
383859Sml29623 #define	  HASHTBL_PART_REG_STEP 8192
393859Sml29623 #define	  HASHTBL_PART_REG_VIR_OFFSET 0x2100
403859Sml29623 #define	  HASHTBL_PART_REG_VIR_STEP 0x4000
413859Sml29623 #define	  GET_HASHTBL_PART_OFFSET_NVIR(partid, reg)	\
423859Sml29623 	((partid  * HASHTBL_PART_REG_STEP) + reg)
433859Sml29623 
443859Sml29623 #define	  GET_HASHTBL_PART_OFFSET(handle, partid, reg)	\
453859Sml29623 	    (handle.is_vraddr ?					\
463859Sml29623 	    (((partid & 0x1) * HASHTBL_PART_REG_VIR_STEP) +	\
473859Sml29623 	    (reg & 0x8) + (HASHTBL_PART_REG_VIR_OFFSET)) :	\
483859Sml29623 	    (partid * HASHTBL_PART_REG_STEP) + reg)
493859Sml29623 
503859Sml29623 #define	 FFLP_PART_OFFSET(partid, reg) ((partid  * 8) + reg)
513859Sml29623 #define	 FFLP_VLAN_OFFSET(vid, reg) ((vid  * 8) + reg)
523859Sml29623 
533859Sml29623 #define	 TCAM_COMPLETION_TRY_COUNT 10
543859Sml29623 #define	 BIT_ENABLE	0x1
553859Sml29623 #define	 BIT_DISABLE	0x0
563859Sml29623 
573859Sml29623 #define	 FCRAM_PARTITION_VALID(partid) \
583859Sml29623 	((partid < NXGE_MAX_RDC_GRPS))
593859Sml29623 #define	FFLP_VLAN_VALID(vid) \
603859Sml29623 	((vid > 0) && (vid < NXGE_MAX_VLANS))
613859Sml29623 #define	FFLP_PORT_VALID(port) \
623859Sml29623 	((port < MAX_PORTS_PER_NXGE))
633859Sml29623 #define	FFLP_RDC_TABLE_VALID(table) \
643859Sml29623 	((table < NXGE_MAX_RDC_GRPS))
653859Sml29623 #define	TCAM_L3_USR_CLASS_VALID(class) \
663859Sml29623 	((class >= TCAM_CLASS_IP_USER_4) && (class <= TCAM_CLASS_IP_USER_7))
673859Sml29623 #define	TCAM_L2_USR_CLASS_VALID(class) \
683859Sml29623 	((class == TCAM_CLASS_ETYPE_1) || (class == TCAM_CLASS_ETYPE_2))
693859Sml29623 #define	TCAM_L3_CLASS_VALID(class) \
703859Sml29623 	((class >= TCAM_CLASS_IP_USER_4) && (class <= TCAM_CLASS_SCTP_IPV6))
71*11304SJanie.Lu@Sun.COM #define	TCAM_L3_CLASS_VALID_RFNL(class) \
72*11304SJanie.Lu@Sun.COM 	((TCAM_L3_CLASS_VALID(class)) || class == TCAM_CLASS_IPV6_FRAG)
733859Sml29623 #define	TCAM_CLASS_VALID(class) \
743859Sml29623 	((class >= TCAM_CLASS_ETYPE_1) && (class <= TCAM_CLASS_RARP))
753859Sml29623 
763859Sml29623 
773859Sml29623 uint64_t fflp_fzc_offset[] = {
783859Sml29623 	FFLP_ENET_VLAN_TBL_REG, FFLP_L2_CLS_ENET1_REG, FFLP_L2_CLS_ENET2_REG,
793859Sml29623 	FFLP_TCAM_KEY_IP_USR4_REG, FFLP_TCAM_KEY_IP_USR5_REG,
803859Sml29623 	FFLP_TCAM_KEY_IP_USR6_REG, FFLP_TCAM_KEY_IP_USR7_REG,
813859Sml29623 	FFLP_TCAM_KEY_IP4_TCP_REG, FFLP_TCAM_KEY_IP4_UDP_REG,
823859Sml29623 	FFLP_TCAM_KEY_IP4_AH_ESP_REG, FFLP_TCAM_KEY_IP4_SCTP_REG,
833859Sml29623 	FFLP_TCAM_KEY_IP6_TCP_REG, FFLP_TCAM_KEY_IP6_UDP_REG,
843859Sml29623 	FFLP_TCAM_KEY_IP6_AH_ESP_REG, FFLP_TCAM_KEY_IP6_SCTP_REG,
853859Sml29623 	FFLP_TCAM_KEY_0_REG, FFLP_TCAM_KEY_1_REG, FFLP_TCAM_KEY_2_REG,
863859Sml29623 	FFLP_TCAM_KEY_3_REG, FFLP_TCAM_MASK_0_REG, FFLP_TCAM_MASK_1_REG,
873859Sml29623 	FFLP_TCAM_MASK_2_REG, FFLP_TCAM_MASK_3_REG, FFLP_TCAM_CTL_REG,
883859Sml29623 	FFLP_VLAN_PAR_ERR_REG, FFLP_TCAM_ERR_REG, HASH_LKUP_ERR_LOG1_REG,
893859Sml29623 	HASH_LKUP_ERR_LOG2_REG, FFLP_FCRAM_ERR_TST0_REG,
903859Sml29623 	FFLP_FCRAM_ERR_TST1_REG, FFLP_FCRAM_ERR_TST2_REG, FFLP_ERR_MSK_REG,
913859Sml29623 	FFLP_CFG_1_REG, FFLP_DBG_TRAIN_VCT_REG, FFLP_TCP_CFLAG_MSK_REG,
923859Sml29623 	FFLP_FCRAM_REF_TMR_REG,  FFLP_FLOW_KEY_IP_USR4_REG,
933859Sml29623 	FFLP_FLOW_KEY_IP_USR5_REG, FFLP_FLOW_KEY_IP_USR6_REG,
943859Sml29623 	FFLP_FLOW_KEY_IP_USR7_REG, FFLP_FLOW_KEY_IP4_TCP_REG,
953859Sml29623 	FFLP_FLOW_KEY_IP4_UDP_REG, FFLP_FLOW_KEY_IP4_AH_ESP_REG,
963859Sml29623 	FFLP_FLOW_KEY_IP4_SCTP_REG, FFLP_FLOW_KEY_IP6_TCP_REG,
973859Sml29623 	FFLP_FLOW_KEY_IP6_UDP_REG, FFLP_FLOW_KEY_IP6_AH_ESP_REG,
983859Sml29623 	FFLP_FLOW_KEY_IP6_SCTP_REG, FFLP_H1POLY_REG, FFLP_H2POLY_REG,
993859Sml29623 	FFLP_FLW_PRT_SEL_REG
1003859Sml29623 };
1013859Sml29623 
1023859Sml29623 const char *fflp_fzc_name[] = {
1033859Sml29623 	"FFLP_ENET_VLAN_TBL_REG", "FFLP_L2_CLS_ENET1_REG",
1043859Sml29623 	"FFLP_L2_CLS_ENET2_REG", "FFLP_TCAM_KEY_IP_USR4_REG",
1053859Sml29623 	"FFLP_TCAM_KEY_IP_USR5_REG", "FFLP_TCAM_KEY_IP_USR6_REG",
1063859Sml29623 	"FFLP_TCAM_KEY_IP_USR7_REG", "FFLP_TCAM_KEY_IP4_TCP_REG",
1073859Sml29623 	"FFLP_TCAM_KEY_IP4_UDP_REG", "FFLP_TCAM_KEY_IP4_AH_ESP_REG",
1083859Sml29623 	"FFLP_TCAM_KEY_IP4_SCTP_REG", "FFLP_TCAM_KEY_IP6_TCP_REG",
1093859Sml29623 	"FFLP_TCAM_KEY_IP6_UDP_REG", "FFLP_TCAM_KEY_IP6_AH_ESP_REG",
1103859Sml29623 	"FFLP_TCAM_KEY_IP6_SCTP_REG", "FFLP_TCAM_KEY_0_REG",
1113859Sml29623 	"FFLP_TCAM_KEY_1_REG", "FFLP_TCAM_KEY_2_REG", "FFLP_TCAM_KEY_3_REG",
1123859Sml29623 	"FFLP_TCAM_MASK_0_REG", "FFLP_TCAM_MASK_1_REG", "FFLP_TCAM_MASK_2_REG",
1133859Sml29623 	"FFLP_TCAM_MASK_3_REG", "FFLP_TCAM_CTL_REG", "FFLP_VLAN_PAR_ERR_REG",
1143859Sml29623 	"FFLP_TCAM_ERR_REG", "HASH_LKUP_ERR_LOG1_REG",
1153859Sml29623 	"HASH_LKUP_ERR_LOG2_REG", "FFLP_FCRAM_ERR_TST0_REG",
1163859Sml29623 	"FFLP_FCRAM_ERR_TST1_REG", "FFLP_FCRAM_ERR_TST2_REG",
1173859Sml29623 	"FFLP_ERR_MSK_REG", "FFLP_CFG_1_REG", "FFLP_DBG_TRAIN_VCT_REG",
1183859Sml29623 	"FFLP_TCP_CFLAG_MSK_REG", "FFLP_FCRAM_REF_TMR_REG",
1193859Sml29623 	"FFLP_FLOW_KEY_IP_USR4_REG", "FFLP_FLOW_KEY_IP_USR5_REG",
1203859Sml29623 	"FFLP_FLOW_KEY_IP_USR6_REG", "FFLP_FLOW_KEY_IP_USR7_REG",
1213859Sml29623 	"FFLP_FLOW_KEY_IP4_TCP_REG", "FFLP_FLOW_KEY_IP4_UDP_REG",
1223859Sml29623 	"FFLP_FLOW_KEY_IP4_AH_ESP_REG", "FFLP_FLOW_KEY_IP4_SCTP_REG",
1233859Sml29623 	"FFLP_FLOW_KEY_IP6_TCP_REG", "FFLP_FLOW_KEY_IP6_UDP_REG",
1243859Sml29623 	"FFLP_FLOW_KEY_IP6_AH_ESP_REG",
1253859Sml29623 	"FFLP_FLOW_KEY_IP6_SCTP_REG", "FFLP_H1POLY_REG", "FFLP_H2POLY_REG",
1263859Sml29623 	"FFLP_FLW_PRT_SEL_REG"
1273859Sml29623 };
1283859Sml29623 
1293859Sml29623 uint64_t fflp_reg_offset[] = {
1303859Sml29623 	FFLP_HASH_TBL_ADDR_REG, FFLP_HASH_TBL_DATA_REG,
1313859Sml29623 	FFLP_HASH_TBL_DATA_LOG_REG
1323859Sml29623 };
1333859Sml29623 
1343859Sml29623 const char *fflp_reg_name[] = {
1353859Sml29623 	"FFLP_HASH_TBL_ADDR_REG", "FFLP_HASH_TBL_DATA_REG",
1363859Sml29623 	"FFLP_HASH_TBL_DATA_LOG_REG"
1373859Sml29623 };
1383859Sml29623 
1393859Sml29623 
1403859Sml29623 
1413859Sml29623 
1423859Sml29623 npi_status_t
npi_fflp_dump_regs(npi_handle_t handle)1433859Sml29623 npi_fflp_dump_regs(npi_handle_t handle)
1443859Sml29623 {
1453859Sml29623 
1463859Sml29623 	uint64_t value;
1473859Sml29623 	int num_regs, i;
1483859Sml29623 
1493859Sml29623 	num_regs = sizeof (fflp_fzc_offset) / sizeof (uint64_t);
1503859Sml29623 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
1516929Smisaki 	    "\nFFLP_FZC Register Dump \n"));
1523859Sml29623 	for (i = 0; i < num_regs; i++) {
1533859Sml29623 		REG_PIO_READ64(handle, fflp_fzc_offset[i], &value);
1543859Sml29623 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
1556929Smisaki 		    " %8llx %s\t %8llx \n",
1566929Smisaki 		    fflp_fzc_offset[i], fflp_fzc_name[i], value));
1573859Sml29623 
1583859Sml29623 	}
1593859Sml29623 
1603859Sml29623 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
1616929Smisaki 	    "\nFFLP Register Dump\n"));
1623859Sml29623 	num_regs = sizeof (fflp_reg_offset) / sizeof (uint64_t);
1633859Sml29623 
1643859Sml29623 	for (i = 0; i < num_regs; i++) {
1653859Sml29623 		REG_PIO_READ64(handle, fflp_reg_offset[i], &value);
1663859Sml29623 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
1676929Smisaki 		    " %8llx %s\t %8llx \n",
1686929Smisaki 		    fflp_reg_offset[i], fflp_reg_name[i], value));
1693859Sml29623 
1703859Sml29623 	}
1713859Sml29623 
1723859Sml29623 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
1736929Smisaki 	    "\n FFLP Register Dump done\n"));
1743859Sml29623 
1753859Sml29623 	return (NPI_SUCCESS);
1763859Sml29623 }
1773859Sml29623 
1783859Sml29623 void
npi_fflp_vlan_tbl_dump(npi_handle_t handle)1793859Sml29623 npi_fflp_vlan_tbl_dump(npi_handle_t handle)
1803859Sml29623 {
1813859Sml29623 	uint64_t offset;
1823859Sml29623 	vlan_id_t vlan_id;
1833859Sml29623 	uint64_t value;
1843859Sml29623 	vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
1853859Sml29623 
1863859Sml29623 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
1876929Smisaki 	    "\nVlan Table Dump \n"));
1883859Sml29623 
1893859Sml29623 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
1906929Smisaki 	    "VID\t Offset\t Value\n"));
1913859Sml29623 
1923859Sml29623 	for (vlan_id = start; vlan_id < stop; vlan_id++) {
1933859Sml29623 		offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
1943859Sml29623 		REG_PIO_READ64(handle, offset, &value);
1953859Sml29623 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
1966929Smisaki 		    "%x\t %llx\t %llx\n", vlan_id, offset, value));
1973859Sml29623 	}
1983859Sml29623 
1993859Sml29623 }
2003859Sml29623 
2013859Sml29623 static uint64_t
2023859Sml29623 npi_fflp_tcam_check_completion(npi_handle_t handle, tcam_op_t op_type);
2033859Sml29623 
2043859Sml29623 /*
2053859Sml29623  * npi_fflp_tcam_check_completion()
2063859Sml29623  * Returns TCAM completion status.
2073859Sml29623  *
2083859Sml29623  * Input:
2093859Sml29623  *           op_type :        Read, Write, Compare
2103859Sml29623  *           handle  :        OS specific handle
2113859Sml29623  *
2123859Sml29623  * Output:
2133859Sml29623  *        For Read and write operations:
2143859Sml29623  *        0   Successful
2153859Sml29623  *        -1  Fail/timeout
2163859Sml29623  *
2173859Sml29623  *       For Compare operations (debug only )
2183859Sml29623  *        TCAM_REG_CTL read value    on success
2193859Sml29623  *                     value contains match location
2203859Sml29623  *        NPI_TCAM_COMP_NO_MATCH          no match
2213859Sml29623  *
2223859Sml29623  */
2233859Sml29623 static uint64_t
npi_fflp_tcam_check_completion(npi_handle_t handle,tcam_op_t op_type)2243859Sml29623 npi_fflp_tcam_check_completion(npi_handle_t handle, tcam_op_t op_type)
2253859Sml29623 {
2263859Sml29623 
2273859Sml29623 	uint32_t try_counter, tcam_delay = 10;
2283859Sml29623 	tcam_ctl_t tctl;
2293859Sml29623 
2303859Sml29623 	try_counter = TCAM_COMPLETION_TRY_COUNT;
2313859Sml29623 
2323859Sml29623 	switch (op_type) {
2333859Sml29623 	case TCAM_RWC_STAT:
2343859Sml29623 
2353859Sml29623 		READ_TCAM_REG_CTL(handle, &tctl.value);
2363859Sml29623 		while ((try_counter) &&
2376929Smisaki 		    (tctl.bits.ldw.stat != TCAM_CTL_RWC_RWC_STAT)) {
2383859Sml29623 			try_counter--;
2393859Sml29623 			NXGE_DELAY(tcam_delay);
2403859Sml29623 			READ_TCAM_REG_CTL(handle, &tctl.value);
2413859Sml29623 		}
2423859Sml29623 
2433859Sml29623 		if (!try_counter) {
2443859Sml29623 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2456929Smisaki 			    " TCAM RWC_STAT operation"
2466929Smisaki 			    " failed to complete \n"));
2473859Sml29623 			return (NPI_FFLP_TCAM_HW_ERROR);
2483859Sml29623 		}
2493859Sml29623 
2503859Sml29623 		tctl.value = 0;
2513859Sml29623 		break;
2523859Sml29623 
2533859Sml29623 	case TCAM_RWC_MATCH:
2543859Sml29623 		READ_TCAM_REG_CTL(handle, &tctl.value);
2553859Sml29623 
2563859Sml29623 		while ((try_counter) &&
2576929Smisaki 		    (tctl.bits.ldw.match != TCAM_CTL_RWC_RWC_MATCH)) {
2583859Sml29623 			try_counter--;
2593859Sml29623 			NXGE_DELAY(tcam_delay);
2603859Sml29623 			READ_TCAM_REG_CTL(handle, &tctl.value);
2613859Sml29623 		}
2623859Sml29623 
2633859Sml29623 		if (!try_counter) {
2643859Sml29623 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2656929Smisaki 			    " TCAM Match operation"
2666929Smisaki 			    "failed to find match \n"));
2673859Sml29623 			tctl.value = NPI_TCAM_COMP_NO_MATCH;
2683859Sml29623 		}
2693859Sml29623 
2703859Sml29623 
2713859Sml29623 		break;
2723859Sml29623 
2733859Sml29623 	default:
2743859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2753859Sml29623 		" Invalid TCAM completion Request \n"));
2763859Sml29623 		return (NPI_FFLP_ERROR |
2773859Sml29623 		    NPI_TCAM_ERROR | OPCODE_INVALID);
2783859Sml29623 	}
2793859Sml29623 
2803859Sml29623 	return (tctl.value);
2813859Sml29623 }
2823859Sml29623 
2833859Sml29623 /*
2843859Sml29623  * npi_fflp_tcam_entry_invalidate()
2853859Sml29623  *
2863859Sml29623  * invalidates entry at tcam location
2873859Sml29623  *
2883859Sml29623  * Input
2893859Sml29623  * handle  :        OS specific handle
2903859Sml29623  * location	:	TCAM location
2913859Sml29623  *
2923859Sml29623  * Return
2933859Sml29623  *   NPI_SUCCESS
2943859Sml29623  *   NPI_FFLP_TCAM_HW_ERROR
2953859Sml29623  *
2963859Sml29623  */
2973859Sml29623 npi_status_t
npi_fflp_tcam_entry_invalidate(npi_handle_t handle,tcam_location_t location)2983859Sml29623 npi_fflp_tcam_entry_invalidate(npi_handle_t handle, tcam_location_t location)
2993859Sml29623 {
3003859Sml29623 
3013859Sml29623 	tcam_ctl_t tctl, tctl_stat;
3023859Sml29623 
3033859Sml29623 /*
3043859Sml29623  * Need to write zero to class field.
3053859Sml29623  * Class field is bits [195:191].
3063859Sml29623  * This corresponds to TCAM key 0 register
3073859Sml29623  *
3083859Sml29623  */
3093859Sml29623 
3103859Sml29623 
3113859Sml29623 	WRITE_TCAM_REG_MASK0(handle, 0xffULL);
3123859Sml29623 	WRITE_TCAM_REG_KEY0(handle, 0x0ULL);
3133859Sml29623 	tctl.value = 0;
3143859Sml29623 	tctl.bits.ldw.location = location;
3153859Sml29623 	tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_WR;
3163859Sml29623 
3173859Sml29623 	WRITE_TCAM_REG_CTL(handle, tctl.value);
3183859Sml29623 
3193859Sml29623 	tctl_stat.value = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
3203859Sml29623 
3213859Sml29623 	if (tctl_stat.value & NPI_FAILURE)
3223859Sml29623 		return (NPI_FFLP_TCAM_HW_ERROR);
3233859Sml29623 
3243859Sml29623 	return (NPI_SUCCESS);
3253859Sml29623 
3263859Sml29623 }
3273859Sml29623 
3283859Sml29623 /*
3293859Sml29623  * npi_fflp_tcam_entry_match()
3303859Sml29623  *
3313859Sml29623  * lookup a tcam entry in the TCAM
3323859Sml29623  *
3333859Sml29623  * Input
3343859Sml29623  * handle  :        OS specific handle
3353859Sml29623  * tcam_ptr   :     TCAM entry ptr
3363859Sml29623  *
3373859Sml29623  * Return
3383859Sml29623  *
3393859Sml29623  *	 NPI_FAILURE | NPI_XX_ERROR:	     Operational Error (HW etc ...)
3403859Sml29623  *	 NPI_TCAM_NO_MATCH:		     no match
3413859Sml29623  *	 0 - TCAM_SIZE:			     matching entry location (if match)
3423859Sml29623  */
3433859Sml29623 int
npi_fflp_tcam_entry_match(npi_handle_t handle,tcam_entry_t * tcam_ptr)3443859Sml29623 npi_fflp_tcam_entry_match(npi_handle_t handle,  tcam_entry_t *tcam_ptr)
3453859Sml29623 {
3463859Sml29623 
3473859Sml29623 	uint64_t tcam_stat = 0;
3483859Sml29623 	tcam_ctl_t tctl, tctl_stat;
3493859Sml29623 
3503859Sml29623 	WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0);
3513859Sml29623 	WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1);
3523859Sml29623 	WRITE_TCAM_REG_MASK2(handle, tcam_ptr->mask2);
3533859Sml29623 	WRITE_TCAM_REG_MASK3(handle, tcam_ptr->mask3);
3543859Sml29623 
3553859Sml29623 	WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0);
3563859Sml29623 	WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1);
3573859Sml29623 	WRITE_TCAM_REG_KEY2(handle, tcam_ptr->key2);
3583859Sml29623 	WRITE_TCAM_REG_KEY3(handle, tcam_ptr->key3);
3593859Sml29623 
3603859Sml29623 	tctl.value = 0;
3613859Sml29623 	tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_CMP;
3623859Sml29623 
3633859Sml29623 	WRITE_TCAM_REG_CTL(handle, tctl.value);
3643859Sml29623 
3653859Sml29623 	tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
3663859Sml29623 	if (tcam_stat & NPI_FAILURE) {
3673859Sml29623 		return ((uint32_t)tcam_stat);
3683859Sml29623 	}
3693859Sml29623 
3703859Sml29623 	tctl_stat.value = npi_fflp_tcam_check_completion(handle,
3716929Smisaki 	    TCAM_RWC_MATCH);
3723859Sml29623 
3733859Sml29623 	if (tctl_stat.bits.ldw.match == TCAM_CTL_RWC_RWC_MATCH) {
3743859Sml29623 		return (uint32_t)(tctl_stat.bits.ldw.location);
3753859Sml29623 	}
3763859Sml29623 
3773859Sml29623 	return ((uint32_t)tctl_stat.value);
3783859Sml29623 
3793859Sml29623 }
3803859Sml29623 
3813859Sml29623 /*
3823859Sml29623  * npi_fflp_tcam_entry_read ()
3833859Sml29623  *
3843859Sml29623  * Reads a tcam entry from the TCAM location, location
3853859Sml29623  *
3863859Sml29623  * Input:
3873859Sml29623  * handle  :        OS specific handle
3883859Sml29623  * location  :		TCAM location
3893859Sml29623  * tcam_ptr  :		TCAM entry pointer
3903859Sml29623  *
3913859Sml29623  * Return:
3923859Sml29623  * NPI_SUCCESS
3933859Sml29623  * NPI_FFLP_TCAM_RD_ERROR
3943859Sml29623  *
3953859Sml29623  */
3963859Sml29623 npi_status_t
npi_fflp_tcam_entry_read(npi_handle_t handle,tcam_location_t location,struct tcam_entry * tcam_ptr)3973859Sml29623 npi_fflp_tcam_entry_read(npi_handle_t handle,
3983859Sml29623 						    tcam_location_t location,
3993859Sml29623 						    struct tcam_entry *tcam_ptr)
4003859Sml29623 {
4013859Sml29623 
4023859Sml29623 	uint64_t tcam_stat;
4033859Sml29623 	tcam_ctl_t tctl;
4043859Sml29623 
4053859Sml29623 	tctl.value = 0;
4063859Sml29623 	tctl.bits.ldw.location = location;
4073859Sml29623 	tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_RD;
4083859Sml29623 
4093859Sml29623 	WRITE_TCAM_REG_CTL(handle, tctl.value);
4103859Sml29623 
4113859Sml29623 	tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
4123859Sml29623 
4133859Sml29623 	if (tcam_stat & NPI_FAILURE) {
4143859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
4153859Sml29623 		    "TCAM read failed loc %d \n", location));
4163859Sml29623 		return (NPI_FFLP_TCAM_RD_ERROR);
4173859Sml29623 	}
4183859Sml29623 
4193859Sml29623 	READ_TCAM_REG_MASK0(handle, &tcam_ptr->mask0);
4203859Sml29623 	READ_TCAM_REG_MASK1(handle, &tcam_ptr->mask1);
4213859Sml29623 	READ_TCAM_REG_MASK2(handle, &tcam_ptr->mask2);
4223859Sml29623 	READ_TCAM_REG_MASK3(handle, &tcam_ptr->mask3);
4233859Sml29623 
4243859Sml29623 	READ_TCAM_REG_KEY0(handle, &tcam_ptr->key0);
4253859Sml29623 	READ_TCAM_REG_KEY1(handle, &tcam_ptr->key1);
4263859Sml29623 	READ_TCAM_REG_KEY2(handle, &tcam_ptr->key2);
4273859Sml29623 	READ_TCAM_REG_KEY3(handle, &tcam_ptr->key3);
4283859Sml29623 
4293859Sml29623 	return (NPI_SUCCESS);
4303859Sml29623 }
4313859Sml29623 
4323859Sml29623 /*
4333859Sml29623  * npi_fflp_tcam_entry_write()
4343859Sml29623  *
4353859Sml29623  * writes a tcam entry to the TCAM location, location
4363859Sml29623  *
4373859Sml29623  * Input:
4383859Sml29623  * handle  :        OS specific handle
4393859Sml29623  * location :	TCAM location
4403859Sml29623  * tcam_ptr :	TCAM entry pointer
4413859Sml29623  *
4423859Sml29623  * Return:
4433859Sml29623  * NPI_SUCCESS
4443859Sml29623  * NPI_FFLP_TCAM_WR_ERROR
4453859Sml29623  *
4463859Sml29623  */
4473859Sml29623 npi_status_t
npi_fflp_tcam_entry_write(npi_handle_t handle,tcam_location_t location,tcam_entry_t * tcam_ptr)4483859Sml29623 npi_fflp_tcam_entry_write(npi_handle_t handle,
4493859Sml29623 			    tcam_location_t location,
4503859Sml29623 			    tcam_entry_t *tcam_ptr)
4513859Sml29623 {
4523859Sml29623 
4533859Sml29623 	uint64_t tcam_stat;
4543859Sml29623 
4553859Sml29623 	tcam_ctl_t tctl;
4563859Sml29623 
4573859Sml29623 	WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0);
4583859Sml29623 	WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1);
4593859Sml29623 	WRITE_TCAM_REG_MASK2(handle, tcam_ptr->mask2);
4603859Sml29623 	WRITE_TCAM_REG_MASK3(handle, tcam_ptr->mask3);
4613859Sml29623 
4623859Sml29623 	WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0);
4633859Sml29623 	WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1);
4643859Sml29623 	WRITE_TCAM_REG_KEY2(handle, tcam_ptr->key2);
4653859Sml29623 	WRITE_TCAM_REG_KEY3(handle, tcam_ptr->key3);
4663859Sml29623 
4673859Sml29623 	NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
4686929Smisaki 	    " tcam write: location %x\n"
4696929Smisaki 	    " key:  %llx %llx %llx %llx \n"
4706929Smisaki 	    " mask: %llx %llx %llx %llx \n",
4716929Smisaki 	    location, tcam_ptr->key0, tcam_ptr->key1,
4726929Smisaki 	    tcam_ptr->key2, tcam_ptr->key3,
4736929Smisaki 	    tcam_ptr->mask0, tcam_ptr->mask1,
4746929Smisaki 	    tcam_ptr->mask2, tcam_ptr->mask3));
4753859Sml29623 	tctl.value = 0;
4763859Sml29623 	tctl.bits.ldw.location = location;
4773859Sml29623 	tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_WR;
4783859Sml29623 	NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
4796929Smisaki 	    " tcam write: ctl value %llx \n", tctl.value));
4803859Sml29623 	WRITE_TCAM_REG_CTL(handle, tctl.value);
4813859Sml29623 
4823859Sml29623 	tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
4833859Sml29623 
4843859Sml29623 	if (tcam_stat & NPI_FAILURE) {
4853859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
4863859Sml29623 		    "TCAM Write failed loc %d \n", location));
4873859Sml29623 		return (NPI_FFLP_TCAM_WR_ERROR);
4883859Sml29623 	}
4893859Sml29623 
4903859Sml29623 	return (NPI_SUCCESS);
4913859Sml29623 }
4923859Sml29623 
4933859Sml29623 /*
4943859Sml29623  * npi_fflp_tcam_asc_ram_entry_write()
4953859Sml29623  *
4963859Sml29623  * writes a tcam associatedRAM at the TCAM location, location
4973859Sml29623  *
4983859Sml29623  * Input:
4993859Sml29623  * handle  :        OS specific handle
5003859Sml29623  * location :	tcam associatedRAM location
5013859Sml29623  * ram_data :	Value to write
5023859Sml29623  *
5033859Sml29623  * Return:
5043859Sml29623  * NPI_SUCCESS
5053859Sml29623  * NPI_FFLP_ASC_RAM_WR_ERROR
5063859Sml29623  *
5073859Sml29623  */
5083859Sml29623 npi_status_t
npi_fflp_tcam_asc_ram_entry_write(npi_handle_t handle,tcam_location_t location,uint64_t ram_data)5093859Sml29623 npi_fflp_tcam_asc_ram_entry_write(npi_handle_t handle,
5103859Sml29623 				    tcam_location_t location,
5113859Sml29623 				    uint64_t ram_data)
5123859Sml29623 {
5133859Sml29623 
5143859Sml29623 	uint64_t tcam_stat = 0;
5153859Sml29623 	tcam_ctl_t tctl;
5163859Sml29623 
5173859Sml29623 
5183859Sml29623 	WRITE_TCAM_REG_KEY1(handle, ram_data);
5193859Sml29623 
5203859Sml29623 	tctl.value = 0;
5213859Sml29623 	tctl.bits.ldw.location = location;
5223859Sml29623 	tctl.bits.ldw.rwc = TCAM_CTL_RWC_RAM_WR;
5233859Sml29623 
5243859Sml29623 	NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
5256929Smisaki 	    " tcam ascr write: location %x data %llx ctl value %llx \n",
5266929Smisaki 	    location, ram_data, tctl.value));
5273859Sml29623 	WRITE_TCAM_REG_CTL(handle, tctl.value);
5283859Sml29623 	tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
5293859Sml29623 
5303859Sml29623 	if (tcam_stat & NPI_FAILURE) {
5313859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
5323859Sml29623 		    "TCAM RAM write failed loc %d \n", location));
5333859Sml29623 		return (NPI_FFLP_ASC_RAM_WR_ERROR);
5343859Sml29623 	}
5353859Sml29623 
5363859Sml29623 	return (NPI_SUCCESS);
5373859Sml29623 }
5383859Sml29623 
5393859Sml29623 /*
5403859Sml29623  * npi_fflp_tcam_asc_ram_entry_read()
5413859Sml29623  *
5423859Sml29623  * reads a tcam associatedRAM content at the TCAM location, location
5433859Sml29623  *
5443859Sml29623  * Input:
5453859Sml29623  * handle  :        OS specific handle
5463859Sml29623  * location :	tcam associatedRAM location
5473859Sml29623  * ram_data :	ptr to return contents
5483859Sml29623  *
5493859Sml29623  * Return:
5503859Sml29623  * NPI_SUCCESS
5513859Sml29623  * NPI_FFLP_ASC_RAM_RD_ERROR
5523859Sml29623  *
5533859Sml29623  */
5543859Sml29623 npi_status_t
npi_fflp_tcam_asc_ram_entry_read(npi_handle_t handle,tcam_location_t location,uint64_t * ram_data)5553859Sml29623 npi_fflp_tcam_asc_ram_entry_read(npi_handle_t handle,
5563859Sml29623 				    tcam_location_t location,
5573859Sml29623 				    uint64_t *ram_data)
5583859Sml29623 {
5593859Sml29623 
5603859Sml29623 	uint64_t tcam_stat;
5613859Sml29623 	tcam_ctl_t tctl;
5623859Sml29623 
5633859Sml29623 
5643859Sml29623 	tctl.value = 0;
5653859Sml29623 	tctl.bits.ldw.location = location;
5663859Sml29623 	tctl.bits.ldw.rwc = TCAM_CTL_RWC_RAM_RD;
5673859Sml29623 
5683859Sml29623 	WRITE_TCAM_REG_CTL(handle, tctl.value);
5693859Sml29623 
5703859Sml29623 	tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
5713859Sml29623 
5723859Sml29623 	if (tcam_stat & NPI_FAILURE) {
5733859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
5743859Sml29623 		    "TCAM RAM read failed loc %d \n", location));
5753859Sml29623 		return (NPI_FFLP_ASC_RAM_RD_ERROR);
5763859Sml29623 	}
5773859Sml29623 
5783859Sml29623 	READ_TCAM_REG_KEY1(handle, ram_data);
5793859Sml29623 
5803859Sml29623 	return (NPI_SUCCESS);
5813859Sml29623 }
5823859Sml29623 
5833859Sml29623 /* FFLP FCRAM Related functions */
5843859Sml29623 /* The following are FCRAM datapath functions */
5853859Sml29623 
5863859Sml29623 /*
5873859Sml29623  * npi_fflp_fcram_entry_write ()
5883859Sml29623  * Populates an FCRAM entry
5893859Sml29623  * Inputs:
5903859Sml29623  *         handle:	opaque handle interpreted by the underlying OS
5913859Sml29623  *	   partid:	Partition ID
5923859Sml29623  *	   location:	Index to the FCRAM.
5933859Sml29623  *			 Corresponds to last 20 bits of H1 value
5943859Sml29623  *	   fcram_ptr:	Pointer to the FCRAM contents to be used for writing
5953859Sml29623  *	   format:	Entry Format. Determines the size of the write.
5963859Sml29623  *			      FCRAM_ENTRY_OPTIM:   8 bytes (a 64 bit write)
5973859Sml29623  *			      FCRAM_ENTRY_EX_IP4:  32 bytes (4 X 64 bit write)
5983859Sml29623  *			      FCRAM_ENTRY_EX_IP6:  56 bytes (7 X 64 bit write)
5993859Sml29623  *
6003859Sml29623  * Outputs:
6013859Sml29623  *         NPI success/failure status code
6023859Sml29623  */
6033859Sml29623 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)6043859Sml29623 npi_fflp_fcram_entry_write(npi_handle_t handle, part_id_t partid,
6053859Sml29623 			    uint32_t location, fcram_entry_t *fcram_ptr,
6063859Sml29623 			    fcram_entry_format_t format)
6073859Sml29623 
6083859Sml29623 {
6093859Sml29623 
6103859Sml29623 	int num_subareas = 0;
6113859Sml29623 	uint64_t addr_reg, data_reg;
6123859Sml29623 	int subarea;
6133859Sml29623 	int autoinc;
6143859Sml29623 	hash_tbl_addr_t addr;
6153859Sml29623 	switch (format) {
6163859Sml29623 	case FCRAM_ENTRY_OPTIM:
6173859Sml29623 		if (location % 8) {
6183859Sml29623 		/* need to be 8 byte alligned */
6193859Sml29623 
6203859Sml29623 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
6213859Sml29623 				    " FCRAM_ENTRY_OOPTIM Write:"
6223859Sml29623 				    " unaligned location %llx \n",
6233859Sml29623 				    location));
6243859Sml29623 
6253859Sml29623 			return (NPI_FFLP_FCRAM_LOC_INVALID);
6263859Sml29623 	}
6273859Sml29623 
6283859Sml29623 	num_subareas = 1;
6293859Sml29623 	autoinc = 0;
6303859Sml29623 	break;
6313859Sml29623 
6323859Sml29623 	case FCRAM_ENTRY_EX_IP4:
6333859Sml29623 		if (location % 32) {
6343859Sml29623 /* need to be 32 byte alligned */
6353859Sml29623 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
6363859Sml29623 			    " FCRAM_ENTRY_EX_IP4 Write:"
6373859Sml29623 			    " unaligned location %llx \n",
6383859Sml29623 			    location));
6393859Sml29623 			return (NPI_FFLP_FCRAM_LOC_INVALID);
6403859Sml29623 	}
6413859Sml29623 
6423859Sml29623 	num_subareas = 4;
6433859Sml29623 	autoinc = 1;
6443859Sml29623 
6453859Sml29623 	break;
6463859Sml29623 	case FCRAM_ENTRY_EX_IP6:
6473859Sml29623 		if (location % 64) {
6483859Sml29623 				/* need to be 64 byte alligned */
6493859Sml29623 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
6503859Sml29623 				    " FCRAM_ENTRY_EX_IP6 Write:"
6513859Sml29623 				    " unaligned location %llx \n",
6523859Sml29623 				    location));
6533859Sml29623 				return (NPI_FFLP_FCRAM_LOC_INVALID);
6543859Sml29623 
6553859Sml29623 		}
6563859Sml29623 		num_subareas = 7;
6573859Sml29623 		autoinc = 1;
6583859Sml29623 			break;
6593859Sml29623 	default:
6603859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
6613859Sml29623 			    " fcram_entry_write:"
6623859Sml29623 			    " unknown format param location %llx\n",
6633859Sml29623 			    location));
6643859Sml29623 		return (NPI_FFLP_ERROR | NPI_FCRAM_ERROR | OPCODE_INVALID);
6653859Sml29623 	}
6663859Sml29623 
6673859Sml29623 	addr.value = 0;
6683859Sml29623 	addr.bits.ldw.autoinc = autoinc;
6693859Sml29623 	addr.bits.ldw.addr = location;
6703859Sml29623 	addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
6713859Sml29623 					    FFLP_HASH_TBL_ADDR_REG);
6723859Sml29623 	data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
6733859Sml29623 					    FFLP_HASH_TBL_DATA_REG);
6743859Sml29623 /* write to addr reg */
6753859Sml29623 	REG_PIO_WRITE64(handle, addr_reg, addr.value);
6763859Sml29623 /* write data to the data register */
6773859Sml29623 
6783859Sml29623 	for (subarea = 0; subarea < num_subareas; subarea++) {
6793859Sml29623 		REG_PIO_WRITE64(handle, data_reg, fcram_ptr->value[subarea]);
6803859Sml29623 	}
6813859Sml29623 
6823859Sml29623 	return (NPI_SUCCESS);
6833859Sml29623 }
6843859Sml29623 
6853859Sml29623 /*
6863859Sml29623  * npi_fflp_fcram_read_read ()
6873859Sml29623  * Reads an FCRAM entry
6883859Sml29623  * Inputs:
6893859Sml29623  *         handle:	opaque handle interpreted by the underlying OS
6903859Sml29623  *	   partid:	Partition ID
6913859Sml29623  *	   location:	Index to the FCRAM.
6923859Sml29623  *                  Corresponds to last 20 bits of H1 value
6933859Sml29623  *
6943859Sml29623  *	   fcram_ptr:	Pointer to the FCRAM contents to be updated
6953859Sml29623  *	   format:	Entry Format. Determines the size of the read.
6963859Sml29623  *			      FCRAM_ENTRY_OPTIM:   8 bytes (a 64 bit read)
6973859Sml29623  *			      FCRAM_ENTRY_EX_IP4:  32 bytes (4 X 64 bit read )
6983859Sml29623  *			      FCRAM_ENTRY_EX_IP6:  56 bytes (7 X 64 bit read )
6993859Sml29623  * Return:
7003859Sml29623  * NPI Success/Failure status code
7013859Sml29623  *
7023859Sml29623  */
7033859Sml29623 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)7043859Sml29623 npi_fflp_fcram_entry_read(npi_handle_t handle,  part_id_t partid,
7053859Sml29623 			    uint32_t location, fcram_entry_t *fcram_ptr,
7063859Sml29623 			    fcram_entry_format_t format)
7073859Sml29623 {
7083859Sml29623 
7093859Sml29623 	int num_subareas = 0;
7103859Sml29623 	uint64_t addr_reg, data_reg;
7113859Sml29623 	int subarea, autoinc;
7123859Sml29623 	hash_tbl_addr_t addr;
7133859Sml29623 	switch (format) {
7143859Sml29623 		case FCRAM_ENTRY_OPTIM:
7153859Sml29623 			if (location % 8) {
7163859Sml29623 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
7176929Smisaki 			    " FCRAM_ENTRY_OOPTIM Read:"
7186929Smisaki 			    " unaligned location %llx \n",
7196929Smisaki 			    location));
7203859Sml29623 			/* need to be 8 byte alligned */
7213859Sml29623 				return (NPI_FFLP_FCRAM_LOC_INVALID);
7223859Sml29623 			}
7233859Sml29623 			num_subareas = 1;
7243859Sml29623 			autoinc = 0;
7253859Sml29623 			break;
7263859Sml29623 		case FCRAM_ENTRY_EX_IP4:
7273859Sml29623 			if (location % 32) {
7283859Sml29623 					/* need to be 32 byte alligned */
7293859Sml29623 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
7306929Smisaki 			    " FCRAM_ENTRY_EX_IP4 READ:"
7316929Smisaki 			    " unaligned location %llx \n",
7326929Smisaki 			    location));
7333859Sml29623 				return (NPI_FFLP_FCRAM_LOC_INVALID);
7343859Sml29623 			}
7353859Sml29623 			num_subareas = 4;
7363859Sml29623 			autoinc = 1;
7373859Sml29623 
7383859Sml29623 			break;
7393859Sml29623 		case FCRAM_ENTRY_EX_IP6:
7403859Sml29623 			if (location % 64) {
7413859Sml29623 					/* need to be 64 byte alligned */
7423859Sml29623 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
7436929Smisaki 			    " FCRAM_ENTRY_EX_IP6 READ:"
7446929Smisaki 			    " unaligned location %llx \n",
7456929Smisaki 			    location));
7463859Sml29623 
7473859Sml29623 				return (NPI_FFLP_FCRAM_LOC_INVALID);
7483859Sml29623 	}
7493859Sml29623 			num_subareas = 7;
7503859Sml29623 			autoinc = 1;
7513859Sml29623 
7523859Sml29623 			break;
7533859Sml29623 		default:
7543859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
7556929Smisaki 		    " fcram_entry_read:"
7566929Smisaki 		    " unknown format param location %llx\n",
7576929Smisaki 		    location));
7583859Sml29623 		return (NPI_FFLP_SW_PARAM_ERROR);
7593859Sml29623 	}
7603859Sml29623 
7613859Sml29623 	addr.value = 0;
7623859Sml29623 	addr.bits.ldw.autoinc = autoinc;
7633859Sml29623 	addr.bits.ldw.addr = location;
7643859Sml29623 	addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
7656929Smisaki 	    FFLP_HASH_TBL_ADDR_REG);
7663859Sml29623 	data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
7676929Smisaki 	    FFLP_HASH_TBL_DATA_REG);
7683859Sml29623 /* write to addr reg */
7693859Sml29623 	REG_PIO_WRITE64(handle, addr_reg, addr.value);
7703859Sml29623 /* read data from the data register */
7713859Sml29623 	for (subarea = 0; subarea < num_subareas; subarea++) {
7723859Sml29623 		REG_PIO_READ64(handle, data_reg, &fcram_ptr->value[subarea]);
7733859Sml29623 	}
7743859Sml29623 
7753859Sml29623 
7763859Sml29623 	return (NPI_SUCCESS);
7773859Sml29623 
7783859Sml29623 }
7793859Sml29623 
7803859Sml29623 /*
7813859Sml29623  * npi_fflp_fcram_entry_invalidate ()
7823859Sml29623  * Invalidate FCRAM entry at the given location
7833859Sml29623  * Inputs:
7843859Sml29623  *	handle:		opaque handle interpreted by the underlying OS
7853859Sml29623  *	partid:		Partition ID
7863859Sml29623  *	location:	location of the FCRAM/hash entry.
7873859Sml29623  *
7883859Sml29623  * Return:
7893859Sml29623  * NPI Success/Failure status code
7903859Sml29623  */
7913859Sml29623 npi_status_t
npi_fflp_fcram_entry_invalidate(npi_handle_t handle,part_id_t partid,uint32_t location)7923859Sml29623 npi_fflp_fcram_entry_invalidate(npi_handle_t handle, part_id_t partid,
7933859Sml29623 				    uint32_t location)
7943859Sml29623 {
7953859Sml29623 
7963859Sml29623 	hash_tbl_addr_t addr;
7973859Sml29623 	uint64_t addr_reg, data_reg;
7983859Sml29623 	hash_hdr_t	   hdr;
7993859Sml29623 
8003859Sml29623 
8013859Sml29623 	if (location % 8) {
8023859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
8036929Smisaki 		    " FCRAM_ENTRY_Invalidate:"
8046929Smisaki 		    " unaligned location %llx \n",
8056929Smisaki 		    location));
8063859Sml29623 			/* need to be 8 byte aligned */
8073859Sml29623 		return (NPI_FFLP_FCRAM_LOC_INVALID);
8083859Sml29623 	}
8093859Sml29623 
8103859Sml29623 	addr.value = 0;
8113859Sml29623 	addr.bits.ldw.addr = location;
8123859Sml29623 	addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
8136929Smisaki 	    FFLP_HASH_TBL_ADDR_REG);
8143859Sml29623 	data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
8156929Smisaki 	    FFLP_HASH_TBL_DATA_REG);
8163859Sml29623 
8173859Sml29623 /* write to addr reg */
8183859Sml29623 	REG_PIO_WRITE64(handle, addr_reg, addr.value);
8193859Sml29623 
8203859Sml29623 	REG_PIO_READ64(handle, data_reg, &hdr.value);
8213859Sml29623 	hdr.exact_hdr.valid = 0;
8223859Sml29623 	REG_PIO_WRITE64(handle, data_reg, hdr.value);
8233859Sml29623 
8243859Sml29623 	return (NPI_SUCCESS);
8253859Sml29623 
8263859Sml29623 }
8273859Sml29623 
8283859Sml29623 /*
8293859Sml29623  * npi_fflp_fcram_write_subarea ()
8303859Sml29623  * Writes to FCRAM entry subarea i.e the 8 bytes within the 64 bytes
8313859Sml29623  * pointed by the  last 20 bits of  H1. Effectively, this accesses
8323859Sml29623  * specific 8 bytes within the hash table bucket.
8333859Sml29623  *
8343859Sml29623  *  H1-->  |-----------------|
8353859Sml29623  *	   |	subarea 0    |
8363859Sml29623  *	   |_________________|
8373859Sml29623  *	   | Subarea 1	     |
8383859Sml29623  *	   |_________________|
8393859Sml29623  *	   | .......	     |
8403859Sml29623  *	   |_________________|
8413859Sml29623  *	   | Subarea 7       |
8423859Sml29623  *	   |_________________|
8433859Sml29623  *
8443859Sml29623  * Inputs:
8453859Sml29623  *         handle:	opaque handle interpreted by the underlying OS
8463859Sml29623  *	   partid:	Partition ID
8473859Sml29623  *	   location:	location of the subarea. It is derived from:
8483859Sml29623  *			Bucket = [19:15][14:0]       (20 bits of H1)
8493859Sml29623  *			location = (Bucket << 3 ) + subarea * 8
8503859Sml29623  *				 = [22:18][17:3] || subarea * 8
8513859Sml29623  *	   data:	Data
8523859Sml29623  *
8533859Sml29623  * Return:
8543859Sml29623  * NPI Success/Failure status code
8553859Sml29623  */
8563859Sml29623 npi_status_t
npi_fflp_fcram_subarea_write(npi_handle_t handle,part_id_t partid,uint32_t location,uint64_t data)8573859Sml29623 npi_fflp_fcram_subarea_write(npi_handle_t handle, part_id_t partid,
8583859Sml29623 			    uint32_t location, uint64_t data)
8593859Sml29623 {
8603859Sml29623 
8613859Sml29623 	hash_tbl_addr_t addr;
8623859Sml29623 	uint64_t addr_reg, data_reg;
8633859Sml29623 
8643859Sml29623 
8653859Sml29623 	if (location % 8) {
8663859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
8676929Smisaki 		    " fcram_subarea_write:"
8686929Smisaki 		    " unaligned location %llx \n",
8696929Smisaki 		    location));
8703859Sml29623 			/* need to be 8 byte alligned */
8713859Sml29623 		return (NPI_FFLP_FCRAM_LOC_INVALID);
8723859Sml29623 	}
8733859Sml29623 
8743859Sml29623 	addr.value = 0;
8753859Sml29623 	addr.bits.ldw.addr = location;
8763859Sml29623 	addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
8776929Smisaki 	    FFLP_HASH_TBL_ADDR_REG);
8783859Sml29623 	data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
8796929Smisaki 	    FFLP_HASH_TBL_DATA_REG);
8803859Sml29623 
8813859Sml29623 /* write to addr reg */
8823859Sml29623 	REG_PIO_WRITE64(handle, addr_reg, addr.value);
8833859Sml29623 	REG_PIO_WRITE64(handle, data_reg, data);
8843859Sml29623 
8853859Sml29623 	return (NPI_SUCCESS);
8863859Sml29623 
8873859Sml29623 }
8883859Sml29623 
8893859Sml29623 /*
8903859Sml29623  * npi_fflp_fcram_subarea_read ()
8913859Sml29623  * Reads an FCRAM entry subarea i.e the 8 bytes within the 64 bytes
8923859Sml29623  * pointed by  the last 20 bits of  H1. Effectively, this accesses
8933859Sml29623  * specific 8 bytes within the hash table bucket.
8943859Sml29623  *
8953859Sml29623  *  H1-->  |-----------------|
8963859Sml29623  *	   |	subarea 0    |
8973859Sml29623  *	   |_________________|
8983859Sml29623  *	   | Subarea 1	     |
8993859Sml29623  *	   |_________________|
9003859Sml29623  *	   | .......	     |
9013859Sml29623  *	   |_________________|
9023859Sml29623  *	   | Subarea 7       |
9033859Sml29623  *	   |_________________|
9043859Sml29623  *
9053859Sml29623  * Inputs:
9063859Sml29623  *         handle:	opaque handle interpreted by the underlying OS
9073859Sml29623  *	   partid:	Partition ID
9083859Sml29623  *	   location:	location of the subarea. It is derived from:
9093859Sml29623  *			Bucket = [19:15][14:0]       (20 bits of H1)
9103859Sml29623  *			location = (Bucket << 3 ) + subarea * 8
9113859Sml29623  *				 = [22:18][17:3] || subarea * 8
9123859Sml29623  *	   data:	ptr do write subarea contents to.
9133859Sml29623  *
9143859Sml29623  * Return:
9153859Sml29623  * NPI Success/Failure status code
9163859Sml29623  */
9173859Sml29623 npi_status_t
npi_fflp_fcram_subarea_read(npi_handle_t handle,part_id_t partid,uint32_t location,uint64_t * data)9183859Sml29623 npi_fflp_fcram_subarea_read(npi_handle_t handle, part_id_t partid,
9193859Sml29623 			    uint32_t location, uint64_t *data)
9203859Sml29623 
9213859Sml29623 {
9223859Sml29623 
9233859Sml29623 	hash_tbl_addr_t addr;
9243859Sml29623 	uint64_t addr_reg, data_reg;
9253859Sml29623 
9263859Sml29623 	if (location % 8) {
9273859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
9283859Sml29623 				    " fcram_subarea_read:"
9293859Sml29623 				    " unaligned location %llx \n",
9303859Sml29623 				    location));
9313859Sml29623 			/* need to be 8 byte alligned */
9323859Sml29623 		return (NPI_FFLP_FCRAM_LOC_INVALID);
9333859Sml29623 	}
9343859Sml29623 
9353859Sml29623 	addr.value = 0;
9363859Sml29623 	addr.bits.ldw.addr = location;
9373859Sml29623 	addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
9383859Sml29623 						    FFLP_HASH_TBL_ADDR_REG);
9393859Sml29623 	data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
9403859Sml29623 						    FFLP_HASH_TBL_DATA_REG);
9413859Sml29623 
9423859Sml29623 /* write to addr reg */
9433859Sml29623 	REG_PIO_WRITE64(handle, addr_reg, addr.value);
9443859Sml29623 	REG_PIO_READ64(handle, data_reg, data);
9453859Sml29623 
9463859Sml29623 	return (NPI_SUCCESS);
9473859Sml29623 
9483859Sml29623 }
9493859Sml29623 
9503859Sml29623 /*
9513859Sml29623  * The following are zero function fflp configuration functions.
9523859Sml29623  */
9533859Sml29623 
9543859Sml29623 /*
9553859Sml29623  * npi_fflp_fcram_config_partition()
9563859Sml29623  * Partitions and configures the FCRAM
9573859Sml29623  */
9583859Sml29623 npi_status_t
npi_fflp_cfg_fcram_partition(npi_handle_t handle,part_id_t partid,uint8_t base_mask,uint8_t base_reloc)9593859Sml29623 npi_fflp_cfg_fcram_partition(npi_handle_t handle, part_id_t partid,
9603859Sml29623 				    uint8_t base_mask, uint8_t base_reloc)
9613859Sml29623 
9623859Sml29623 {
9633859Sml29623 /*
9643859Sml29623  * assumes that the base mask and relocation are computed somewhere
9653859Sml29623  * and kept in the state data structure. Alternativiely, one can pass
9663859Sml29623  * a partition size and a starting address and this routine can compute
9673859Sml29623  * the mask and reloc vlaues.
9683859Sml29623  */
9693859Sml29623 
9703859Sml29623     flow_prt_sel_t sel;
9713859Sml29623     uint64_t offset;
9723859Sml29623 
9733859Sml29623     ASSERT(FCRAM_PARTITION_VALID(partid));
9743859Sml29623 	if (!FCRAM_PARTITION_VALID(partid)) {
9753859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
9763859Sml29623 				    " npi_fflp_cfg_fcram_partition:"
9773859Sml29623 				    " Invalid Partition %d \n",
9783859Sml29623 				    partid));
9793859Sml29623 		return (NPI_FFLP_FCRAM_PART_INVALID);
9803859Sml29623 	}
9813859Sml29623 
9823859Sml29623     offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
9833859Sml29623     sel.value = 0;
9843859Sml29623     sel.bits.ldw.mask = base_mask;
9853859Sml29623     sel.bits.ldw.base = base_reloc;
9863859Sml29623     sel.bits.ldw.ext = BIT_DISABLE; /* disable */
9873859Sml29623     REG_PIO_WRITE64(handle, offset, sel.value);
9883859Sml29623     return (NPI_SUCCESS);
9893859Sml29623 
9903859Sml29623 }
9913859Sml29623 
9923859Sml29623 /*
9933859Sml29623  * npi_fflp_fcram_partition_enable
9943859Sml29623  * Enable previously configured FCRAM partition
9953859Sml29623  *
9963859Sml29623  * Input
9973859Sml29623  *         handle:	opaque handle interpreted by the underlying OS
9983859Sml29623  *         partid:	 partition ID, Corresponds to the RDC table
9993859Sml29623  *
10003859Sml29623  * Return
10013859Sml29623  *      0			Successful
10023859Sml29623  *      Non zero  error code    Enable failed, and reason.
10033859Sml29623  *
10043859Sml29623  */
10053859Sml29623 npi_status_t
npi_fflp_cfg_fcram_partition_enable(npi_handle_t handle,part_id_t partid)10063859Sml29623 npi_fflp_cfg_fcram_partition_enable  (npi_handle_t handle, part_id_t partid)
10073859Sml29623 
10083859Sml29623 {
10093859Sml29623 
10103859Sml29623     flow_prt_sel_t sel;
10113859Sml29623     uint64_t offset;
10123859Sml29623 
10133859Sml29623     ASSERT(FCRAM_PARTITION_VALID(partid));
10143859Sml29623     if (!FCRAM_PARTITION_VALID(partid)) {
10153859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
10163859Sml29623 				    " fcram_partition enable:"
10173859Sml29623 				    " Invalid Partition %d \n",
10183859Sml29623 				    partid));
10193859Sml29623 		return (NPI_FFLP_FCRAM_PART_INVALID);
10203859Sml29623 	}
10213859Sml29623 
10223859Sml29623     offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
10233859Sml29623 
10243859Sml29623     REG_PIO_READ64(handle, offset, &sel.value);
10253859Sml29623     sel.bits.ldw.ext = BIT_ENABLE; /* enable */
10263859Sml29623     REG_PIO_WRITE64(handle, offset, sel.value);
10273859Sml29623 
10283859Sml29623     return (NPI_SUCCESS);
10293859Sml29623 
10303859Sml29623 }
10313859Sml29623 
10323859Sml29623 /*
10333859Sml29623  * npi_fflp_fcram_partition_disable
10343859Sml29623  * Disable previously configured FCRAM partition
10353859Sml29623  *
10363859Sml29623  * Input
10373859Sml29623  *         handle:	opaque handle interpreted by the underlying OS
10383859Sml29623  *         partid:	partition ID, Corresponds to the RDC table
10393859Sml29623  *
10403859Sml29623  * Return:
10413859Sml29623  * NPI Success/Failure status code
10423859Sml29623  */
10433859Sml29623 npi_status_t
npi_fflp_cfg_fcram_partition_disable(npi_handle_t handle,part_id_t partid)10443859Sml29623 npi_fflp_cfg_fcram_partition_disable(npi_handle_t handle, part_id_t partid)
10453859Sml29623 
10463859Sml29623 {
10473859Sml29623 
10483859Sml29623 	flow_prt_sel_t sel;
10493859Sml29623 	uint64_t offset;
10503859Sml29623 
10513859Sml29623 	ASSERT(FCRAM_PARTITION_VALID(partid));
10523859Sml29623 	if (!FCRAM_PARTITION_VALID(partid)) {
10533859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
10543859Sml29623 				    " fcram_partition disable:"
10553859Sml29623 				    " Invalid Partition %d \n",
10563859Sml29623 				    partid));
10573859Sml29623 		return (NPI_FFLP_FCRAM_PART_INVALID);
10583859Sml29623 	}
10593859Sml29623 	offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
10603859Sml29623 	REG_PIO_READ64(handle, offset, &sel.value);
10613859Sml29623 	sel.bits.ldw.ext = BIT_DISABLE; /* disable */
10623859Sml29623 	REG_PIO_WRITE64(handle, offset, sel.value);
10633859Sml29623 	return (NPI_SUCCESS);
10643859Sml29623 }
10653859Sml29623 
10663859Sml29623 /*
10673859Sml29623  *  npi_fflp_cam_errorcheck_disable
10683859Sml29623  *  Disables FCRAM and TCAM error checking
10693859Sml29623  */
10703859Sml29623 npi_status_t
npi_fflp_cfg_cam_errorcheck_disable(npi_handle_t handle)10713859Sml29623 npi_fflp_cfg_cam_errorcheck_disable(npi_handle_t handle)
10723859Sml29623 
10733859Sml29623 {
10743859Sml29623 
10753859Sml29623 	fflp_cfg_1_t fflp_cfg;
10763859Sml29623 	uint64_t offset;
10773859Sml29623 	offset = FFLP_CFG_1_REG;
10783859Sml29623 
10793859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
10803859Sml29623 
10813859Sml29623 	fflp_cfg.bits.ldw.errordis = BIT_ENABLE;
10823859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
10833859Sml29623 
10843859Sml29623 	return (NPI_SUCCESS);
10853859Sml29623 
10863859Sml29623 }
10873859Sml29623 
10883859Sml29623 /*
10893859Sml29623  *  npi_fflp_cam_errorcheck_enable
10903859Sml29623  *  Enables FCRAM and TCAM error checking
10913859Sml29623  */
10923859Sml29623 npi_status_t
npi_fflp_cfg_cam_errorcheck_enable(npi_handle_t handle)10933859Sml29623 npi_fflp_cfg_cam_errorcheck_enable(npi_handle_t handle)
10943859Sml29623 
10953859Sml29623 {
10963859Sml29623 	fflp_cfg_1_t fflp_cfg;
10973859Sml29623 	uint64_t offset;
10983859Sml29623 	offset = FFLP_CFG_1_REG;
10993859Sml29623 
11003859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
11013859Sml29623 
11023859Sml29623 	fflp_cfg.bits.ldw.errordis = BIT_DISABLE;
11033859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
11043859Sml29623 
11053859Sml29623 	return (NPI_SUCCESS);
11063859Sml29623 
11073859Sml29623 }
11083859Sml29623 
11093859Sml29623 /*
11103859Sml29623  *  npi_fflp_cam_llcsnap_enable
11113859Sml29623  *  Enables input parser llcsnap recognition
11123859Sml29623  */
11133859Sml29623 npi_status_t
npi_fflp_cfg_llcsnap_enable(npi_handle_t handle)11143859Sml29623 npi_fflp_cfg_llcsnap_enable(npi_handle_t handle)
11153859Sml29623 
11163859Sml29623 {
11173859Sml29623 
11183859Sml29623 	fflp_cfg_1_t fflp_cfg;
11193859Sml29623 	uint64_t offset;
11203859Sml29623 	offset = FFLP_CFG_1_REG;
11213859Sml29623 
11223859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
11233859Sml29623 
11243859Sml29623 	fflp_cfg.bits.ldw.llcsnap = BIT_ENABLE;
11253859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
11263859Sml29623 
11273859Sml29623 	return (NPI_SUCCESS);
11283859Sml29623 
11293859Sml29623 }
11303859Sml29623 
11313859Sml29623 /*
11323859Sml29623  *  npi_fflp_cam_llcsnap_disable
11333859Sml29623  *  Disables input parser llcsnap recognition
11343859Sml29623  */
11353859Sml29623 npi_status_t
npi_fflp_cfg_llcsnap_disable(npi_handle_t handle)11363859Sml29623 npi_fflp_cfg_llcsnap_disable(npi_handle_t handle)
11373859Sml29623 
11383859Sml29623 {
11393859Sml29623 
11403859Sml29623 
11413859Sml29623 	fflp_cfg_1_t fflp_cfg;
11423859Sml29623 	uint64_t offset;
11433859Sml29623 	offset = FFLP_CFG_1_REG;
11443859Sml29623 
11453859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
11463859Sml29623 
11473859Sml29623 	fflp_cfg.bits.ldw.llcsnap = BIT_DISABLE;
11483859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
11493859Sml29623 
11503859Sml29623 	return (NPI_SUCCESS);
11513859Sml29623 
11523859Sml29623 }
11533859Sml29623 
11543859Sml29623 /*
11553859Sml29623  * npi_fflp_config_fcram_refresh
11563859Sml29623  * Set FCRAM min and max refresh time.
11573859Sml29623  *
11583859Sml29623  * Input
11593859Sml29623  *      handle			opaque handle interpreted by the underlying OS
11603859Sml29623  *	min_time		Minimum Refresh time count
11613859Sml29623  *	max_time		maximum Refresh Time count
11623859Sml29623  *	sys_time		System Clock rate
11633859Sml29623  *
11643859Sml29623  *	The counters are 16 bit counters. The maximum refresh time is
11653859Sml29623  *      3.9us/clock cycle. The minimum is 400ns/clock cycle.
11663859Sml29623  *	Clock cycle is the FCRAM clock cycle?????
11673859Sml29623  *	If the cycle is FCRAM clock cycle, then sys_time parameter
11683859Sml29623  *      is not needed as there wont be configuration variation due to
11693859Sml29623  *      system clock cycle.
11703859Sml29623  *
11713859Sml29623  * Return:
11723859Sml29623  * NPI Success/Failure status code
11733859Sml29623  */
11743859Sml29623 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)11753859Sml29623 npi_fflp_cfg_fcram_refresh_time(npi_handle_t handle, uint32_t min_time,
11763859Sml29623 				    uint32_t max_time, uint32_t sys_time)
11773859Sml29623 
11783859Sml29623 {
11793859Sml29623 
11803859Sml29623 	uint64_t offset;
11813859Sml29623 	fcram_ref_tmr_t refresh_timer_reg;
11823859Sml29623 	uint16_t max, min;
11833859Sml29623 
11843859Sml29623 	offset = FFLP_FCRAM_REF_TMR_REG;
11853859Sml29623 /* need to figure out how to dervive the numbers */
11863859Sml29623 	max = max_time * sys_time;
11873859Sml29623 	min = min_time * sys_time;
11883859Sml29623 /* for now, just set with #def values */
11893859Sml29623 
11903859Sml29623 	max = FCRAM_REFRESH_DEFAULT_MAX_TIME;
11913859Sml29623 	min = FCRAM_REFRESH_DEFAULT_MIN_TIME;
11923859Sml29623 	REG_PIO_READ64(handle, offset, &refresh_timer_reg.value);
11933859Sml29623 	refresh_timer_reg.bits.ldw.min = min;
11943859Sml29623 	refresh_timer_reg.bits.ldw.max = max;
11953859Sml29623 	REG_PIO_WRITE64(handle, offset, refresh_timer_reg.value);
11963859Sml29623 	return (NPI_SUCCESS);
11973859Sml29623 }
11983859Sml29623 
11993859Sml29623 /*
12003859Sml29623  *  npi_fflp_hash_lookup_err_report
12013859Sml29623  *  Reports hash table (fcram) lookup errors
12023859Sml29623  *
12033859Sml29623  *  Input
12043859Sml29623  *      handle			opaque handle interpreted by the underlying OS
12053859Sml29623  *      err_stat		Pointer to return Error bits
12063859Sml29623  *
12073859Sml29623  *
12083859Sml29623  * Return:
12093859Sml29623  * NPI success/failure status code
12103859Sml29623  */
12113859Sml29623 npi_status_t
npi_fflp_fcram_get_lookup_err_log(npi_handle_t handle,hash_lookup_err_log_t * err_stat)12123859Sml29623 npi_fflp_fcram_get_lookup_err_log(npi_handle_t handle,
12133859Sml29623 				    hash_lookup_err_log_t *err_stat)
12143859Sml29623 
12153859Sml29623 {
12163859Sml29623 
12173859Sml29623 	hash_lookup_err_log1_t err_log1;
12183859Sml29623 	hash_lookup_err_log2_t err_log2;
12193859Sml29623 	uint64_t  err_log1_offset, err_log2_offset;
12203859Sml29623 	err_log1.value = 0;
12213859Sml29623 	err_log2.value = 0;
12223859Sml29623 
12233859Sml29623 	err_log1_offset = HASH_LKUP_ERR_LOG1_REG;
12243859Sml29623 	err_log2_offset = HASH_LKUP_ERR_LOG2_REG;
12253859Sml29623 
12263859Sml29623 	REG_PIO_READ64(handle, err_log1_offset, &err_log1.value);
12273859Sml29623 	REG_PIO_READ64(handle, err_log2_offset, &err_log2.value);
12283859Sml29623 
12293859Sml29623 	if (err_log1.value) {
12303859Sml29623 /* nonzero means there are some errors */
12313859Sml29623 		err_stat->lookup_err = BIT_ENABLE;
12323859Sml29623 		err_stat->syndrome = err_log2.bits.ldw.syndrome;
12333859Sml29623 		err_stat->subarea = err_log2.bits.ldw.subarea;
12343859Sml29623 		err_stat->h1 = err_log2.bits.ldw.h1;
12353859Sml29623 		err_stat->multi_bit = err_log1.bits.ldw.mult_bit;
12363859Sml29623 		err_stat->multi_lkup = err_log1.bits.ldw.mult_lk;
12373859Sml29623 		err_stat->ecc_err = err_log1.bits.ldw.ecc_err;
12383859Sml29623 		err_stat->uncor_err = err_log1.bits.ldw.cu;
12393859Sml29623 	} else {
12403859Sml29623 		err_stat->lookup_err = BIT_DISABLE;
12413859Sml29623 	}
12423859Sml29623 
12433859Sml29623 	return (NPI_SUCCESS);
12443859Sml29623 
12453859Sml29623 }
12463859Sml29623 
12473859Sml29623 /*
12483859Sml29623  * npi_fflp_fcram_get_pio_err_log
12493859Sml29623  * Reports hash table PIO read errors for the given partition.
12503859Sml29623  * by default, it clears the error bit which was set by the HW.
12513859Sml29623  *
12523859Sml29623  * Input
12533859Sml29623  *      handle:		opaque handle interpreted by the underlying OS
12543859Sml29623  *	partid:		partition ID
12553859Sml29623  *      err_stat	Pointer to return Error bits
12563859Sml29623  *
12573859Sml29623  * Return
12583859Sml29623  *	NPI success/failure status code
12593859Sml29623  */
12603859Sml29623 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)12613859Sml29623 npi_fflp_fcram_get_pio_err_log(npi_handle_t handle, part_id_t partid,
12623859Sml29623 				    hash_pio_err_log_t *err_stat)
12633859Sml29623 {
12643859Sml29623 
12653859Sml29623 	hash_tbl_data_log_t err_log;
12663859Sml29623 	uint64_t offset;
12673859Sml29623 
12683859Sml29623 	ASSERT(FCRAM_PARTITION_VALID(partid));
12693859Sml29623 	if (!FCRAM_PARTITION_VALID(partid)) {
12703859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
12716929Smisaki 		    " fcram_get_pio_err_log:"
12726929Smisaki 		    " Invalid Partition %d \n",
12736929Smisaki 		    partid));
12743859Sml29623 		return (NPI_FFLP_FCRAM_PART_INVALID);
12753859Sml29623 	}
12763859Sml29623 
12773859Sml29623 	offset = GET_HASHTBL_PART_OFFSET_NVIR(partid,
12786929Smisaki 	    FFLP_HASH_TBL_DATA_LOG_REG);
12793859Sml29623 
12803859Sml29623 	REG_PIO_READ64(handle, offset, &err_log.value);
12813859Sml29623 
12823859Sml29623 	if (err_log.bits.ldw.pio_err == BIT_ENABLE) {
12833859Sml29623 /* nonzero means there are some errors */
12843859Sml29623 		err_stat->pio_err = BIT_ENABLE;
12853859Sml29623 		err_stat->syndrome = err_log.bits.ldw.syndrome;
12863859Sml29623 		err_stat->addr = err_log.bits.ldw.fcram_addr;
12873859Sml29623 		err_log.value = 0;
12883859Sml29623 		REG_PIO_WRITE64(handle, offset, err_log.value);
12893859Sml29623 	} else {
12903859Sml29623 		err_stat->pio_err = BIT_DISABLE;
12913859Sml29623 	}
12923859Sml29623 
12933859Sml29623 	return (NPI_SUCCESS);
12943859Sml29623 
12953859Sml29623 }
12963859Sml29623 
12973859Sml29623 /*
12983859Sml29623  * npi_fflp_fcram_clr_pio_err_log
12993859Sml29623  * Clears FCRAM PIO  error status for the partition.
13003859Sml29623  * If there are TCAM errors as indicated by err bit set by HW,
13013859Sml29623  *  then the SW will clear it by clearing the bit.
13023859Sml29623  *
13033859Sml29623  * Input
13043859Sml29623  *      handle:		opaque handle interpreted by the underlying OS
13053859Sml29623  *	partid:		partition ID
13063859Sml29623  *
13073859Sml29623  *
13083859Sml29623  * Return
13093859Sml29623  *	NPI success/failure status code
13103859Sml29623  */
13113859Sml29623 npi_status_t
npi_fflp_fcram_clr_pio_err_log(npi_handle_t handle,part_id_t partid)13123859Sml29623 npi_fflp_fcram_clr_pio_err_log(npi_handle_t handle, part_id_t partid)
13133859Sml29623 {
13143859Sml29623 	uint64_t offset;
13153859Sml29623 
13163859Sml29623 	hash_tbl_data_log_t err_log;
13173859Sml29623 
13183859Sml29623 	ASSERT(FCRAM_PARTITION_VALID(partid));
13193859Sml29623 	if (!FCRAM_PARTITION_VALID(partid)) {
13203859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
13216929Smisaki 		    " fcram_clr_pio_err_log:"
13226929Smisaki 		    " Invalid Partition %d \n",
13236929Smisaki 		    partid));
13243859Sml29623 
13253859Sml29623 		return (NPI_FFLP_FCRAM_PART_INVALID);
13263859Sml29623 	}
13273859Sml29623 
13283859Sml29623 	offset = GET_HASHTBL_PART_OFFSET_NVIR(partid,
13296929Smisaki 	    FFLP_HASH_TBL_DATA_LOG_REG);
13303859Sml29623 
13313859Sml29623 	err_log.value = 0;
13323859Sml29623 	REG_PIO_WRITE64(handle, offset, err_log.value);
13333859Sml29623 
13343859Sml29623 
13353859Sml29623 	return (NPI_SUCCESS);
13363859Sml29623 
13373859Sml29623 }
13383859Sml29623 
13393859Sml29623 /*
13403859Sml29623  * npi_fflp_tcam_get_err_log
13413859Sml29623  * Reports TCAM PIO read and lookup errors.
13423859Sml29623  * If there are TCAM errors as indicated by err bit set by HW,
13433859Sml29623  *  then the SW will clear it by clearing the bit.
13443859Sml29623  *
13453859Sml29623  * Input
13463859Sml29623  *      handle:		opaque handle interpreted by the underlying OS
13473859Sml29623  *	err_stat:	 structure to report various TCAM errors.
13483859Sml29623  *                       will be updated if there are TCAM errors.
13493859Sml29623  *
13503859Sml29623  *
13513859Sml29623  * Return
13523859Sml29623  *	NPI_SUCCESS	Success
13533859Sml29623  *
13543859Sml29623  *
13553859Sml29623  */
13563859Sml29623 npi_status_t
npi_fflp_tcam_get_err_log(npi_handle_t handle,tcam_err_log_t * err_stat)13573859Sml29623 npi_fflp_tcam_get_err_log(npi_handle_t handle, tcam_err_log_t *err_stat)
13583859Sml29623 {
13593859Sml29623 	tcam_err_t err_log;
13603859Sml29623 	uint64_t offset;
13613859Sml29623 
13623859Sml29623 	offset = FFLP_TCAM_ERR_REG;
13633859Sml29623 	err_log.value = 0;
13643859Sml29623 
13653859Sml29623 	REG_PIO_READ64(handle, offset, &err_log.value);
13663859Sml29623 
13673859Sml29623 	if (err_log.bits.ldw.err == BIT_ENABLE) {
13683859Sml29623 /* non-zero means err */
13693859Sml29623 		err_stat->tcam_err = BIT_ENABLE;
13703859Sml29623 		if (err_log.bits.ldw.p_ecc) {
13713859Sml29623 			err_stat->parity_err = 0;
13723859Sml29623 			err_stat->ecc_err = 1;
13733859Sml29623 		} else {
13743859Sml29623 			err_stat->parity_err = 1;
13753859Sml29623 			err_stat->ecc_err = 0;
13763859Sml29623 
13773859Sml29623 		}
13783859Sml29623 		err_stat->syndrome = err_log.bits.ldw.syndrome;
13793859Sml29623 		err_stat->location = err_log.bits.ldw.addr;
13803859Sml29623 
13813859Sml29623 
13823859Sml29623 		err_stat->multi_lkup = err_log.bits.ldw.mult;
13833859Sml29623 			/* now clear the error */
13843859Sml29623 		err_log.value = 0;
13853859Sml29623 		REG_PIO_WRITE64(handle, offset, err_log.value);
13863859Sml29623 
13873859Sml29623 	} else {
13883859Sml29623 		err_stat->tcam_err = 0;
13893859Sml29623 	}
13903859Sml29623 	return (NPI_SUCCESS);
13913859Sml29623 
13923859Sml29623 }
13933859Sml29623 
13943859Sml29623 /*
13953859Sml29623  * npi_fflp_tcam_clr_err_log
13963859Sml29623  * Clears TCAM PIO read and lookup error status.
13973859Sml29623  * If there are TCAM errors as indicated by err bit set by HW,
13983859Sml29623  *  then the SW will clear it by clearing the bit.
13993859Sml29623  *
14003859Sml29623  * Input
14013859Sml29623  *         handle:	opaque handle interpreted by the underlying OS
14023859Sml29623  *
14033859Sml29623  *
14043859Sml29623  * Return
14053859Sml29623  *	NPI_SUCCESS	Success
14063859Sml29623  *
14073859Sml29623  *
14083859Sml29623  */
14093859Sml29623 npi_status_t
npi_fflp_tcam_clr_err_log(npi_handle_t handle)14103859Sml29623 npi_fflp_tcam_clr_err_log(npi_handle_t handle)
14113859Sml29623 {
14123859Sml29623 	tcam_err_t err_log;
14133859Sml29623 	uint64_t offset;
14143859Sml29623 
14153859Sml29623 	offset = FFLP_TCAM_ERR_REG;
14163859Sml29623 	err_log.value = 0;
14173859Sml29623 	REG_PIO_WRITE64(handle, offset, err_log.value);
14183859Sml29623 
14193859Sml29623 	return (NPI_SUCCESS);
14203859Sml29623 
14213859Sml29623 }
14223859Sml29623 
14233859Sml29623 /*
14243859Sml29623  * npi_fflp_fcram_err_synd_test
14253859Sml29623  * Tests the FCRAM error detection logic.
14263859Sml29623  * The error detection logic for the syndrome is tested.
14273859Sml29623  * tst0->synd (8bits) are set to select the syndrome bits
14283859Sml29623  * to be XOR'ed
14293859Sml29623  *
14303859Sml29623  * Input
14313859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
14323859Sml29623  *	syndrome_bits:	 Syndrome bits to select bits to be xor'ed
14333859Sml29623  *
14343859Sml29623  *
14353859Sml29623  * Return
14363859Sml29623  *	NPI_SUCCESS	Success
14373859Sml29623  *
14383859Sml29623  *
14393859Sml29623  */
14403859Sml29623 npi_status_t
npi_fflp_fcram_err_synd_test(npi_handle_t handle,uint8_t syndrome_bits)14413859Sml29623 npi_fflp_fcram_err_synd_test(npi_handle_t handle, uint8_t syndrome_bits)
14423859Sml29623 {
14433859Sml29623 
14443859Sml29623 	uint64_t t0_offset;
14453859Sml29623 	fcram_err_tst0_t tst0;
14463859Sml29623 	t0_offset = FFLP_FCRAM_ERR_TST0_REG;
14473859Sml29623 
14483859Sml29623 	tst0.value = 0;
14493859Sml29623 	tst0.bits.ldw.syndrome_mask = syndrome_bits;
14503859Sml29623 
14513859Sml29623 	REG_PIO_WRITE64(handle, t0_offset, tst0.value);
14523859Sml29623 
14533859Sml29623 	return (NPI_SUCCESS);
14543859Sml29623 
14553859Sml29623 }
14563859Sml29623 
14573859Sml29623 /*
14583859Sml29623  * npi_fflp_fcram_err_data_test
14593859Sml29623  * Tests the FCRAM error detection logic.
14603859Sml29623  * The error detection logic for the datapath is tested.
14613859Sml29623  * bits [63:0] are set to select the data bits to be xor'ed
14623859Sml29623  *
14633859Sml29623  * Input
14643859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
14653859Sml29623  *	data:	 data bits to select bits to be xor'ed
14663859Sml29623  *
14673859Sml29623  *
14683859Sml29623  * Return
14693859Sml29623  *	NPI_SUCCESS	Success
14703859Sml29623  *
14713859Sml29623  *
14723859Sml29623  */
14733859Sml29623 npi_status_t
npi_fflp_fcram_err_data_test(npi_handle_t handle,fcram_err_data_t * data)14743859Sml29623 npi_fflp_fcram_err_data_test(npi_handle_t handle, fcram_err_data_t *data)
14753859Sml29623 {
14763859Sml29623 
14773859Sml29623 	uint64_t t1_offset, t2_offset;
14783859Sml29623 	fcram_err_tst1_t tst1; /* for data bits [31:0] */
14793859Sml29623 	fcram_err_tst2_t tst2; /* for data bits [63:32] */
14803859Sml29623 
14813859Sml29623 	t1_offset = FFLP_FCRAM_ERR_TST1_REG;
14823859Sml29623 	t2_offset = FFLP_FCRAM_ERR_TST2_REG;
14833859Sml29623 	tst1.value = 0;
14843859Sml29623 	tst2.value = 0;
14853859Sml29623 	tst1.bits.ldw.dat = data->bits.ldw.dat;
14863859Sml29623 	tst2.bits.ldw.dat = data->bits.hdw.dat;
14873859Sml29623 
14883859Sml29623 	REG_PIO_WRITE64(handle, t1_offset, tst1.value);
14893859Sml29623 	REG_PIO_WRITE64(handle, t2_offset, tst2.value);
14903859Sml29623 
14913859Sml29623 	return (NPI_SUCCESS);
14923859Sml29623 
14933859Sml29623 }
14943859Sml29623 
14953859Sml29623 /*
14963859Sml29623  * npi_fflp_cfg_enet_vlan_table_assoc
14973859Sml29623  * associates port vlan id to rdc table.
14983859Sml29623  *
14993859Sml29623  * Input
15003859Sml29623  *     handle			opaque handle interpreted by the underlying OS
15013859Sml29623  *     mac_portn		port number
15023859Sml29623  *     vlan_id			VLAN ID
15033859Sml29623  *     rdc_table		RDC Table #
15043859Sml29623  *     priority			priority
15053859Sml29623  *
15063859Sml29623  * Output
15073859Sml29623  *
15083859Sml29623  *	NPI success/failure status code
15093859Sml29623  *
15103859Sml29623  */
15113859Sml29623 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)15123859Sml29623 npi_fflp_cfg_enet_vlan_table_assoc(npi_handle_t handle, uint8_t mac_portn,
15133859Sml29623 				    vlan_id_t vlan_id, uint8_t rdc_table,
15143859Sml29623 				    uint8_t priority)
15153859Sml29623 {
15163859Sml29623 
15173859Sml29623 	fflp_enet_vlan_tbl_t cfg;
15183859Sml29623 	uint64_t offset;
15193859Sml29623 	uint8_t vlan_parity[8] = {0, 1, 1, 2, 1, 2, 2, 3};
15203859Sml29623 	uint8_t parity_bit;
15213859Sml29623 
15223859Sml29623 	ASSERT(FFLP_VLAN_VALID(vlan_id));
15233859Sml29623 	if (!FFLP_VLAN_VALID(vlan_id)) {
15243859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
15256929Smisaki 		    " fflp_cfg_enet_vlan_table:"
15266929Smisaki 		    " Invalid vlan ID %d \n",
15276929Smisaki 		    vlan_id));
15283859Sml29623 		return (NPI_FFLP_VLAN_INVALID);
15293859Sml29623 	}
15303859Sml29623 
15313859Sml29623 	ASSERT(FFLP_PORT_VALID(mac_portn));
15323859Sml29623 	if (!FFLP_PORT_VALID(mac_portn)) {
15333859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
15346929Smisaki 		    " fflp_cfg_enet_vlan_table:"
15356929Smisaki 		    " Invalid port num %d \n",
15366929Smisaki 		    mac_portn));
15373859Sml29623 		return (NPI_FFLP_PORT_INVALID);
15383859Sml29623 	}
15393859Sml29623 
15403859Sml29623 	ASSERT(FFLP_RDC_TABLE_VALID(rdc_table));
15413859Sml29623 	if (!FFLP_RDC_TABLE_VALID(rdc_table)) {
15423859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
15436929Smisaki 		    " fflp_cfg_enet_vlan_table:"
15446929Smisaki 		    " Invalid RDC Table %d \n",
15456929Smisaki 		    rdc_table));
15463859Sml29623 		return (NPI_FFLP_RDC_TABLE_INVALID);
15473859Sml29623 	}
15483859Sml29623 
15493859Sml29623 	offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
15503859Sml29623 	REG_PIO_READ64(handle, offset, &cfg.value);
15513859Sml29623 
15523859Sml29623 	switch (mac_portn) {
15533859Sml29623 		case 0:
15543859Sml29623 			cfg.bits.ldw.vlanrdctbln0 = rdc_table;
15553859Sml29623 			if (priority)
15563859Sml29623 				cfg.bits.ldw.vpr0 = BIT_ENABLE;
15573859Sml29623 			else
15583859Sml29623 				cfg.bits.ldw.vpr0 = BIT_DISABLE;
15593859Sml29623 				/* set the parity bits */
15603859Sml29623 			parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] +
15616929Smisaki 			    vlan_parity[cfg.bits.ldw.vlanrdctbln1] +
15626929Smisaki 			    cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1;
15633859Sml29623 			cfg.bits.ldw.parity0 = parity_bit & 0x1;
15643859Sml29623 			break;
15653859Sml29623 		case 1:
15663859Sml29623 			cfg.bits.ldw.vlanrdctbln1 = rdc_table;
15673859Sml29623 			if (priority)
15683859Sml29623 				cfg.bits.ldw.vpr1 = BIT_ENABLE;
15693859Sml29623 			else
15703859Sml29623 				cfg.bits.ldw.vpr1 = BIT_DISABLE;
15713859Sml29623 				/* set the parity bits */
15723859Sml29623 			parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] +
15736929Smisaki 			    vlan_parity[cfg.bits.ldw.vlanrdctbln1] +
15746929Smisaki 			    cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1;
15753859Sml29623 				cfg.bits.ldw.parity0 = parity_bit & 0x1;
15763859Sml29623 
15773859Sml29623 			break;
15783859Sml29623 		case 2:
15793859Sml29623 			cfg.bits.ldw.vlanrdctbln2 = rdc_table;
15803859Sml29623 			if (priority)
15813859Sml29623 				cfg.bits.ldw.vpr2 = BIT_ENABLE;
15823859Sml29623 			else
15833859Sml29623 				cfg.bits.ldw.vpr2 = BIT_DISABLE;
15843859Sml29623 				/* set the parity bits */
15853859Sml29623 			parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] +
15866929Smisaki 			    vlan_parity[cfg.bits.ldw.vlanrdctbln3] +
15876929Smisaki 			    cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3;
15883859Sml29623 			cfg.bits.ldw.parity1 = parity_bit & 0x1;
15893859Sml29623 
15903859Sml29623 			break;
15913859Sml29623 		case 3:
15923859Sml29623 			cfg.bits.ldw.vlanrdctbln3 = rdc_table;
15933859Sml29623 			if (priority)
15943859Sml29623 				cfg.bits.ldw.vpr3 = BIT_ENABLE;
15953859Sml29623 			else
15963859Sml29623 				cfg.bits.ldw.vpr3 = BIT_DISABLE;
15973859Sml29623 				/* set the parity bits */
15983859Sml29623 			parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] +
15996929Smisaki 			    vlan_parity[cfg.bits.ldw.vlanrdctbln3] +
16006929Smisaki 			    cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3;
16013859Sml29623 			cfg.bits.ldw.parity1 = parity_bit & 0x1;
16023859Sml29623 			break;
16033859Sml29623 		default:
16043859Sml29623 			return (NPI_FFLP_SW_PARAM_ERROR);
16053859Sml29623 	}
16063859Sml29623 
16073859Sml29623 	REG_PIO_WRITE64(handle, offset, cfg.value);
16083859Sml29623 	return (NPI_SUCCESS);
16093859Sml29623 }
16103859Sml29623 
16113859Sml29623 /*
16123859Sml29623  * npi_fflp_cfg_enet_vlan_table_set_pri
16133859Sml29623  * sets the  vlan based classification priority in respect to L2DA
16143859Sml29623  * classification.
16153859Sml29623  *
16163859Sml29623  * Input
16173859Sml29623  *     handle		opaque handle interpreted by the underlying OS
16183859Sml29623  *     mac_portn	port number
16193859Sml29623  *     vlan_id		VLAN ID
16203859Sml29623  *     priority 	priority
16213859Sml29623  *			1: vlan classification has higher priority
16223859Sml29623  *			0: l2da classification has higher priority
16233859Sml29623  *
16243859Sml29623  * Output
16253859Sml29623  *
16263859Sml29623  *	NPI success/failure status code
16273859Sml29623  */
16283859Sml29623 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)16293859Sml29623 npi_fflp_cfg_enet_vlan_table_set_pri(npi_handle_t handle, uint8_t mac_portn,
16303859Sml29623 				    vlan_id_t vlan_id, uint8_t priority)
16313859Sml29623 {
16323859Sml29623 
16333859Sml29623 	fflp_enet_vlan_tbl_t cfg;
16343859Sml29623 	uint64_t offset;
16353859Sml29623 	uint64_t old_value;
16363859Sml29623 
16373859Sml29623 	ASSERT(FFLP_VLAN_VALID(vlan_id));
16383859Sml29623 	if (!FFLP_VLAN_VALID(vlan_id)) {
16393859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
16406929Smisaki 		    " enet_vlan_table set pri:"
16416929Smisaki 		    " Invalid vlan ID %d \n",
16426929Smisaki 		    vlan_id));
16433859Sml29623 		return (NPI_FFLP_VLAN_INVALID);
16443859Sml29623 	}
16453859Sml29623 
16463859Sml29623 	ASSERT(FFLP_PORT_VALID(mac_portn));
16473859Sml29623 	if (!FFLP_PORT_VALID(mac_portn)) {
16483859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
16496929Smisaki 		    " enet_vlan_table set pri:"
16506929Smisaki 		    " Invalid port num %d \n",
16516929Smisaki 		    mac_portn));
16523859Sml29623 		return (NPI_FFLP_PORT_INVALID);
16533859Sml29623 	}
16543859Sml29623 
16553859Sml29623 
16563859Sml29623 	offset = FFLP_ENET_VLAN_TBL_REG + (vlan_id  << 3);
16573859Sml29623 	REG_PIO_READ64(handle, offset, &cfg.value);
16583859Sml29623 	old_value = cfg.value;
16593859Sml29623 	switch (mac_portn) {
16603859Sml29623 		case 0:
16613859Sml29623 			if (priority)
16623859Sml29623 				cfg.bits.ldw.vpr0 = BIT_ENABLE;
16633859Sml29623 			else
16643859Sml29623 				cfg.bits.ldw.vpr0 = BIT_DISABLE;
16653859Sml29623 			break;
16663859Sml29623 		case 1:
16673859Sml29623 			if (priority)
16683859Sml29623 				cfg.bits.ldw.vpr1 = BIT_ENABLE;
16693859Sml29623 			else
16703859Sml29623 				cfg.bits.ldw.vpr1 = BIT_DISABLE;
16713859Sml29623 			break;
16723859Sml29623 		case 2:
16733859Sml29623 			if (priority)
16743859Sml29623 				cfg.bits.ldw.vpr2 = BIT_ENABLE;
16753859Sml29623 			else
16763859Sml29623 				cfg.bits.ldw.vpr2 = BIT_DISABLE;
16773859Sml29623 			break;
16783859Sml29623 		case 3:
16793859Sml29623 			if (priority)
16803859Sml29623 				cfg.bits.ldw.vpr3 = BIT_ENABLE;
16813859Sml29623 			else
16823859Sml29623 				cfg.bits.ldw.vpr3 = BIT_DISABLE;
16833859Sml29623 			break;
16843859Sml29623 		default:
16853859Sml29623 			return (NPI_FFLP_SW_PARAM_ERROR);
16863859Sml29623 	}
16873859Sml29623 	if (old_value != cfg.value) {
16883859Sml29623 		if (mac_portn > 1)
16893859Sml29623 			cfg.bits.ldw.parity1++;
16903859Sml29623 		else
16913859Sml29623 			cfg.bits.ldw.parity0++;
16923859Sml29623 
16933859Sml29623 		REG_PIO_WRITE64(handle, offset, cfg.value);
16943859Sml29623 	}
16953859Sml29623 	return (NPI_SUCCESS);
16963859Sml29623 }
16973859Sml29623 
16983859Sml29623 /*
16993859Sml29623  * npi_fflp_cfg_vlan_table_clear
17003859Sml29623  * Clears the vlan RDC table
17013859Sml29623  *
17023859Sml29623  * Input
17033859Sml29623  *     handle		opaque handle interpreted by the underlying OS
17043859Sml29623  *     vlan_id		VLAN ID
17053859Sml29623  *
17063859Sml29623  * Output
17073859Sml29623  *
17083859Sml29623  *	NPI success/failure status code
17093859Sml29623  *
17103859Sml29623  */
17113859Sml29623 npi_status_t
npi_fflp_cfg_vlan_table_clear(npi_handle_t handle,vlan_id_t vlan_id)17123859Sml29623 npi_fflp_cfg_vlan_table_clear(npi_handle_t handle, vlan_id_t vlan_id)
17133859Sml29623 {
17143859Sml29623 
17153859Sml29623 	uint64_t offset;
17163859Sml29623 	uint64_t clear = 0ULL;
17173859Sml29623 	vlan_id_t start_vlan = 0;
17183859Sml29623 
17193859Sml29623 	if ((vlan_id < start_vlan) || (vlan_id >= NXGE_MAX_VLANS)) {
17203859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
17216929Smisaki 		    " enet_vlan_table clear:"
17226929Smisaki 		    " Invalid vlan ID %d \n",
17236929Smisaki 		    vlan_id));
17243859Sml29623 		return (NPI_FFLP_VLAN_INVALID);
17253859Sml29623 	}
17263859Sml29623 
17273859Sml29623 
17283859Sml29623 	offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
17293859Sml29623 
17303859Sml29623 	REG_PIO_WRITE64(handle, offset, clear);
17313859Sml29623 	return (NPI_SUCCESS);
17323859Sml29623 }
17333859Sml29623 
17343859Sml29623 /*
17353859Sml29623  * npi_fflp_vlan_tbl_get_err_log
17363859Sml29623  * Reports VLAN Table  errors.
17373859Sml29623  * If there are VLAN Table errors as indicated by err bit set by HW,
17383859Sml29623  *  then the SW will clear it by clearing the bit.
17393859Sml29623  *
17403859Sml29623  * Input
17413859Sml29623  *      handle:		opaque handle interpreted by the underlying OS
17423859Sml29623  *	err_stat:	 structure to report various VLAN table errors.
17433859Sml29623  *                       will be updated if there are errors.
17443859Sml29623  *
17453859Sml29623  *
17463859Sml29623  * Return
17473859Sml29623  *	NPI_SUCCESS	Success
17483859Sml29623  *
17493859Sml29623  *
17503859Sml29623  */
17513859Sml29623 npi_status_t
npi_fflp_vlan_tbl_get_err_log(npi_handle_t handle,vlan_tbl_err_log_t * err_stat)17523859Sml29623 npi_fflp_vlan_tbl_get_err_log(npi_handle_t handle, vlan_tbl_err_log_t *err_stat)
17533859Sml29623 {
17543859Sml29623 	vlan_par_err_t err_log;
17553859Sml29623 	uint64_t offset;
17563859Sml29623 
17573859Sml29623 
17583859Sml29623 	offset = FFLP_VLAN_PAR_ERR_REG;
17593859Sml29623 	err_log.value = 0;
17603859Sml29623 
17613859Sml29623 	REG_PIO_READ64(handle, offset, &err_log.value);
17623859Sml29623 
17633859Sml29623 	if (err_log.bits.ldw.err == BIT_ENABLE) {
17643859Sml29623 /* non-zero means err */
17653859Sml29623 		err_stat->err = BIT_ENABLE;
17663859Sml29623 		err_stat->multi = err_log.bits.ldw.m_err;
17673859Sml29623 		err_stat->addr = err_log.bits.ldw.addr;
17683859Sml29623 		err_stat->data = err_log.bits.ldw.data;
17693859Sml29623 /* now clear the error */
17703859Sml29623 		err_log.value = 0;
17713859Sml29623 		REG_PIO_WRITE64(handle, offset, err_log.value);
17723859Sml29623 
17733859Sml29623 	} else {
17743859Sml29623 		err_stat->err = 0;
17753859Sml29623 	}
17763859Sml29623 
17773859Sml29623 	return (NPI_SUCCESS);
17783859Sml29623 }
17793859Sml29623 
17803859Sml29623 /*
17813859Sml29623  * npi_fflp_vlan_tbl_clr_err_log
17823859Sml29623  * Clears VLAN Table PIO  error status.
17833859Sml29623  * If there are VLAN Table errors as indicated by err bit set by HW,
17843859Sml29623  *  then the SW will clear it by clearing the bit.
17853859Sml29623  *
17863859Sml29623  * Input
17873859Sml29623  *         handle:	opaque handle interpreted by the underlying OS
17883859Sml29623  *
17893859Sml29623  *
17903859Sml29623  * Return
17913859Sml29623  *	NPI_SUCCESS	Success
17923859Sml29623  *
17933859Sml29623  *
17943859Sml29623  */
17953859Sml29623 npi_status_t
npi_fflp_vlan_tbl_clr_err_log(npi_handle_t handle)17963859Sml29623 npi_fflp_vlan_tbl_clr_err_log(npi_handle_t handle)
17973859Sml29623 {
17983859Sml29623 	vlan_par_err_t err_log;
17993859Sml29623 	uint64_t offset;
18003859Sml29623 
18013859Sml29623 	offset = FFLP_VLAN_PAR_ERR_REG;
18023859Sml29623 	err_log.value = 0;
18033859Sml29623 
18043859Sml29623 	REG_PIO_WRITE64(handle, offset, err_log.value);
18053859Sml29623 
18063859Sml29623 	return (NPI_SUCCESS);
18073859Sml29623 }
18083859Sml29623 
18093859Sml29623 /*
18103859Sml29623  * npi_fflp_cfg_enet_usr_cls_set()
18113859Sml29623  * Configures a user configurable ethernet class
18123859Sml29623  *
18133859Sml29623  * Input
18143859Sml29623  *      handle:		opaque handle interpreted by the underlying OS
18153859Sml29623  *      class:       Ethernet Class  class
18163859Sml29623  *		     (TCAM_CLASS_ETYPE or  TCAM_CLASS_ETYPE_2)
18173859Sml29623  *      enet_type:   16 bit Ethernet Type value, corresponding ethernet bytes
18183859Sml29623  *                        [13:14] in the frame.
18193859Sml29623  *
18203859Sml29623  *  by default, the class will be disabled until explicitly enabled.
18213859Sml29623  *
18223859Sml29623  * Return
18233859Sml29623  * NPI success/failure status code
18243859Sml29623  */
18253859Sml29623 npi_status_t
npi_fflp_cfg_enet_usr_cls_set(npi_handle_t handle,tcam_class_t class,uint16_t enet_type)18263859Sml29623 npi_fflp_cfg_enet_usr_cls_set(npi_handle_t handle,
18273859Sml29623 			    tcam_class_t class, uint16_t enet_type)
18283859Sml29623 {
18293859Sml29623 	uint64_t offset;
18303859Sml29623 	tcam_class_prg_ether_t cls_cfg;
18313859Sml29623 	cls_cfg.value = 0x0;
18323859Sml29623 
18333859Sml29623 /* check if etype is valid */
18343859Sml29623 	ASSERT(TCAM_L2_USR_CLASS_VALID(class));
18353859Sml29623 	if (!TCAM_L2_USR_CLASS_VALID(class)) {
18363859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
18376929Smisaki 		    " npi_fflp_cfg_enet_usr_cls_set:"
18386929Smisaki 		    " Invalid class %d \n",
18396929Smisaki 		    class));
18403859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
18413859Sml29623 	}
18423859Sml29623 	offset = GET_TCAM_CLASS_OFFSET(class);
18433859Sml29623 
18443859Sml29623 /*
18453859Sml29623  * etype check code
18463859Sml29623  *
18473859Sml29623  * if (check_fail)
18483859Sml29623  *  return (NPI_FAILURE | NPI_SW_ERROR);
18493859Sml29623  */
18503859Sml29623 
18513859Sml29623 	cls_cfg.bits.ldw.etype = enet_type;
18523859Sml29623 	cls_cfg.bits.ldw.valid = BIT_DISABLE;
18533859Sml29623 	REG_PIO_WRITE64(handle, offset, cls_cfg.value);
18543859Sml29623 	return (NPI_SUCCESS);
18553859Sml29623 }
18563859Sml29623 
18573859Sml29623 /*
18583859Sml29623  * npi_fflp_cfg_enet_usr_cls_enable()
18593859Sml29623  * Enable previously configured TCAM user configurable Ethernet classes.
18603859Sml29623  *
18613859Sml29623  * Input
18623859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
18633859Sml29623  *      class:       Ethernet Class  class
18643859Sml29623  *		     (TCAM_CLASS_ETYPE or  TCAM_CLASS_ETYPE_2)
18653859Sml29623  *
18663859Sml29623  * Return
18673859Sml29623  * NPI success/failure status code
18683859Sml29623  */
18693859Sml29623 npi_status_t
npi_fflp_cfg_enet_usr_cls_enable(npi_handle_t handle,tcam_class_t class)18703859Sml29623 npi_fflp_cfg_enet_usr_cls_enable(npi_handle_t handle, tcam_class_t class)
18713859Sml29623 {
18723859Sml29623 	uint64_t offset;
18733859Sml29623 	tcam_class_prg_ether_t cls_cfg;
18743859Sml29623 
18753859Sml29623 	ASSERT(TCAM_L2_USR_CLASS_VALID(class));
18763859Sml29623 	if (!TCAM_L2_USR_CLASS_VALID(class)) {
18773859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
18786929Smisaki 		    " npi_fflp_cfg_enet_usr_cls_enable:"
18796929Smisaki 		    " Invalid class %d \n",
18806929Smisaki 		    class));
18813859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
18823859Sml29623 	}
18833859Sml29623 
18843859Sml29623 	offset = GET_TCAM_CLASS_OFFSET(class);
18853859Sml29623 
18863859Sml29623 	REG_PIO_READ64(handle, offset, &cls_cfg.value);
18873859Sml29623 	cls_cfg.bits.ldw.valid = BIT_ENABLE;
18883859Sml29623 	REG_PIO_WRITE64(handle, offset, cls_cfg.value);
18893859Sml29623 	return (NPI_SUCCESS);
18903859Sml29623 }
18913859Sml29623 
18923859Sml29623 /*
18933859Sml29623  * npi_fflp_cfg_enet_usr_cls_disable()
18943859Sml29623  * Disables previously configured TCAM user configurable Ethernet classes.
18953859Sml29623  *
18963859Sml29623  * Input
18973859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
18983859Sml29623  *      class:       Ethernet Class  class
18993859Sml29623  *		     (TCAM_CLASS_ETYPE or  TCAM_CLASS_ETYPE_2)
19003859Sml29623  *
19013859Sml29623  * Return
19023859Sml29623  * NPI success/failure status code
19033859Sml29623  */
19043859Sml29623 npi_status_t
npi_fflp_cfg_enet_usr_cls_disable(npi_handle_t handle,tcam_class_t class)19053859Sml29623 npi_fflp_cfg_enet_usr_cls_disable(npi_handle_t handle, tcam_class_t class)
19063859Sml29623 {
19073859Sml29623 	uint64_t offset;
19083859Sml29623 	tcam_class_prg_ether_t cls_cfg;
19093859Sml29623 
19103859Sml29623 	ASSERT(TCAM_L2_USR_CLASS_VALID(class));
19113859Sml29623 	if (!TCAM_L2_USR_CLASS_VALID(class)) {
19123859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
19136929Smisaki 		    " npi_fflp_cfg_enet_usr_cls_disable:"
19146929Smisaki 		    " Invalid class %d \n",
19156929Smisaki 		    class));
19163859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
19173859Sml29623 	}
19183859Sml29623 
19193859Sml29623 	offset = GET_TCAM_CLASS_OFFSET(class);
19203859Sml29623 
19213859Sml29623 	REG_PIO_READ64(handle, offset, &cls_cfg.value);
19223859Sml29623 	cls_cfg.bits.ldw.valid = BIT_DISABLE;
19233859Sml29623 
19243859Sml29623 	REG_PIO_WRITE64(handle, offset, cls_cfg.value);
19253859Sml29623 	return (NPI_SUCCESS);
19263859Sml29623 }
19273859Sml29623 
19283859Sml29623 /*
19293859Sml29623  * npi_fflp_cfg_ip_usr_cls_set()
19303859Sml29623  * Configures the TCAM user configurable IP classes.
19313859Sml29623  *
19323859Sml29623  * Input
19333859Sml29623  *      handle:		opaque handle interpreted by the underlying OS
19343859Sml29623  *      class:       IP Class  class
19353859Sml29623  *		     (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
19363859Sml29623  *      tos:         IP TOS bits
19373859Sml29623  *      tos_mask:    IP TOS bits mask. bits with mask bits set will be used
19383859Sml29623  *      proto:       IP Proto
19393859Sml29623  *      ver:         IP Version
19403859Sml29623  * by default, will the class is disabled until explicitly enabled
19413859Sml29623  *
19423859Sml29623  * Return
19433859Sml29623  * NPI success/failure status code
19443859Sml29623  */
19453859Sml29623 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)19463859Sml29623 npi_fflp_cfg_ip_usr_cls_set(npi_handle_t handle, tcam_class_t class,
19473859Sml29623 			    uint8_t tos, uint8_t tos_mask,
19483859Sml29623 			    uint8_t proto, uint8_t ver)
19493859Sml29623 {
19503859Sml29623 	uint64_t offset;
19513859Sml29623 	tcam_class_prg_ip_t ip_cls_cfg;
19523859Sml29623 
19533859Sml29623 	ASSERT(TCAM_L3_USR_CLASS_VALID(class));
19543859Sml29623 	if (!TCAM_L3_USR_CLASS_VALID(class)) {
19553859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
19566929Smisaki 		    " npi_fflp_cfg_ip_usr_cls_set:"
19576929Smisaki 		    " Invalid class %d \n",
19586929Smisaki 		    class));
19593859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
19603859Sml29623 	}
19613859Sml29623 
19623859Sml29623 	offset = GET_TCAM_CLASS_OFFSET(class);
19633859Sml29623 
19643859Sml29623 	ip_cls_cfg.bits.ldw.pid = proto;
19653859Sml29623 	ip_cls_cfg.bits.ldw.ipver = ver;
19663859Sml29623 	ip_cls_cfg.bits.ldw.tos = tos;
19673859Sml29623 	ip_cls_cfg.bits.ldw.tosmask = tos_mask;
19683859Sml29623 	ip_cls_cfg.bits.ldw.valid = 0;
19693859Sml29623 	REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
19703859Sml29623 	return (NPI_SUCCESS);
19713859Sml29623 
19723859Sml29623 }
19733859Sml29623 
19743859Sml29623 /*
1975*11304SJanie.Lu@Sun.COM  * npi_fflp_cfg_ip_usr_cls_set_iptun()
1976*11304SJanie.Lu@Sun.COM  * Configures the TCAM user configurable IP classes. This function sets the
1977*11304SJanie.Lu@Sun.COM  * new fields that were added for IP tunneling support
1978*11304SJanie.Lu@Sun.COM  *
1979*11304SJanie.Lu@Sun.COM  * Input
1980*11304SJanie.Lu@Sun.COM  *      handle:		opaque handle interpreted by the underlying OS
1981*11304SJanie.Lu@Sun.COM  *      class:       IP Class  class
1982*11304SJanie.Lu@Sun.COM  *		     (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
1983*11304SJanie.Lu@Sun.COM  *	l4b0_val	value of the first L4 byte to be compared
1984*11304SJanie.Lu@Sun.COM  *	l4b0_msk	mask to apply to compare byte 0 of L4
1985*11304SJanie.Lu@Sun.COM  *	l4b23_val	values of L4 bytes 2 and 3 to compare
1986*11304SJanie.Lu@Sun.COM  *	l4b23_sel	set to 1 to compare L4 bytes 2 and 3.
1987*11304SJanie.Lu@Sun.COM  * by default, the class is disabled until explicitly enabled
1988*11304SJanie.Lu@Sun.COM  *
1989*11304SJanie.Lu@Sun.COM  * Return
1990*11304SJanie.Lu@Sun.COM  * NPI success/failure status code
1991*11304SJanie.Lu@Sun.COM  */
1992*11304SJanie.Lu@Sun.COM 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)1993*11304SJanie.Lu@Sun.COM npi_fflp_cfg_ip_usr_cls_set_iptun(npi_handle_t handle, tcam_class_t class,
1994*11304SJanie.Lu@Sun.COM 			    uint8_t l4b0_val, uint8_t l4b0_msk,
1995*11304SJanie.Lu@Sun.COM 			    uint16_t l4b23_val, uint8_t l4b23_sel)
1996*11304SJanie.Lu@Sun.COM {
1997*11304SJanie.Lu@Sun.COM 	uint64_t offset, val;
1998*11304SJanie.Lu@Sun.COM 	tcam_class_prg_ip_t ip_cls_cfg;
1999*11304SJanie.Lu@Sun.COM 
2000*11304SJanie.Lu@Sun.COM 	ASSERT(TCAM_L3_USR_CLASS_VALID(class));
2001*11304SJanie.Lu@Sun.COM 	if (!TCAM_L3_USR_CLASS_VALID(class)) {
2002*11304SJanie.Lu@Sun.COM 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2003*11304SJanie.Lu@Sun.COM 		    " npi_fflp_cfg_ip_usr_cls_set:"
2004*11304SJanie.Lu@Sun.COM 		    " Invalid class %d \n",
2005*11304SJanie.Lu@Sun.COM 		    class));
2006*11304SJanie.Lu@Sun.COM 		return (NPI_FFLP_TCAM_CLASS_INVALID);
2007*11304SJanie.Lu@Sun.COM 	}
2008*11304SJanie.Lu@Sun.COM 
2009*11304SJanie.Lu@Sun.COM 	offset = GET_TCAM_CLASS_OFFSET(class);
2010*11304SJanie.Lu@Sun.COM 	REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2011*11304SJanie.Lu@Sun.COM 
2012*11304SJanie.Lu@Sun.COM 	val = 1;
2013*11304SJanie.Lu@Sun.COM 	ip_cls_cfg.value |= (val << L3_UCLS_L4_MODE_SH);
2014*11304SJanie.Lu@Sun.COM 	val = l4b0_val;
2015*11304SJanie.Lu@Sun.COM 	ip_cls_cfg.value |= (val << L3_UCLS_L4B0_VAL_SH);
2016*11304SJanie.Lu@Sun.COM 	val = l4b0_msk;
2017*11304SJanie.Lu@Sun.COM 	ip_cls_cfg.value |= (val << L3_UCLS_L4B0_MASK_SH);
2018*11304SJanie.Lu@Sun.COM 	val = l4b23_sel;
2019*11304SJanie.Lu@Sun.COM 	ip_cls_cfg.value |= (val << L3_UCLS_L4B23_SEL_SH);
2020*11304SJanie.Lu@Sun.COM 	val = l4b23_val;
2021*11304SJanie.Lu@Sun.COM 	ip_cls_cfg.value |= (val << L3_UCLS_L4B23_VAL_SH);
2022*11304SJanie.Lu@Sun.COM 
2023*11304SJanie.Lu@Sun.COM 	ip_cls_cfg.bits.ldw.valid = 0;
2024*11304SJanie.Lu@Sun.COM 	REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
2025*11304SJanie.Lu@Sun.COM 	return (NPI_SUCCESS);
2026*11304SJanie.Lu@Sun.COM }
2027*11304SJanie.Lu@Sun.COM 
2028*11304SJanie.Lu@Sun.COM /*
2029*11304SJanie.Lu@Sun.COM  * npi_fflp_cfg_ip_usr_cls_get_iptun()
2030*11304SJanie.Lu@Sun.COM  * Retrieves the IP tunneling related settings for the given TCAM user
2031*11304SJanie.Lu@Sun.COM  * configurable IP classe.
2032*11304SJanie.Lu@Sun.COM  *
2033*11304SJanie.Lu@Sun.COM  * Input
2034*11304SJanie.Lu@Sun.COM  *      handle:		opaque handle interpreted by the underlying OS
2035*11304SJanie.Lu@Sun.COM  *      class:       IP Class  class
2036*11304SJanie.Lu@Sun.COM  *		     (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
2037*11304SJanie.Lu@Sun.COM  *	l4b0_val	value of the first L4 byte to be compared
2038*11304SJanie.Lu@Sun.COM  *	l4b0_msk	mask to apply to compare byte 0 of L4
2039*11304SJanie.Lu@Sun.COM  *	l4b23_val	values of L4 bytes 2 and 3 to compare
2040*11304SJanie.Lu@Sun.COM  *	l4b23_sel	set to 1 to compare L4 bytes 2 and 3.
2041*11304SJanie.Lu@Sun.COM  * by default, the class is disabled until explicitly enabled
2042*11304SJanie.Lu@Sun.COM  *
2043*11304SJanie.Lu@Sun.COM  * Return
2044*11304SJanie.Lu@Sun.COM  * NPI success/failure status code
2045*11304SJanie.Lu@Sun.COM  */
2046*11304SJanie.Lu@Sun.COM 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)2047*11304SJanie.Lu@Sun.COM npi_fflp_cfg_ip_usr_cls_get_iptun(npi_handle_t handle, tcam_class_t class,
2048*11304SJanie.Lu@Sun.COM 			    uint8_t *l4b0_val, uint8_t *l4b0_msk,
2049*11304SJanie.Lu@Sun.COM 			    uint16_t *l4b23_val, uint8_t *l4b23_sel)
2050*11304SJanie.Lu@Sun.COM {
2051*11304SJanie.Lu@Sun.COM 	uint64_t offset;
2052*11304SJanie.Lu@Sun.COM 	tcam_class_prg_ip_t ip_cls_cfg;
2053*11304SJanie.Lu@Sun.COM 
2054*11304SJanie.Lu@Sun.COM 	ASSERT(TCAM_L3_USR_CLASS_VALID(class));
2055*11304SJanie.Lu@Sun.COM 	if (!TCAM_L3_USR_CLASS_VALID(class)) {
2056*11304SJanie.Lu@Sun.COM 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2057*11304SJanie.Lu@Sun.COM 		    " npi_fflp_cfg_ip_usr_cls_set:"
2058*11304SJanie.Lu@Sun.COM 		    " Invalid class %d \n",
2059*11304SJanie.Lu@Sun.COM 		    class));
2060*11304SJanie.Lu@Sun.COM 		return (NPI_FFLP_TCAM_CLASS_INVALID);
2061*11304SJanie.Lu@Sun.COM 	}
2062*11304SJanie.Lu@Sun.COM 
2063*11304SJanie.Lu@Sun.COM 	offset = GET_TCAM_CLASS_OFFSET(class);
2064*11304SJanie.Lu@Sun.COM 	REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2065*11304SJanie.Lu@Sun.COM 
2066*11304SJanie.Lu@Sun.COM 	*l4b0_val = (ip_cls_cfg.value >> L3_UCLS_L4B0_VAL_SH) &
2067*11304SJanie.Lu@Sun.COM 	    L3_UCLS_L4B0_VAL_MSK;
2068*11304SJanie.Lu@Sun.COM 	*l4b0_msk = (ip_cls_cfg.value >> L3_UCLS_L4B0_MASK_SH) &
2069*11304SJanie.Lu@Sun.COM 	    L3_UCLS_L4B0_MASK_MSK;
2070*11304SJanie.Lu@Sun.COM 	*l4b23_sel = (ip_cls_cfg.value >> L3_UCLS_L4B23_SEL_SH) &
2071*11304SJanie.Lu@Sun.COM 	    L3_UCLS_L4B23_SEL_MSK;
2072*11304SJanie.Lu@Sun.COM 	*l4b23_val = (ip_cls_cfg.value >> L3_UCLS_L4B23_VAL_SH) &
2073*11304SJanie.Lu@Sun.COM 	    L3_UCLS_L4B23_VAL_MSK;
2074*11304SJanie.Lu@Sun.COM 
2075*11304SJanie.Lu@Sun.COM 	return (NPI_SUCCESS);
2076*11304SJanie.Lu@Sun.COM 
2077*11304SJanie.Lu@Sun.COM }
2078*11304SJanie.Lu@Sun.COM 
2079*11304SJanie.Lu@Sun.COM /*
20803859Sml29623  * npi_fflp_cfg_ip_usr_cls_enable()
20813859Sml29623  * Enable previously configured TCAM user configurable IP classes.
20823859Sml29623  *
20833859Sml29623  * Input
20843859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
20853859Sml29623  *      class:       IP Class  class
20863859Sml29623  *		     (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
20873859Sml29623  *
20883859Sml29623  * Return
20893859Sml29623  * NPI success/failure status code
20903859Sml29623  */
20913859Sml29623 npi_status_t
npi_fflp_cfg_ip_usr_cls_enable(npi_handle_t handle,tcam_class_t class)20923859Sml29623 npi_fflp_cfg_ip_usr_cls_enable(npi_handle_t handle, tcam_class_t class)
20933859Sml29623 {
20943859Sml29623 	uint64_t offset;
20953859Sml29623 	tcam_class_prg_ip_t ip_cls_cfg;
20963859Sml29623 
20973859Sml29623 	ASSERT(TCAM_L3_USR_CLASS_VALID(class));
20983859Sml29623 	if (!TCAM_L3_USR_CLASS_VALID(class)) {
20993859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
21006929Smisaki 		    " npi_fflp_cfg_ip_usr_cls_enable:"
21016929Smisaki 		    " Invalid class %d \n",
21026929Smisaki 		    class));
21033859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
21043859Sml29623 	}
21053859Sml29623 
21063859Sml29623 	offset = GET_TCAM_CLASS_OFFSET(class);
21073859Sml29623 	REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
21083859Sml29623 	ip_cls_cfg.bits.ldw.valid = 1;
21093859Sml29623 
21103859Sml29623 	REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
21113859Sml29623 	return (NPI_SUCCESS);
21123859Sml29623 
21133859Sml29623 }
21143859Sml29623 
21153859Sml29623 /*
21163859Sml29623  * npi_fflp_cfg_ip_usr_cls_disable()
21173859Sml29623  * Disables previously configured TCAM user configurable IP classes.
21183859Sml29623  *
21193859Sml29623  * Input
21203859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
21213859Sml29623  *      class:       IP Class  class
21223859Sml29623  *		     (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
21233859Sml29623  *
21243859Sml29623  * Return
21253859Sml29623  * NPI success/failure status code
21263859Sml29623  */
21273859Sml29623 npi_status_t
npi_fflp_cfg_ip_usr_cls_disable(npi_handle_t handle,tcam_class_t class)21283859Sml29623 npi_fflp_cfg_ip_usr_cls_disable(npi_handle_t handle, tcam_class_t class)
21293859Sml29623 {
21303859Sml29623 	uint64_t offset;
21313859Sml29623 	tcam_class_prg_ip_t ip_cls_cfg;
21323859Sml29623 
21333859Sml29623 	ASSERT(TCAM_L3_USR_CLASS_VALID(class));
21343859Sml29623 	if (!TCAM_L3_USR_CLASS_VALID(class)) {
21353859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
21366929Smisaki 		    " npi_fflp_cfg_ip_usr_cls_disable:"
21376929Smisaki 		    " Invalid class %d \n",
21386929Smisaki 		    class));
21393859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
21403859Sml29623 	}
21413859Sml29623 
21423859Sml29623 	offset = GET_TCAM_CLASS_OFFSET(class);
21433859Sml29623 
21443859Sml29623 	REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
21453859Sml29623 	ip_cls_cfg.bits.ldw.valid = 0;
21463859Sml29623 
21473859Sml29623 	REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
21483859Sml29623 	return (NPI_SUCCESS);
21493859Sml29623 
21503859Sml29623 }
21513859Sml29623 
21523859Sml29623 /*
21533859Sml29623  * npi_fflp_cfg_ip_cls_tcam_key ()
21543859Sml29623  *
21553859Sml29623  * Configures the TCAM key generation for the IP classes
21563859Sml29623  *
21573859Sml29623  * Input
21583859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
21593859Sml29623  *      l3_class:        IP class to configure key generation
21603859Sml29623  *      cfg:             Configuration bits:
21613859Sml29623  *                   discard:      Discard all frames of this class
21623859Sml29623  *                   use_ip_saddr: use ip src address (for ipv6)
21633859Sml29623  *                   use_ip_daddr: use ip dest address (for ipv6)
21643859Sml29623  *                   lookup_enable: Enable Lookup
21653859Sml29623  *
21663859Sml29623  *
21673859Sml29623  * Return
21683859Sml29623  * NPI success/failure status code
21693859Sml29623  */
21703859Sml29623 npi_status_t
npi_fflp_cfg_ip_cls_tcam_key(npi_handle_t handle,tcam_class_t l3_class,tcam_key_cfg_t * cfg)21713859Sml29623 npi_fflp_cfg_ip_cls_tcam_key(npi_handle_t handle,
21723859Sml29623 			    tcam_class_t l3_class, tcam_key_cfg_t *cfg)
21733859Sml29623 {
21743859Sml29623 	uint64_t offset;
21753859Sml29623 	tcam_class_key_ip_t tcam_cls_cfg;
21763859Sml29623 
21773859Sml29623 	ASSERT(TCAM_L3_CLASS_VALID(l3_class));
21783859Sml29623 	if (!(TCAM_L3_CLASS_VALID(l3_class))) {
21793859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
21806929Smisaki 		    " npi_fflp_cfg_ip_cls_tcam_key:"
21816929Smisaki 		    " Invalid class %d \n",
21826929Smisaki 		    l3_class));
21833859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
21843859Sml29623 	}
21853859Sml29623 
21863859Sml29623 	if ((cfg->use_ip_daddr) &&
21876929Smisaki 	    (cfg->use_ip_saddr == cfg->use_ip_daddr)) {
21883859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
21896929Smisaki 		    " npi_fflp_cfg_ip_cls_tcam_key:"
21906929Smisaki 		    " Invalid configuration %x for class %d \n",
21916929Smisaki 		    *cfg, l3_class));
21923859Sml29623 		return (NPI_FFLP_SW_PARAM_ERROR);
21933859Sml29623 	}
21943859Sml29623 
21953859Sml29623 
21963859Sml29623 	offset = GET_TCAM_KEY_OFFSET(l3_class);
21973859Sml29623 	tcam_cls_cfg.value = 0;
21983859Sml29623 
21993859Sml29623 	if (cfg->discard) {
22003859Sml29623 		tcam_cls_cfg.bits.ldw.discard = 1;
22013859Sml29623 	}
22023859Sml29623 
22033859Sml29623 	if (cfg->use_ip_saddr) {
22043859Sml29623 		tcam_cls_cfg.bits.ldw.ipaddr = 1;
22053859Sml29623 	}
22063859Sml29623 
22073859Sml29623 	if (cfg->use_ip_daddr) {
22083859Sml29623 		tcam_cls_cfg.bits.ldw.ipaddr = 0;
22093859Sml29623 	}
22103859Sml29623 
22113859Sml29623 	if (cfg->lookup_enable) {
22123859Sml29623 		tcam_cls_cfg.bits.ldw.tsel = 1;
22133859Sml29623 	}
22143859Sml29623 
22153859Sml29623 	REG_PIO_WRITE64(handle, offset, tcam_cls_cfg.value);
22163859Sml29623 	return (NPI_SUCCESS);
22173859Sml29623 }
22183859Sml29623 
22193859Sml29623 /*
22203859Sml29623  * npi_fflp_cfg_ip_cls_flow_key ()
22213859Sml29623  *
22223859Sml29623  * Configures the flow key generation for the IP classes
22233859Sml29623  * Flow key is used to generate the H1 hash function value
22243859Sml29623  * The fields used for the generation are configured using this
22253859Sml29623  * NPI function.
22263859Sml29623  *
22273859Sml29623  * Input
22283859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
22293859Sml29623  *      l3_class:        IP class to configure flow key generation
22303859Sml29623  *      cfg:             Configuration bits:
22313859Sml29623  *                   use_proto:     Use IP proto field
22323859Sml29623  *                   use_dport:     use l4 destination port
22333859Sml29623  *                   use_sport:     use l4 source port
22343859Sml29623  *                   ip_opts_exist: IP Options Present
22353859Sml29623  *                   use_daddr:     use ip dest address
22363859Sml29623  *                   use_saddr:     use ip source address
22373859Sml29623  *                   use_vlan:      use VLAN ID
22383859Sml29623  *                   use_l2da:      use L2 Dest MAC Address
22393859Sml29623  *                   use_portnum:   use L2 virtual port number
22403859Sml29623  *
22413859Sml29623  *
22423859Sml29623  * Return
22433859Sml29623  * NPI success/failure status code
22443859Sml29623  */
22453859Sml29623 npi_status_t
npi_fflp_cfg_ip_cls_flow_key(npi_handle_t handle,tcam_class_t l3_class,flow_key_cfg_t * cfg)22463859Sml29623 npi_fflp_cfg_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class,
22473859Sml29623 							    flow_key_cfg_t *cfg)
22483859Sml29623 {
22493859Sml29623 	uint64_t offset;
22503859Sml29623 	flow_class_key_ip_t flow_cfg_reg;
22513859Sml29623 
22523859Sml29623 	ASSERT(TCAM_L3_CLASS_VALID(l3_class));
22533859Sml29623 	if (!(TCAM_L3_CLASS_VALID(l3_class))) {
22543859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
22556929Smisaki 		    " npi_fflp_cfg_ip_cls_flow_key:"
22566929Smisaki 		    " Invalid class %d \n",
22576929Smisaki 		    l3_class));
22583859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
22593859Sml29623 	}
22603859Sml29623 
22613859Sml29623 
22623859Sml29623 	offset = GET_FLOW_KEY_OFFSET(l3_class);
22633859Sml29623 	flow_cfg_reg.value = 0; /* default */
22643859Sml29623 
22653859Sml29623 	if (cfg->use_proto) {
22663859Sml29623 		flow_cfg_reg.bits.ldw.proto = 1;
22673859Sml29623 	}
22683859Sml29623 
22693859Sml29623 	if (cfg->use_dport) {
22703859Sml29623 		flow_cfg_reg.bits.ldw.l4_1 = 2;
22713859Sml29623 		if (cfg->ip_opts_exist)
22723859Sml29623 			flow_cfg_reg.bits.ldw.l4_1 = 3;
22733859Sml29623 	}
22743859Sml29623 
22753859Sml29623 	if (cfg->use_sport) {
22763859Sml29623 		flow_cfg_reg.bits.ldw.l4_0 = 2;
22773859Sml29623 		if (cfg->ip_opts_exist)
22783859Sml29623 			flow_cfg_reg.bits.ldw.l4_0 = 3;
22793859Sml29623 	}
22803859Sml29623 
22813859Sml29623 	if (cfg->use_daddr) {
22823859Sml29623 		flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE;
22833859Sml29623 	}
22843859Sml29623 
22853859Sml29623 	if (cfg->use_saddr) {
22863859Sml29623 		flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE;
22873859Sml29623 	}
22883859Sml29623 
22893859Sml29623 	if (cfg->use_vlan) {
22903859Sml29623 		flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE;
22913859Sml29623 	}
22923859Sml29623 
22933859Sml29623 	if (cfg->use_l2da) {
22943859Sml29623 		flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE;
22953859Sml29623 	}
22963859Sml29623 
22973859Sml29623 	if (cfg->use_portnum) {
22983859Sml29623 		flow_cfg_reg.bits.ldw.port = BIT_ENABLE;
22993859Sml29623 	}
23003859Sml29623 
23013859Sml29623 	REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
23023859Sml29623 	return (NPI_SUCCESS);
23033859Sml29623 
23043859Sml29623 }
23053859Sml29623 
23063859Sml29623 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)23073859Sml29623 npi_fflp_cfg_ip_cls_flow_key_get(npi_handle_t handle,
23083859Sml29623 				    tcam_class_t l3_class,
23093859Sml29623 				    flow_key_cfg_t *cfg)
23103859Sml29623 {
23113859Sml29623 	uint64_t offset;
23123859Sml29623 	flow_class_key_ip_t flow_cfg_reg;
23133859Sml29623 
23143859Sml29623 	ASSERT(TCAM_L3_CLASS_VALID(l3_class));
23153859Sml29623 	if (!(TCAM_L3_CLASS_VALID(l3_class))) {
23163859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
23176929Smisaki 		    " npi_fflp_cfg_ip_cls_flow_key:"
23186929Smisaki 		    " Invalid class %d \n",
23196929Smisaki 		    l3_class));
23203859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
23213859Sml29623 	}
23223859Sml29623 
23233859Sml29623 	offset = GET_FLOW_KEY_OFFSET(l3_class);
23243859Sml29623 
23253859Sml29623 	cfg->use_proto = 0;
23263859Sml29623 	cfg->use_dport = 0;
23273859Sml29623 	cfg->use_sport = 0;
23283859Sml29623 	cfg->ip_opts_exist = 0;
23293859Sml29623 	cfg->use_daddr = 0;
23303859Sml29623 	cfg->use_saddr = 0;
23313859Sml29623 	cfg->use_vlan = 0;
23323859Sml29623 	cfg->use_l2da = 0;
23333859Sml29623 	cfg->use_portnum  = 0;
23343859Sml29623 
23353859Sml29623 	REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
23363859Sml29623 
23373859Sml29623 	if (flow_cfg_reg.bits.ldw.proto) {
23383859Sml29623 		cfg->use_proto = 1;
23393859Sml29623 	}
23403859Sml29623 
23413859Sml29623 	if (flow_cfg_reg.bits.ldw.l4_1 == 2) {
23423859Sml29623 		cfg->use_dport = 1;
23433859Sml29623 	}
23443859Sml29623 
23453859Sml29623 	if (flow_cfg_reg.bits.ldw.l4_1 == 3) {
23463859Sml29623 		cfg->use_dport = 1;
23473859Sml29623 		cfg->ip_opts_exist = 1;
23483859Sml29623 	}
23493859Sml29623 
23503859Sml29623 	if (flow_cfg_reg.bits.ldw.l4_0 == 2) {
23513859Sml29623 		cfg->use_sport = 1;
23523859Sml29623 	}
23533859Sml29623 
23543859Sml29623 	if (flow_cfg_reg.bits.ldw.l4_0 == 3) {
23553859Sml29623 		cfg->use_sport = 1;
23563859Sml29623 		cfg->ip_opts_exist = 1;
23573859Sml29623 	}
23583859Sml29623 
23593859Sml29623 	if (flow_cfg_reg.bits.ldw.ipda) {
23603859Sml29623 		cfg->use_daddr = 1;
23613859Sml29623 	}
23623859Sml29623 
23633859Sml29623 	if (flow_cfg_reg.bits.ldw.ipsa) {
23643859Sml29623 		cfg->use_saddr = 1;
23653859Sml29623 	}
23663859Sml29623 
23673859Sml29623 	if (flow_cfg_reg.bits.ldw.vlan) {
23683859Sml29623 		cfg->use_vlan = 1;
23693859Sml29623 	}
23703859Sml29623 
23713859Sml29623 	if (flow_cfg_reg.bits.ldw.l2da) {
23723859Sml29623 		cfg->use_l2da = 1;
23733859Sml29623 	}
23743859Sml29623 
23753859Sml29623 	if (flow_cfg_reg.bits.ldw.port) {
23763859Sml29623 		cfg->use_portnum = 1;
23773859Sml29623 	}
23783859Sml29623 
23793859Sml29623 	NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
23806929Smisaki 	    " npi_fflp_cfg_ip_cls_flow_get %llx \n",
23816929Smisaki 	    flow_cfg_reg.value));
23823859Sml29623 
23833859Sml29623 	return (NPI_SUCCESS);
23843859Sml29623 
23853859Sml29623 }
23863859Sml29623 
2387*11304SJanie.Lu@Sun.COM /*
2388*11304SJanie.Lu@Sun.COM  * npi_fflp_cfg_ip_cls_flow_key_rfnl ()
2389*11304SJanie.Lu@Sun.COM  *
2390*11304SJanie.Lu@Sun.COM  * Configures the flow key generation for the IP classes
2391*11304SJanie.Lu@Sun.COM  * Flow key is used to generate the H1 hash function value
2392*11304SJanie.Lu@Sun.COM  * The fields used for the generation are configured using this
2393*11304SJanie.Lu@Sun.COM  * NPI function.
2394*11304SJanie.Lu@Sun.COM  *
2395*11304SJanie.Lu@Sun.COM  * Input
2396*11304SJanie.Lu@Sun.COM  *      handle:	opaque handle interpreted by the underlying OS
2397*11304SJanie.Lu@Sun.COM  *      l3_class:        IP class to configure flow key generation
2398*11304SJanie.Lu@Sun.COM  *      cfg:             Configuration bits:
2399*11304SJanie.Lu@Sun.COM  *		     l4_xor_sel:    bit field to select the L4 payload
2400*11304SJanie.Lu@Sun.COM  *				    bytes for X-OR to get hash key.
2401*11304SJanie.Lu@Sun.COM  *		     use_l4_md:	    Set to 1 for enabling L4-mode.
2402*11304SJanie.Lu@Sun.COM  *		     use_sym:	    Set to 1 to use symmetric mode.
2403*11304SJanie.Lu@Sun.COM  *                   use_proto:     Use IP proto field
2404*11304SJanie.Lu@Sun.COM  *                   use_dport:     use l4 destination port
2405*11304SJanie.Lu@Sun.COM  *                   use_sport:     use l4 source port
2406*11304SJanie.Lu@Sun.COM  *                   ip_opts_exist: IP Options Present
2407*11304SJanie.Lu@Sun.COM  *                   use_daddr:     use ip dest address
2408*11304SJanie.Lu@Sun.COM  *                   use_saddr:     use ip source address
2409*11304SJanie.Lu@Sun.COM  *                   use_vlan:      use VLAN ID
2410*11304SJanie.Lu@Sun.COM  *                   use_l2da:      use L2 Dest MAC Address
2411*11304SJanie.Lu@Sun.COM  *                   use_portnum:   use L2 virtual port number
2412*11304SJanie.Lu@Sun.COM  *
2413*11304SJanie.Lu@Sun.COM  *
2414*11304SJanie.Lu@Sun.COM  * Return
2415*11304SJanie.Lu@Sun.COM  * NPI success/failure status code
2416*11304SJanie.Lu@Sun.COM  */
2417*11304SJanie.Lu@Sun.COM 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)2418*11304SJanie.Lu@Sun.COM npi_fflp_cfg_ip_cls_flow_key_rfnl(npi_handle_t handle, tcam_class_t l3_class,
2419*11304SJanie.Lu@Sun.COM 		flow_key_cfg_t *cfg)
2420*11304SJanie.Lu@Sun.COM {
2421*11304SJanie.Lu@Sun.COM 	uint64_t offset;
2422*11304SJanie.Lu@Sun.COM 	flow_class_key_ip_t flow_cfg_reg;
2423*11304SJanie.Lu@Sun.COM 
2424*11304SJanie.Lu@Sun.COM 	ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
2425*11304SJanie.Lu@Sun.COM 	if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
2426*11304SJanie.Lu@Sun.COM 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2427*11304SJanie.Lu@Sun.COM 		    " npi_fflp_cfg_ip_cls_flow_key_rfnl:"
2428*11304SJanie.Lu@Sun.COM 		    " Invalid class %d \n",
2429*11304SJanie.Lu@Sun.COM 		    l3_class));
2430*11304SJanie.Lu@Sun.COM 		return (NPI_FFLP_TCAM_CLASS_INVALID);
2431*11304SJanie.Lu@Sun.COM 	}
2432*11304SJanie.Lu@Sun.COM 
2433*11304SJanie.Lu@Sun.COM 	if (l3_class == TCAM_CLASS_IPV6_FRAG) {
2434*11304SJanie.Lu@Sun.COM 		offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
2435*11304SJanie.Lu@Sun.COM 	} else {
2436*11304SJanie.Lu@Sun.COM 		offset = GET_FLOW_KEY_OFFSET(l3_class);
2437*11304SJanie.Lu@Sun.COM 	}
2438*11304SJanie.Lu@Sun.COM 
2439*11304SJanie.Lu@Sun.COM 	flow_cfg_reg.value = 0;
2440*11304SJanie.Lu@Sun.COM 
2441*11304SJanie.Lu@Sun.COM 	flow_cfg_reg.bits.ldw.l4_xor = cfg->l4_xor_sel;
2442*11304SJanie.Lu@Sun.COM 
2443*11304SJanie.Lu@Sun.COM 	if (cfg->use_l4_md)
2444*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.l4_mode = 1;
2445*11304SJanie.Lu@Sun.COM 
2446*11304SJanie.Lu@Sun.COM 	if (cfg->use_sym)
2447*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.sym = 1;
2448*11304SJanie.Lu@Sun.COM 
2449*11304SJanie.Lu@Sun.COM 	if (cfg->use_proto) {
2450*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.proto = 1;
2451*11304SJanie.Lu@Sun.COM 	}
2452*11304SJanie.Lu@Sun.COM 
2453*11304SJanie.Lu@Sun.COM 	if (cfg->use_dport) {
2454*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.l4_1 = 2;
2455*11304SJanie.Lu@Sun.COM 		if (cfg->ip_opts_exist)
2456*11304SJanie.Lu@Sun.COM 			flow_cfg_reg.bits.ldw.l4_1 = 3;
2457*11304SJanie.Lu@Sun.COM 	}
2458*11304SJanie.Lu@Sun.COM 
2459*11304SJanie.Lu@Sun.COM 	if (cfg->use_sport) {
2460*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.l4_0 = 2;
2461*11304SJanie.Lu@Sun.COM 		if (cfg->ip_opts_exist)
2462*11304SJanie.Lu@Sun.COM 			flow_cfg_reg.bits.ldw.l4_0 = 3;
2463*11304SJanie.Lu@Sun.COM 	}
2464*11304SJanie.Lu@Sun.COM 
2465*11304SJanie.Lu@Sun.COM 	if (cfg->use_daddr) {
2466*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE;
2467*11304SJanie.Lu@Sun.COM 	}
2468*11304SJanie.Lu@Sun.COM 
2469*11304SJanie.Lu@Sun.COM 	if (cfg->use_saddr) {
2470*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE;
2471*11304SJanie.Lu@Sun.COM 	}
2472*11304SJanie.Lu@Sun.COM 
2473*11304SJanie.Lu@Sun.COM 	if (cfg->use_vlan) {
2474*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE;
2475*11304SJanie.Lu@Sun.COM 	}
2476*11304SJanie.Lu@Sun.COM 
2477*11304SJanie.Lu@Sun.COM 	if (cfg->use_l2da) {
2478*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE;
2479*11304SJanie.Lu@Sun.COM 	}
2480*11304SJanie.Lu@Sun.COM 
2481*11304SJanie.Lu@Sun.COM 	if (cfg->use_portnum) {
2482*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.port = BIT_ENABLE;
2483*11304SJanie.Lu@Sun.COM 	}
2484*11304SJanie.Lu@Sun.COM 
2485*11304SJanie.Lu@Sun.COM 	REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2486*11304SJanie.Lu@Sun.COM 	return (NPI_SUCCESS);
2487*11304SJanie.Lu@Sun.COM 
2488*11304SJanie.Lu@Sun.COM }
2489*11304SJanie.Lu@Sun.COM 
2490*11304SJanie.Lu@Sun.COM npi_status_t
npi_fflp_cfg_sym_ip_cls_flow_key(npi_handle_t handle,tcam_class_t l3_class,boolean_t enable)2491*11304SJanie.Lu@Sun.COM npi_fflp_cfg_sym_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class,
2492*11304SJanie.Lu@Sun.COM 		boolean_t enable)
2493*11304SJanie.Lu@Sun.COM {
2494*11304SJanie.Lu@Sun.COM 	uint64_t offset;
2495*11304SJanie.Lu@Sun.COM 	flow_class_key_ip_t flow_cfg_reg;
2496*11304SJanie.Lu@Sun.COM 
2497*11304SJanie.Lu@Sun.COM 	ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
2498*11304SJanie.Lu@Sun.COM 	if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
2499*11304SJanie.Lu@Sun.COM 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2500*11304SJanie.Lu@Sun.COM 		    " npi_fflp_cfg_sym_ip_cls_flow_key:"
2501*11304SJanie.Lu@Sun.COM 		    " Invalid class %d \n",
2502*11304SJanie.Lu@Sun.COM 		    l3_class));
2503*11304SJanie.Lu@Sun.COM 		return (NPI_FFLP_TCAM_CLASS_INVALID);
2504*11304SJanie.Lu@Sun.COM 	}
2505*11304SJanie.Lu@Sun.COM 
2506*11304SJanie.Lu@Sun.COM 	if (l3_class == TCAM_CLASS_IPV6_FRAG) {
2507*11304SJanie.Lu@Sun.COM 		offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
2508*11304SJanie.Lu@Sun.COM 	} else {
2509*11304SJanie.Lu@Sun.COM 		offset = GET_FLOW_KEY_OFFSET(l3_class);
2510*11304SJanie.Lu@Sun.COM 	}
2511*11304SJanie.Lu@Sun.COM 
2512*11304SJanie.Lu@Sun.COM 	REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
2513*11304SJanie.Lu@Sun.COM 
2514*11304SJanie.Lu@Sun.COM 	if (enable && flow_cfg_reg.bits.ldw.sym == 0) {
2515*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.sym = 1;
2516*11304SJanie.Lu@Sun.COM 		REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2517*11304SJanie.Lu@Sun.COM 	} else if (!enable && flow_cfg_reg.bits.ldw.sym == 1) {
2518*11304SJanie.Lu@Sun.COM 		flow_cfg_reg.bits.ldw.sym = 0;
2519*11304SJanie.Lu@Sun.COM 		REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2520*11304SJanie.Lu@Sun.COM 	}
2521*11304SJanie.Lu@Sun.COM 
2522*11304SJanie.Lu@Sun.COM 	return (NPI_SUCCESS);
2523*11304SJanie.Lu@Sun.COM 
2524*11304SJanie.Lu@Sun.COM }
2525*11304SJanie.Lu@Sun.COM 
2526*11304SJanie.Lu@Sun.COM 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)2527*11304SJanie.Lu@Sun.COM npi_fflp_cfg_ip_cls_flow_key_get_rfnl(npi_handle_t handle,
2528*11304SJanie.Lu@Sun.COM 				    tcam_class_t l3_class,
2529*11304SJanie.Lu@Sun.COM 				    flow_key_cfg_t *cfg)
2530*11304SJanie.Lu@Sun.COM {
2531*11304SJanie.Lu@Sun.COM 	uint64_t offset;
2532*11304SJanie.Lu@Sun.COM 	flow_class_key_ip_t flow_cfg_reg;
2533*11304SJanie.Lu@Sun.COM 
2534*11304SJanie.Lu@Sun.COM 	ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
2535*11304SJanie.Lu@Sun.COM 	if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
2536*11304SJanie.Lu@Sun.COM 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2537*11304SJanie.Lu@Sun.COM 		    " npi_fflp_cfg_ip_cls_flow_key_get_rfnl:"
2538*11304SJanie.Lu@Sun.COM 		    " Invalid class %d \n",
2539*11304SJanie.Lu@Sun.COM 		    l3_class));
2540*11304SJanie.Lu@Sun.COM 		return (NPI_FFLP_TCAM_CLASS_INVALID);
2541*11304SJanie.Lu@Sun.COM 	}
2542*11304SJanie.Lu@Sun.COM 
2543*11304SJanie.Lu@Sun.COM 	if (l3_class == TCAM_CLASS_IPV6_FRAG) {
2544*11304SJanie.Lu@Sun.COM 		offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
2545*11304SJanie.Lu@Sun.COM 	} else {
2546*11304SJanie.Lu@Sun.COM 		offset = GET_FLOW_KEY_OFFSET(l3_class);
2547*11304SJanie.Lu@Sun.COM 	}
2548*11304SJanie.Lu@Sun.COM 
2549*11304SJanie.Lu@Sun.COM 	cfg->l4_xor_sel = 0;
2550*11304SJanie.Lu@Sun.COM 	cfg->use_l4_md = 0;
2551*11304SJanie.Lu@Sun.COM 	cfg->use_sym = 0;
2552*11304SJanie.Lu@Sun.COM 	cfg->use_proto = 0;
2553*11304SJanie.Lu@Sun.COM 	cfg->use_dport = 0;
2554*11304SJanie.Lu@Sun.COM 	cfg->use_sport = 0;
2555*11304SJanie.Lu@Sun.COM 	cfg->ip_opts_exist = 0;
2556*11304SJanie.Lu@Sun.COM 	cfg->use_daddr = 0;
2557*11304SJanie.Lu@Sun.COM 	cfg->use_saddr = 0;
2558*11304SJanie.Lu@Sun.COM 	cfg->use_vlan = 0;
2559*11304SJanie.Lu@Sun.COM 	cfg->use_l2da = 0;
2560*11304SJanie.Lu@Sun.COM 	cfg->use_portnum  = 0;
2561*11304SJanie.Lu@Sun.COM 
2562*11304SJanie.Lu@Sun.COM 	REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
2563*11304SJanie.Lu@Sun.COM 
2564*11304SJanie.Lu@Sun.COM 	cfg->l4_xor_sel = flow_cfg_reg.bits.ldw.l4_xor;
2565*11304SJanie.Lu@Sun.COM 
2566*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.l4_mode)
2567*11304SJanie.Lu@Sun.COM 		cfg->use_l4_md = 1;
2568*11304SJanie.Lu@Sun.COM 
2569*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.sym)
2570*11304SJanie.Lu@Sun.COM 		cfg->use_sym = 1;
2571*11304SJanie.Lu@Sun.COM 
2572*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.proto) {
2573*11304SJanie.Lu@Sun.COM 		cfg->use_proto = 1;
2574*11304SJanie.Lu@Sun.COM 	}
2575*11304SJanie.Lu@Sun.COM 
2576*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.l4_1 == 2) {
2577*11304SJanie.Lu@Sun.COM 		cfg->use_dport = 1;
2578*11304SJanie.Lu@Sun.COM 	}
2579*11304SJanie.Lu@Sun.COM 
2580*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.l4_1 == 3) {
2581*11304SJanie.Lu@Sun.COM 		cfg->use_dport = 1;
2582*11304SJanie.Lu@Sun.COM 		cfg->ip_opts_exist = 1;
2583*11304SJanie.Lu@Sun.COM 	}
2584*11304SJanie.Lu@Sun.COM 
2585*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.l4_0 == 2) {
2586*11304SJanie.Lu@Sun.COM 		cfg->use_sport = 1;
2587*11304SJanie.Lu@Sun.COM 	}
2588*11304SJanie.Lu@Sun.COM 
2589*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.l4_0 == 3) {
2590*11304SJanie.Lu@Sun.COM 		cfg->use_sport = 1;
2591*11304SJanie.Lu@Sun.COM 		cfg->ip_opts_exist = 1;
2592*11304SJanie.Lu@Sun.COM 	}
2593*11304SJanie.Lu@Sun.COM 
2594*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.ipda) {
2595*11304SJanie.Lu@Sun.COM 		cfg->use_daddr = 1;
2596*11304SJanie.Lu@Sun.COM 	}
2597*11304SJanie.Lu@Sun.COM 
2598*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.ipsa) {
2599*11304SJanie.Lu@Sun.COM 		cfg->use_saddr = 1;
2600*11304SJanie.Lu@Sun.COM 	}
2601*11304SJanie.Lu@Sun.COM 
2602*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.vlan) {
2603*11304SJanie.Lu@Sun.COM 		cfg->use_vlan = 1;
2604*11304SJanie.Lu@Sun.COM 	}
2605*11304SJanie.Lu@Sun.COM 
2606*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.l2da) {
2607*11304SJanie.Lu@Sun.COM 		cfg->use_l2da = 1;
2608*11304SJanie.Lu@Sun.COM 	}
2609*11304SJanie.Lu@Sun.COM 
2610*11304SJanie.Lu@Sun.COM 	if (flow_cfg_reg.bits.ldw.port) {
2611*11304SJanie.Lu@Sun.COM 		cfg->use_portnum = 1;
2612*11304SJanie.Lu@Sun.COM 	}
2613*11304SJanie.Lu@Sun.COM 
2614*11304SJanie.Lu@Sun.COM 	NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
2615*11304SJanie.Lu@Sun.COM 	    " npi_fflp_cfg_ip_cls_flow_get %llx \n",
2616*11304SJanie.Lu@Sun.COM 	    flow_cfg_reg.value));
2617*11304SJanie.Lu@Sun.COM 
2618*11304SJanie.Lu@Sun.COM 	return (NPI_SUCCESS);
2619*11304SJanie.Lu@Sun.COM 
2620*11304SJanie.Lu@Sun.COM }
2621*11304SJanie.Lu@Sun.COM 
26223859Sml29623 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)26233859Sml29623 npi_fflp_cfg_ip_cls_tcam_key_get(npi_handle_t handle,
26243859Sml29623 			    tcam_class_t l3_class, tcam_key_cfg_t *cfg)
26253859Sml29623 {
26263859Sml29623 	uint64_t offset;
26273859Sml29623 	tcam_class_key_ip_t tcam_cls_cfg;
26283859Sml29623 
26293859Sml29623 	ASSERT(TCAM_L3_CLASS_VALID(l3_class));
26303859Sml29623 	if (!(TCAM_L3_CLASS_VALID(l3_class))) {
26313859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
26326929Smisaki 		    " npi_fflp_cfg_ip_cls_tcam_key_get:"
26336929Smisaki 		    " Invalid class %d \n",
26346929Smisaki 		    l3_class));
26353859Sml29623 		return (NPI_FFLP_TCAM_CLASS_INVALID);
26363859Sml29623 	}
26373859Sml29623 
26383859Sml29623 
26393859Sml29623 	offset = GET_TCAM_KEY_OFFSET(l3_class);
26403859Sml29623 
26413859Sml29623 	REG_PIO_READ64(handle, offset, &tcam_cls_cfg.value);
26423859Sml29623 
26433859Sml29623 	cfg->discard = 0;
26443859Sml29623 	cfg->use_ip_saddr = 0;
26453859Sml29623 	cfg->use_ip_daddr = 1;
26463859Sml29623 	cfg->lookup_enable = 0;
26473859Sml29623 
26483859Sml29623 	if (tcam_cls_cfg.bits.ldw.discard)
26493859Sml29623 			cfg->discard = 1;
26503859Sml29623 
26513859Sml29623 	if (tcam_cls_cfg.bits.ldw.ipaddr) {
26523859Sml29623 		cfg->use_ip_saddr = 1;
26533859Sml29623 		cfg->use_ip_daddr = 0;
26543859Sml29623 	}
26553859Sml29623 
26563859Sml29623 	if (tcam_cls_cfg.bits.ldw.tsel) {
2657*11304SJanie.Lu@Sun.COM 		cfg->lookup_enable = 1;
26583859Sml29623 	}
26593859Sml29623 
26603859Sml29623 	NPI_DEBUG_MSG((handle.function, NPI_CTL,
26616929Smisaki 	    " npi_fflp_cfg_ip_cls_tcam_key_get %llx \n",
26626929Smisaki 	    tcam_cls_cfg.value));
26633859Sml29623 	return (NPI_SUCCESS);
26643859Sml29623 }
26653859Sml29623 
26663859Sml29623 /*
26673859Sml29623  * npi_fflp_cfg_fcram_access ()
26683859Sml29623  *
26693859Sml29623  * Sets the ratio between the FCRAM pio and lookup access
26703859Sml29623  * Input:
26713859Sml29623  * handle:	opaque handle interpreted by the underlying OS
26723859Sml29623  * access_ratio: 0  Lookup has the highest priority
26733859Sml29623  *		 15 PIO has maximum possible priority
26743859Sml29623  *
26753859Sml29623  * Return
26763859Sml29623  * NPI success/failure status code
26773859Sml29623  */
26783859Sml29623 npi_status_t
npi_fflp_cfg_fcram_access(npi_handle_t handle,uint8_t access_ratio)26793859Sml29623 npi_fflp_cfg_fcram_access(npi_handle_t handle, uint8_t access_ratio)
26803859Sml29623 {
26813859Sml29623 
26823859Sml29623 	fflp_cfg_1_t fflp_cfg;
26833859Sml29623 	uint64_t offset;
26843859Sml29623 	offset = FFLP_CFG_1_REG;
26853859Sml29623 
26863859Sml29623 	if (access_ratio > 0xf) {
26873859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
26886929Smisaki 		    " npi_fflp_cfg_fcram_access:"
26896929Smisaki 		    " Invalid access ratio %d \n",
26906929Smisaki 		    access_ratio));
26913859Sml29623 		return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
26923859Sml29623 	}
26933859Sml29623 
26943859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
26953859Sml29623 	fflp_cfg.bits.ldw.fflpinitdone = 0;
26963859Sml29623 	fflp_cfg.bits.ldw.fcramratio = access_ratio;
26973859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
26983859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
26993859Sml29623 	fflp_cfg.bits.ldw.fflpinitdone = 1;
27003859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
27013859Sml29623 	return (NPI_SUCCESS);
27023859Sml29623 
27033859Sml29623 }
27043859Sml29623 
27053859Sml29623 /*
27063859Sml29623  * npi_fflp_cfg_tcam_access ()
27073859Sml29623  *
27083859Sml29623  * Sets the ratio between the TCAM pio and lookup access
27093859Sml29623  * Input:
27103859Sml29623  * handle:	opaque handle interpreted by the underlying OS
27113859Sml29623  * access_ratio: 0  Lookup has the highest priority
27123859Sml29623  *		 15 PIO has maximum possible priority
27133859Sml29623  * Return
27143859Sml29623  * NPI success/failure status code
27153859Sml29623  */
27163859Sml29623 npi_status_t
npi_fflp_cfg_tcam_access(npi_handle_t handle,uint8_t access_ratio)27173859Sml29623 npi_fflp_cfg_tcam_access(npi_handle_t handle, uint8_t access_ratio)
27183859Sml29623 {
27193859Sml29623 	fflp_cfg_1_t fflp_cfg;
27203859Sml29623 	uint64_t offset;
27213859Sml29623 	offset = FFLP_CFG_1_REG;
27223859Sml29623 
27233859Sml29623 	if (access_ratio > 0xf) {
27243859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
27256929Smisaki 		    " npi_fflp_cfg_tcram_access:"
27266929Smisaki 		    " Invalid access ratio %d \n",
27276929Smisaki 		    access_ratio));
27283859Sml29623 		return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
27293859Sml29623 	}
27303859Sml29623 
27313859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
27323859Sml29623 	fflp_cfg.bits.ldw.fflpinitdone = 0;
27333859Sml29623 	fflp_cfg.bits.ldw.camratio = access_ratio;
27343859Sml29623 
27353859Sml29623 	/* since the cam latency is fixed, we might set it here */
27363859Sml29623 	fflp_cfg.bits.ldw.camlatency = TCAM_DEFAULT_LATENCY;
27373859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
27383859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
27393859Sml29623 	fflp_cfg.bits.ldw.fflpinitdone = 1;
27403859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
27413859Sml29623 
27423859Sml29623 	return (NPI_SUCCESS);
27433859Sml29623 }
27443859Sml29623 
27453859Sml29623 /*
27463859Sml29623  * npi_fflp_cfg_hash_h1poly()
27473859Sml29623  * Initializes the H1 hash generation logic.
27483859Sml29623  *
27493859Sml29623  * Input
27503859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
27513859Sml29623  *      init_value:       The initial value (seed)
27523859Sml29623  *
27533859Sml29623  * Return
27543859Sml29623  * NPI success/failure status code
27553859Sml29623  */
27563859Sml29623 npi_status_t
npi_fflp_cfg_hash_h1poly(npi_handle_t handle,uint32_t init_value)27573859Sml29623 npi_fflp_cfg_hash_h1poly(npi_handle_t handle, uint32_t init_value)
27583859Sml29623 {
27593859Sml29623 
27603859Sml29623 
27613859Sml29623 	hash_h1poly_t h1_cfg;
27623859Sml29623 	uint64_t offset;
27633859Sml29623 	offset = FFLP_H1POLY_REG;
27643859Sml29623 
27653859Sml29623 	h1_cfg.value = 0;
27663859Sml29623 	h1_cfg.bits.ldw.init_value = init_value;
27673859Sml29623 
27683859Sml29623 	REG_PIO_WRITE64(handle, offset, h1_cfg.value);
27693859Sml29623 	return (NPI_SUCCESS);
27703859Sml29623 }
27713859Sml29623 
27723859Sml29623 /*
27733859Sml29623  * npi_fflp_cfg_hash_h2poly()
27743859Sml29623  * Initializes the H2 hash generation logic.
27753859Sml29623  *
27763859Sml29623  * Input
27773859Sml29623  *      handle:	opaque handle interpreted by the underlying OS
27783859Sml29623  *      init_value:       The initial value (seed)
27793859Sml29623  *
27803859Sml29623  * Return
27813859Sml29623  * NPI_SUCCESS
27823859Sml29623  *
27833859Sml29623  */
27843859Sml29623 npi_status_t
npi_fflp_cfg_hash_h2poly(npi_handle_t handle,uint16_t init_value)27853859Sml29623 npi_fflp_cfg_hash_h2poly(npi_handle_t handle, uint16_t init_value)
27863859Sml29623 {
27873859Sml29623 
27883859Sml29623 
27893859Sml29623 	hash_h2poly_t h2_cfg;
27903859Sml29623 	uint64_t offset;
27913859Sml29623 	offset = FFLP_H2POLY_REG;
27923859Sml29623 
27933859Sml29623 	h2_cfg.value = 0;
27943859Sml29623 	h2_cfg.bits.ldw.init_value = init_value;
27953859Sml29623 
27963859Sml29623 	REG_PIO_WRITE64(handle, offset, h2_cfg.value);
27973859Sml29623 	return (NPI_SUCCESS);
27983859Sml29623 
27993859Sml29623 
28003859Sml29623 }
28013859Sml29623 
28023859Sml29623 /*
28033859Sml29623  *  npi_fflp_cfg_reset
28043859Sml29623  *  Initializes the FCRAM reset sequence.
28053859Sml29623  *
28063859Sml29623  *  Input
28073859Sml29623  *      handle:		opaque handle interpreted by the underlying OS
28083859Sml29623  *	strength:		FCRAM Drive strength
28093859Sml29623  *				   strong, weak or normal
28103859Sml29623  *				   HW recommended value:
28113859Sml29623  *	qs:			FCRAM QS mode selection
28123859Sml29623  *				   qs mode or free running
28133859Sml29623  *				   HW recommended value is:
28143859Sml29623  *
28153859Sml29623  * Return:
28163859Sml29623  * NPI success/failure status code
28173859Sml29623  */
28183859Sml29623 
28193859Sml29623 npi_status_t
npi_fflp_cfg_fcram_reset(npi_handle_t handle,fflp_fcram_output_drive_t strength,fflp_fcram_qs_t qs)28203859Sml29623 npi_fflp_cfg_fcram_reset(npi_handle_t handle,
28213859Sml29623 	fflp_fcram_output_drive_t strength, fflp_fcram_qs_t qs)
28223859Sml29623 {
28233859Sml29623 	fflp_cfg_1_t fflp_cfg;
28243859Sml29623 	uint64_t offset;
28253859Sml29623 	offset = FFLP_CFG_1_REG;
28263859Sml29623 
28273859Sml29623 	/* These bits have to be configured before FCRAM reset is issued */
28283859Sml29623 	fflp_cfg.value = 0;
28293859Sml29623 	fflp_cfg.bits.ldw.pio_fio_rst = 1;
28303859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
28313859Sml29623 
28323859Sml29623 	NXGE_DELAY(5); /* TODO: What is the correct delay? */
28333859Sml29623 
28343859Sml29623 	fflp_cfg.bits.ldw.pio_fio_rst = 0;
28353859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
28363859Sml29623 	fflp_cfg.bits.ldw.fcramqs = qs;
28373859Sml29623 	fflp_cfg.bits.ldw.fcramoutdr = strength;
28383859Sml29623 	fflp_cfg.bits.ldw.fflpinitdone = 1;
28393859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
28403859Sml29623 
28413859Sml29623 	return (NPI_SUCCESS);
28423859Sml29623 }
28433859Sml29623 
28443859Sml29623 npi_status_t
npi_fflp_cfg_init_done(npi_handle_t handle)28453859Sml29623 npi_fflp_cfg_init_done(npi_handle_t handle)
28463859Sml29623 
28473859Sml29623 {
28483859Sml29623 
28493859Sml29623 	fflp_cfg_1_t fflp_cfg;
28503859Sml29623 	uint64_t offset;
28513859Sml29623 	offset = FFLP_CFG_1_REG;
28523859Sml29623 
28533859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
28543859Sml29623 	fflp_cfg.bits.ldw.fflpinitdone = 1;
28553859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
28563859Sml29623 	return (NPI_SUCCESS);
28573859Sml29623 
28583859Sml29623 }
28593859Sml29623 
28603859Sml29623 npi_status_t
npi_fflp_cfg_init_start(npi_handle_t handle)28613859Sml29623 npi_fflp_cfg_init_start(npi_handle_t handle)
28623859Sml29623 
28633859Sml29623 {
28643859Sml29623 
28653859Sml29623 	fflp_cfg_1_t fflp_cfg;
28663859Sml29623 	uint64_t offset;
28673859Sml29623 	offset = FFLP_CFG_1_REG;
28683859Sml29623 
28693859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
28703859Sml29623 	fflp_cfg.bits.ldw.fflpinitdone = 0;
28713859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
28723859Sml29623 	return (NPI_SUCCESS);
28733859Sml29623 
28743859Sml29623 }
28753859Sml29623 
28763859Sml29623 /*
28773859Sml29623  * Enables the TCAM search function.
28783859Sml29623  *
28793859Sml29623  */
28803859Sml29623 npi_status_t
npi_fflp_cfg_tcam_enable(npi_handle_t handle)28813859Sml29623 npi_fflp_cfg_tcam_enable(npi_handle_t handle)
28823859Sml29623 
28833859Sml29623 {
28843859Sml29623 
28853859Sml29623 	fflp_cfg_1_t fflp_cfg;
28863859Sml29623 	uint64_t offset;
28873859Sml29623 	offset = FFLP_CFG_1_REG;
28883859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
28893859Sml29623 	fflp_cfg.bits.ldw.tcam_disable = 0;
28903859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
28913859Sml29623 	return (NPI_SUCCESS);
28923859Sml29623 
28933859Sml29623 }
28943859Sml29623 
28953859Sml29623 /*
28963859Sml29623  * Disables the TCAM search function.
28973859Sml29623  * While the TCAM is in disabled state, all TCAM matches would return NO_MATCH
28983859Sml29623  *
28993859Sml29623  */
29003859Sml29623 npi_status_t
npi_fflp_cfg_tcam_disable(npi_handle_t handle)29013859Sml29623 npi_fflp_cfg_tcam_disable(npi_handle_t handle)
29023859Sml29623 
29033859Sml29623 {
29043859Sml29623 
29053859Sml29623 	fflp_cfg_1_t fflp_cfg;
29063859Sml29623 	uint64_t offset;
29073859Sml29623 	offset = FFLP_CFG_1_REG;
29083859Sml29623 	REG_PIO_READ64(handle, offset, &fflp_cfg.value);
29093859Sml29623 	fflp_cfg.bits.ldw.tcam_disable = 1;
29103859Sml29623 	REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
29113859Sml29623 	return (NPI_SUCCESS);
29123859Sml29623 
29133859Sml29623 }
29143859Sml29623 
29153859Sml29623 /*
29163859Sml29623  * npi_rxdma_event_mask_config():
29173859Sml29623  *	This function is called to operate on the event mask
29183859Sml29623  *	register which is used for generating interrupts
29193859Sml29623  *	and status register.
29203859Sml29623  */
29213859Sml29623 npi_status_t
npi_fflp_event_mask_config(npi_handle_t handle,io_op_t op_mode,fflp_event_mask_cfg_t * mask_cfgp)29223859Sml29623 npi_fflp_event_mask_config(npi_handle_t handle, io_op_t op_mode,
29233859Sml29623 		fflp_event_mask_cfg_t *mask_cfgp)
29243859Sml29623 {
29253859Sml29623 	int		status = NPI_SUCCESS;
29263859Sml29623 	fflp_err_mask_t mask_reg;
29273859Sml29623 
29283859Sml29623 	switch (op_mode) {
29293859Sml29623 	case OP_GET:
29303859Sml29623 
29313859Sml29623 		REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value);
29323859Sml29623 		*mask_cfgp = mask_reg.value & FFLP_ERR_MASK_ALL;
29333859Sml29623 		break;
29343859Sml29623 
29353859Sml29623 	case OP_SET:
29363859Sml29623 		mask_reg.value = (~(*mask_cfgp) & FFLP_ERR_MASK_ALL);
29373859Sml29623 		REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
29383859Sml29623 		break;
29393859Sml29623 
29403859Sml29623 	case OP_UPDATE:
29413859Sml29623 		REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value);
29423859Sml29623 		mask_reg.value |=  (~(*mask_cfgp) & FFLP_ERR_MASK_ALL);
29433859Sml29623 		REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
29443859Sml29623 		break;
29453859Sml29623 
29463859Sml29623 	case OP_CLEAR:
29473859Sml29623 		mask_reg.value = FFLP_ERR_MASK_ALL;
29483859Sml29623 		REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
29493859Sml29623 		break;
29503859Sml29623 	default:
29513859Sml29623 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
29523859Sml29623 		    " npi_fflp_event_mask_config",
29533859Sml29623 		    " eventmask <0x%x>", op_mode));
29543859Sml29623 		return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
29553859Sml29623 	}
29563859Sml29623 
29573859Sml29623 	return (status);
29583859Sml29623 }
29593859Sml29623 
29603859Sml29623 /*
29613859Sml29623  * Read vlan error bits
29623859Sml29623  */
29633859Sml29623 void
npi_fflp_vlan_error_get(npi_handle_t handle,p_vlan_par_err_t p_err)29643859Sml29623 npi_fflp_vlan_error_get(npi_handle_t handle, p_vlan_par_err_t p_err)
29653859Sml29623 {
29663859Sml29623 	REG_PIO_READ64(handle, FFLP_VLAN_PAR_ERR_REG, &p_err->value);
29673859Sml29623 }
29683859Sml29623 
29693859Sml29623 /*
29703859Sml29623  * clear vlan error bits
29713859Sml29623  */
29723859Sml29623 void
npi_fflp_vlan_error_clear(npi_handle_t handle)29733859Sml29623 npi_fflp_vlan_error_clear(npi_handle_t handle)
29743859Sml29623 {
29753859Sml29623 	vlan_par_err_t p_err;
29763859Sml29623 	p_err.value  = 0;
29773859Sml29623 	p_err.bits.ldw.m_err = 0;
29783859Sml29623 	p_err.bits.ldw.err = 0;
29793859Sml29623 	REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, p_err.value);
29803859Sml29623 
29813859Sml29623 }
29823859Sml29623 
29833859Sml29623 /*
29843859Sml29623  * Read TCAM error bits
29853859Sml29623  */
29863859Sml29623 void
npi_fflp_tcam_error_get(npi_handle_t handle,p_tcam_err_t p_err)29873859Sml29623 npi_fflp_tcam_error_get(npi_handle_t handle, p_tcam_err_t p_err)
29883859Sml29623 {
29893859Sml29623 	REG_PIO_READ64(handle, FFLP_TCAM_ERR_REG, &p_err->value);
29903859Sml29623 }
29913859Sml29623 
29923859Sml29623 /*
29933859Sml29623  * clear TCAM error bits
29943859Sml29623  */
29953859Sml29623 void
npi_fflp_tcam_error_clear(npi_handle_t handle)29963859Sml29623 npi_fflp_tcam_error_clear(npi_handle_t handle)
29973859Sml29623 {
29983859Sml29623 	tcam_err_t p_err;
29993859Sml29623 
30003859Sml29623 	p_err.value  = 0;
30013859Sml29623 	p_err.bits.ldw.p_ecc = 0;
30023859Sml29623 	p_err.bits.ldw.mult = 0;
30033859Sml29623 	p_err.bits.ldw.err = 0;
30043859Sml29623 	REG_PIO_WRITE64(handle, FFLP_TCAM_ERR_REG, p_err.value);
30053859Sml29623 
30063859Sml29623 }
30073859Sml29623 
30083859Sml29623 /*
30093859Sml29623  * Read FCRAM error bits
30103859Sml29623  */
30113859Sml29623 void
npi_fflp_fcram_error_get(npi_handle_t handle,p_hash_tbl_data_log_t p_err,uint8_t partition)30123859Sml29623 npi_fflp_fcram_error_get(npi_handle_t handle,
30133859Sml29623 	p_hash_tbl_data_log_t p_err, uint8_t partition)
30143859Sml29623 {
30153859Sml29623 	uint64_t offset;
30163859Sml29623 
30173859Sml29623 	offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192;
30183859Sml29623 	REG_PIO_READ64(handle, offset, &p_err->value);
30193859Sml29623 }
30203859Sml29623 
30213859Sml29623 /*
30223859Sml29623  * clear FCRAM error bits
30233859Sml29623  */
30243859Sml29623 void
npi_fflp_fcram_error_clear(npi_handle_t handle,uint8_t partition)30253859Sml29623 npi_fflp_fcram_error_clear(npi_handle_t handle, uint8_t partition)
30263859Sml29623 {
30273859Sml29623 	hash_tbl_data_log_t p_err;
30283859Sml29623 	uint64_t offset;
30293859Sml29623 
30303859Sml29623 	p_err.value  = 0;
30313859Sml29623 	p_err.bits.ldw.pio_err = 0;
30323859Sml29623 	offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192;
30333859Sml29623 
30343859Sml29623 	REG_PIO_WRITE64(handle, offset,
30356929Smisaki 	    p_err.value);
30363859Sml29623 
30373859Sml29623 }
30383859Sml29623 
30393859Sml29623 /*
30403859Sml29623  * Read FCRAM lookup error log1 bits
30413859Sml29623  */
30423859Sml29623 void
npi_fflp_fcram_error_log1_get(npi_handle_t handle,p_hash_lookup_err_log1_t log1)30433859Sml29623 npi_fflp_fcram_error_log1_get(npi_handle_t handle,
30443859Sml29623 			    p_hash_lookup_err_log1_t log1)
30453859Sml29623 {
30463859Sml29623 	REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG1_REG,
30476929Smisaki 	    &log1->value);
30483859Sml29623 }
30493859Sml29623 
30503859Sml29623 /*
30513859Sml29623  * Read FCRAM lookup error log2 bits
30523859Sml29623  */
30533859Sml29623 void
npi_fflp_fcram_error_log2_get(npi_handle_t handle,p_hash_lookup_err_log2_t log2)30543859Sml29623 npi_fflp_fcram_error_log2_get(npi_handle_t handle,
30553859Sml29623 		    p_hash_lookup_err_log2_t log2)
30563859Sml29623 {
30573859Sml29623 	REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG2_REG,
30586929Smisaki 	    &log2->value);
30593859Sml29623 }
3060