xref: /onnv-gate/usr/src/uts/common/io/nxge/nxge_fflp.c (revision 11878:ac93462db6d7)
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  */
21*11878SVenu.Iyer@Sun.COM 
223859Sml29623 /*
23*11878SVenu.Iyer@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
243859Sml29623  * Use is subject to license terms.
253859Sml29623  */
263859Sml29623 
273859Sml29623 #include <npi_fflp.h>
283859Sml29623 #include <npi_mac.h>
293859Sml29623 #include <nxge_defs.h>
303859Sml29623 #include <nxge_flow.h>
313859Sml29623 #include <nxge_fflp.h>
323859Sml29623 #include <nxge_impl.h>
333859Sml29623 #include <nxge_fflp_hash.h>
343859Sml29623 #include <nxge_common.h>
353859Sml29623 
363859Sml29623 
373859Sml29623 /*
383859Sml29623  * Function prototypes
393859Sml29623  */
403859Sml29623 static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t);
413859Sml29623 static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t);
423859Sml29623 static nxge_status_t nxge_fflp_tcam_init(p_nxge_t);
433859Sml29623 static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t);
443859Sml29623 static nxge_status_t nxge_fflp_fcram_init(p_nxge_t);
453859Sml29623 static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *);
463859Sml29623 static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
473859Sml29623 static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
483859Sml29623 static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
493859Sml29623 static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *,
503859Sml29623 	tcam_entry_t *);
513859Sml29623 static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *,
523859Sml29623 	tcam_entry_t *);
533859Sml29623 static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *,
543859Sml29623 	tcam_entry_t *);
5511304SJanie.Lu@Sun.COM static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t);
5611304SJanie.Lu@Sun.COM static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t);
5711304SJanie.Lu@Sun.COM static uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t);
5811304SJanie.Lu@Sun.COM static uint32_t nxge_tcam_cls_to_flow(uint32_t);
5911304SJanie.Lu@Sun.COM static uint8_t nxge_iptun_pkt_type_to_pid(uint8_t);
6011304SJanie.Lu@Sun.COM static npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t,
6111304SJanie.Lu@Sun.COM 					iptun_cfg_t *);
6211304SJanie.Lu@Sun.COM static boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *);
633859Sml29623 
643859Sml29623 /*
653859Sml29623  * functions used outside this file
663859Sml29623  */
673859Sml29623 nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t);
683859Sml29623 nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t);
693859Sml29623 nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *);
703859Sml29623 static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t);
713859Sml29623 nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *);
723859Sml29623 nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *);
733859Sml29623 nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *,
743859Sml29623 	uint32_t *, uint16_t *);
7511304SJanie.Lu@Sun.COM int nxge_get_valid_tcam_cnt(p_nxge_t);
7611304SJanie.Lu@Sun.COM void nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *);
7711304SJanie.Lu@Sun.COM void nxge_get_tcam_entry(p_nxge_t, flow_resource_t *);
7811304SJanie.Lu@Sun.COM void nxge_del_tcam_entry(p_nxge_t, uint32_t);
7911304SJanie.Lu@Sun.COM void nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *);
8011304SJanie.Lu@Sun.COM void nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t);
8111304SJanie.Lu@Sun.COM void nxge_del_iptun_class(p_nxge_t, uint8_t);
8211304SJanie.Lu@Sun.COM void nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t);
8311304SJanie.Lu@Sun.COM void nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t);
8411304SJanie.Lu@Sun.COM void nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *);
8511304SJanie.Lu@Sun.COM 
863859Sml29623 
873859Sml29623 nxge_status_t
nxge_tcam_dump_entry(p_nxge_t nxgep,uint32_t location)883859Sml29623 nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location)
893859Sml29623 {
903859Sml29623 	tcam_entry_t tcam_rdptr;
913859Sml29623 	uint64_t asc_ram = 0;
923859Sml29623 	npi_handle_t handle;
933859Sml29623 	npi_status_t status;
943859Sml29623 
953859Sml29623 	handle = nxgep->npi_reg_handle;
963859Sml29623 
973859Sml29623 	bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry));
983859Sml29623 	status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location,
996929Smisaki 	    (struct tcam_entry *)&tcam_rdptr);
1003859Sml29623 	if (status & NPI_FAILURE) {
1013859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1026929Smisaki 		    " nxge_tcam_dump_entry:"
1036929Smisaki 		    "  tcam read failed at location %d ", location));
1043859Sml29623 		return (NXGE_ERROR);
1053859Sml29623 	}
1063859Sml29623 	status = npi_fflp_tcam_asc_ram_entry_read(handle,
1076929Smisaki 	    (tcam_location_t)location, &asc_ram);
1083859Sml29623 
1093859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n"
1106929Smisaki 	    " key:  %llx %llx %llx %llx \n"
1116929Smisaki 	    " mask: %llx %llx %llx %llx \n"
1126929Smisaki 	    " ASC RAM %llx \n", location,
1136929Smisaki 	    tcam_rdptr.key0, tcam_rdptr.key1,
1146929Smisaki 	    tcam_rdptr.key2, tcam_rdptr.key3,
1156929Smisaki 	    tcam_rdptr.mask0, tcam_rdptr.mask1,
1166929Smisaki 	    tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram));
1173859Sml29623 	return (NXGE_OK);
1183859Sml29623 }
1193859Sml29623 
1203859Sml29623 void
nxge_get_tcam(p_nxge_t nxgep,p_mblk_t mp)1213859Sml29623 nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp)
1223859Sml29623 {
1233859Sml29623 	uint32_t tcam_loc;
1243859Sml29623 	int *lptr;
1253859Sml29623 	int location;
1263859Sml29623 
1273859Sml29623 	uint32_t start_location = 0;
1283859Sml29623 	uint32_t stop_location = nxgep->classifier.tcam_size;
1293859Sml29623 	lptr = (int *)mp->b_rptr;
1303859Sml29623 	location = *lptr;
1313859Sml29623 
1323859Sml29623 	if ((location >= nxgep->classifier.tcam_size) || (location < -1)) {
1333859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1346929Smisaki 		    "nxge_tcam_dump: Invalid location %d \n", location));
1353859Sml29623 		return;
1363859Sml29623 	}
1373859Sml29623 	if (location == -1) {
1383859Sml29623 		start_location = 0;
1393859Sml29623 		stop_location = nxgep->classifier.tcam_size;
1403859Sml29623 	} else {
1413859Sml29623 		start_location = location;
1423859Sml29623 		stop_location = location + 1;
1433859Sml29623 	}
1443859Sml29623 	for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++)
1453859Sml29623 		(void) nxge_tcam_dump_entry(nxgep, tcam_loc);
1463859Sml29623 }
1473859Sml29623 
1483859Sml29623 /*
1493859Sml29623  * nxge_fflp_vlan_table_invalidate_all
1503859Sml29623  * invalidates the vlan RDC table entries.
1513859Sml29623  * INPUT
1523859Sml29623  * nxge    soft state data structure
1533859Sml29623  * Return
1543859Sml29623  *      NXGE_OK
1553859Sml29623  *      NXGE_ERROR
1563859Sml29623  *
1573859Sml29623  */
1583859Sml29623 
1593859Sml29623 static nxge_status_t
nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)1603859Sml29623 nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)
1613859Sml29623 {
1623859Sml29623 	vlan_id_t vlan_id;
1633859Sml29623 	npi_handle_t handle;
1643859Sml29623 	npi_status_t rs = NPI_SUCCESS;
1653859Sml29623 	vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
1663859Sml29623 
1673859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all "));
1683859Sml29623 	handle = nxgep->npi_reg_handle;
1693859Sml29623 	for (vlan_id = start; vlan_id < stop; vlan_id++) {
1703859Sml29623 		rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id);
1713859Sml29623 		if (rs != NPI_SUCCESS) {
1723859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1736929Smisaki 			    "VLAN Table invalidate failed for vlan id %d ",
1746929Smisaki 			    vlan_id));
1753859Sml29623 			return (NXGE_ERROR | rs);
1763859Sml29623 		}
1773859Sml29623 	}
1783859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all "));
1793859Sml29623 	return (NXGE_OK);
1803859Sml29623 }
1813859Sml29623 
1823859Sml29623 /*
1833859Sml29623  * The following functions are used by other modules to init
1843859Sml29623  * the fflp module.
1853859Sml29623  * these functions are the basic API used to init
1863859Sml29623  * the fflp modules (tcam, fcram etc ......)
1873859Sml29623  *
1883859Sml29623  * The TCAM search future would be disabled  by default.
1893859Sml29623  */
1903859Sml29623 
1913859Sml29623 static nxge_status_t
nxge_fflp_tcam_init(p_nxge_t nxgep)1923859Sml29623 nxge_fflp_tcam_init(p_nxge_t nxgep)
1933859Sml29623 {
1943859Sml29623 	uint8_t access_ratio;
1953859Sml29623 	tcam_class_t class;
1963859Sml29623 	npi_status_t rs = NPI_SUCCESS;
1973859Sml29623 	npi_handle_t handle;
1983859Sml29623 
1993859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init"));
2003859Sml29623 	handle = nxgep->npi_reg_handle;
2013859Sml29623 
2023859Sml29623 	rs = npi_fflp_cfg_tcam_disable(handle);
2033859Sml29623 	if (rs != NPI_SUCCESS) {
2043859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n"));
2053859Sml29623 		return (NXGE_ERROR | rs);
2063859Sml29623 	}
2073859Sml29623 
2083859Sml29623 	access_ratio = nxgep->param_arr[param_tcam_access_ratio].value;
2093859Sml29623 	rs = npi_fflp_cfg_tcam_access(handle, access_ratio);
2103859Sml29623 	if (rs != NPI_SUCCESS) {
2113859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2126929Smisaki 		    "failed TCAM Access cfg\n"));
2133859Sml29623 		return (NXGE_ERROR | rs);
2143859Sml29623 	}
2153859Sml29623 
2163859Sml29623 	/* disable configurable classes */
2173859Sml29623 	/* disable the configurable ethernet classes; */
2183859Sml29623 	for (class = TCAM_CLASS_ETYPE_1;
2196929Smisaki 	    class <= TCAM_CLASS_ETYPE_2; class++) {
2203859Sml29623 		rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class);
2213859Sml29623 		if (rs != NPI_SUCCESS) {
2223859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2236929Smisaki 			    "TCAM USR Ether Class config failed."));
2243859Sml29623 			return (NXGE_ERROR | rs);
2253859Sml29623 		}
2263859Sml29623 	}
2273859Sml29623 
2283859Sml29623 	/* disable the configurable ip classes; */
2293859Sml29623 	for (class = TCAM_CLASS_IP_USER_4;
2306929Smisaki 	    class <= TCAM_CLASS_IP_USER_7; class++) {
2313859Sml29623 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
2323859Sml29623 		if (rs != NPI_SUCCESS) {
2333859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2346929Smisaki 			    "TCAM USR IP Class cnfg failed."));
2353859Sml29623 			return (NXGE_ERROR | rs);
2363859Sml29623 		}
2373859Sml29623 	}
2383859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init"));
2393859Sml29623 	return (NXGE_OK);
2403859Sml29623 }
2413859Sml29623 
2423859Sml29623 /*
2433859Sml29623  * nxge_fflp_tcam_invalidate_all
2443859Sml29623  * invalidates all the tcam entries.
2453859Sml29623  * INPUT
2463859Sml29623  * nxge    soft state data structure
2473859Sml29623  * Return
2483859Sml29623  *      NXGE_OK
2493859Sml29623  *      NXGE_ERROR
2503859Sml29623  *
2513859Sml29623  */
2523859Sml29623 
2533859Sml29623 
2543859Sml29623 static nxge_status_t
nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)2553859Sml29623 nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)
2563859Sml29623 {
2573859Sml29623 	uint16_t location;
2583859Sml29623 	npi_status_t rs = NPI_SUCCESS;
2593859Sml29623 	npi_handle_t handle;
2603859Sml29623 	uint16_t start = 0, stop = nxgep->classifier.tcam_size;
2613859Sml29623 	p_nxge_hw_list_t hw_p;
2623859Sml29623 
2633859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
2646929Smisaki 	    "==> nxge_fflp_tcam_invalidate_all"));
2653859Sml29623 	handle = nxgep->npi_reg_handle;
2663859Sml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
2673859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2686929Smisaki 		    " nxge_fflp_tcam_invalidate_all:"
2696929Smisaki 		    " common hardware not set", nxgep->niu_type));
2703859Sml29623 		return (NXGE_ERROR);
2713859Sml29623 	}
2723859Sml29623 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
2733859Sml29623 	for (location = start; location < stop; location++) {
2743859Sml29623 		rs = npi_fflp_tcam_entry_invalidate(handle, location);
2753859Sml29623 		if (rs != NPI_SUCCESS) {
2763859Sml29623 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2773859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2786929Smisaki 			    "TCAM invalidate failed at loc %d ", location));
2793859Sml29623 			return (NXGE_ERROR | rs);
2803859Sml29623 		}
2813859Sml29623 	}
2823859Sml29623 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2833859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
2846929Smisaki 	    "<== nxge_fflp_tcam_invalidate_all"));
2853859Sml29623 	return (NXGE_OK);
2863859Sml29623 }
2873859Sml29623 
2883859Sml29623 /*
2893859Sml29623  * nxge_fflp_fcram_entry_invalidate_all
2903859Sml29623  * invalidates all the FCRAM entries.
2913859Sml29623  * INPUT
2923859Sml29623  * nxge    soft state data structure
2933859Sml29623  * Return
2943859Sml29623  *      NXGE_OK
2953859Sml29623  *      NXGE_ERROR
2963859Sml29623  *
2973859Sml29623  */
2983859Sml29623 
2993859Sml29623 static nxge_status_t
nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)3003859Sml29623 nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)
3013859Sml29623 {
3023859Sml29623 	npi_handle_t handle;
3033859Sml29623 	npi_status_t rs = NPI_SUCCESS;
3043859Sml29623 	part_id_t pid = 0;
3053859Sml29623 	uint8_t base_mask, base_reloc;
3063859Sml29623 	fcram_entry_t fc;
3073859Sml29623 	uint32_t location;
3083859Sml29623 	uint32_t increment, last_location;
3093859Sml29623 
3103859Sml29623 	/*
3113859Sml29623 	 * (1) configure and enable partition 0 with no relocation
3123859Sml29623 	 * (2) Assume the FCRAM is used as IPv4 exact match entry cells
3133859Sml29623 	 * (3) Invalidate these cells by clearing the valid bit in
3143859Sml29623 	 * the subareas 0 and 4
3153859Sml29623 	 * (4) disable the partition
3163859Sml29623 	 *
3173859Sml29623 	 */
3183859Sml29623 
3193859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all"));
3203859Sml29623 
3213859Sml29623 	base_mask = base_reloc = 0x0;
3223859Sml29623 	handle = nxgep->npi_reg_handle;
3233859Sml29623 	rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc);
3243859Sml29623 
3253859Sml29623 	if (rs != NPI_SUCCESS) {
3263859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n"));
3273859Sml29623 		return (NXGE_ERROR | rs);
3283859Sml29623 	}
3293859Sml29623 	rs = npi_fflp_cfg_fcram_partition_disable(handle, pid);
3303859Sml29623 
3313859Sml29623 	if (rs != NPI_SUCCESS) {
3323859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3336929Smisaki 		    "failed partition enable\n"));
3343859Sml29623 		return (NXGE_ERROR | rs);
3353859Sml29623 	}
3363859Sml29623 	fc.dreg[0].value = 0;
3373859Sml29623 	fc.hash_hdr_valid = 0;
3383859Sml29623 	fc.hash_hdr_ext = 1;	/* specify as IPV4 exact match entry */
3393859Sml29623 	increment = sizeof (hash_ipv4_t);
3403859Sml29623 	last_location = FCRAM_SIZE * 0x40;
3413859Sml29623 
3423859Sml29623 	for (location = 0; location < last_location; location += increment) {
3433859Sml29623 		rs = npi_fflp_fcram_subarea_write(handle, pid,
3446929Smisaki 		    location, fc.value[0]);
3453859Sml29623 		if (rs != NPI_SUCCESS) {
3463859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3476929Smisaki 			    "failed write at location %x ", location));
3483859Sml29623 			return (NXGE_ERROR | rs);
3493859Sml29623 		}
3503859Sml29623 	}
3513859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all"));
3523859Sml29623 	return (NXGE_OK);
3533859Sml29623 }
3543859Sml29623 
3553859Sml29623 static nxge_status_t
nxge_fflp_fcram_init(p_nxge_t nxgep)3563859Sml29623 nxge_fflp_fcram_init(p_nxge_t nxgep)
3573859Sml29623 {
3583859Sml29623 	fflp_fcram_output_drive_t strength;
3593859Sml29623 	fflp_fcram_qs_t qs;
3603859Sml29623 	npi_status_t rs = NPI_SUCCESS;
3613859Sml29623 	uint8_t access_ratio;
3623859Sml29623 	int partition;
3633859Sml29623 	npi_handle_t handle;
3643859Sml29623 	uint32_t min_time, max_time, sys_time;
3653859Sml29623 
3663859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init"));
3673859Sml29623 
3683859Sml29623 	/*
3693859Sml29623 	 * Recommended values are needed.
3703859Sml29623 	 */
3713859Sml29623 	min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME;
3723859Sml29623 	max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME;
3733859Sml29623 	sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME;
3743859Sml29623 
3753859Sml29623 	handle = nxgep->npi_reg_handle;
3763859Sml29623 	strength = FCRAM_OUTDR_NORMAL;
3773859Sml29623 	qs = FCRAM_QS_MODE_QS;
3783859Sml29623 	rs = npi_fflp_cfg_fcram_reset(handle, strength, qs);
3793859Sml29623 	if (rs != NPI_SUCCESS) {
3803859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. "));
3813859Sml29623 		return (NXGE_ERROR | rs);
3823859Sml29623 	}
3833859Sml29623 
3843859Sml29623 	access_ratio = nxgep->param_arr[param_fcram_access_ratio].value;
3853859Sml29623 	rs = npi_fflp_cfg_fcram_access(handle, access_ratio);
3863859Sml29623 	if (rs != NPI_SUCCESS) {
3873859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio"
3886929Smisaki 		    "configuration \n"));
3893859Sml29623 		return (NXGE_ERROR | rs);
3903859Sml29623 	}
3913859Sml29623 	rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time,
3926929Smisaki 	    max_time, sys_time);
3933859Sml29623 	if (rs != NPI_SUCCESS) {
3943859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3956929Smisaki 		    "failed FCRAM refresh cfg"));
3963859Sml29623 		return (NXGE_ERROR);
3973859Sml29623 	}
3983859Sml29623 
3993859Sml29623 	/* disable all the partitions until explicitly enabled */
4003859Sml29623 	for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) {
4013859Sml29623 		rs = npi_fflp_cfg_fcram_partition_disable(handle, partition);
4023859Sml29623 		if (rs != NPI_SUCCESS) {
4033859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4046929Smisaki 			    "failed FCRAM partition"
4056929Smisaki 			    " enable for partition %d ", partition));
4063859Sml29623 			return (NXGE_ERROR | rs);
4073859Sml29623 		}
4083859Sml29623 	}
4093859Sml29623 
4103859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init"));
4113859Sml29623 	return (NXGE_OK);
4123859Sml29623 }
4133859Sml29623 
4143859Sml29623 nxge_status_t
nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep,uint8_t alt_mac)4153859Sml29623 nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac)
4163859Sml29623 {
4173859Sml29623 	npi_status_t rs = NPI_SUCCESS;
4183859Sml29623 	hostinfo_t mac_rdc;
4193859Sml29623 	npi_handle_t handle;
4203859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
4213859Sml29623 
4223859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
4233859Sml29623 	if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) {
4243859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4256929Smisaki 		    " nxge_logical_mac_assign_rdc_table"
4266929Smisaki 		    " unconfigured alt MAC addr %d ", alt_mac));
4273859Sml29623 		return (NXGE_ERROR);
4283859Sml29623 	}
4293859Sml29623 	handle = nxgep->npi_reg_handle;
4303859Sml29623 	mac_rdc.value = 0;
4313859Sml29623 	mac_rdc.bits.w0.rdc_tbl_num =
4326929Smisaki 	    p_class_cfgp->mac_host_info[alt_mac].rdctbl;
4333859Sml29623 	mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr;
4343859Sml29623 
4353859Sml29623 	rs = npi_mac_hostinfo_entry(handle, OP_SET,
4366929Smisaki 	    nxgep->function_num, alt_mac, &mac_rdc);
4373859Sml29623 
4383859Sml29623 	if (rs != NPI_SUCCESS) {
4393859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4406929Smisaki 		    "failed Assign RDC table"));
4413859Sml29623 		return (NXGE_ERROR | rs);
4423859Sml29623 	}
4433859Sml29623 	return (NXGE_OK);
4443859Sml29623 }
4453859Sml29623 
4463859Sml29623 nxge_status_t
nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)4473859Sml29623 nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)
4483859Sml29623 {
4493859Sml29623 	npi_status_t rs = NPI_SUCCESS;
4503859Sml29623 	hostinfo_t mac_rdc;
4513859Sml29623 	npi_handle_t handle;
452*11878SVenu.Iyer@Sun.COM 	int i;
4533859Sml29623 
4543859Sml29623 	handle = nxgep->npi_reg_handle;
4553859Sml29623 	mac_rdc.value = 0;
4563859Sml29623 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp;
4573859Sml29623 	mac_rdc.bits.w0.mac_pref = 1;
4583859Sml29623 	switch (nxgep->function_num) {
4593859Sml29623 	case 0:
4603859Sml29623 	case 1:
461*11878SVenu.Iyer@Sun.COM 		/*
462*11878SVenu.Iyer@Sun.COM 		 * Tests indicate that it is OK not to re-initialize the
463*11878SVenu.Iyer@Sun.COM 		 * hostinfo registers for the XMAC's alternate MAC
464*11878SVenu.Iyer@Sun.COM 		 * addresses. But that is necessary for BMAC (case 2
465*11878SVenu.Iyer@Sun.COM 		 * and case 3 below)
466*11878SVenu.Iyer@Sun.COM 		 */
4673859Sml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
4686929Smisaki 		    nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
4693859Sml29623 		break;
4703859Sml29623 	case 2:
4713859Sml29623 	case 3:
4723859Sml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
4736929Smisaki 		    nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
474*11878SVenu.Iyer@Sun.COM 		for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
475*11878SVenu.Iyer@Sun.COM 			rs |= npi_mac_hostinfo_entry(handle, OP_SET,
476*11878SVenu.Iyer@Sun.COM 			    nxgep->function_num, i, &mac_rdc);
4773859Sml29623 		break;
4783859Sml29623 	default:
4793859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4806929Smisaki 		    "failed Assign RDC table (invalid function #)"));
4813859Sml29623 		return (NXGE_ERROR);
4823859Sml29623 	}
4833859Sml29623 
4843859Sml29623 	if (rs != NPI_SUCCESS) {
4853859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4866929Smisaki 		    "failed Assign RDC table"));
4873859Sml29623 		return (NXGE_ERROR | rs);
4883859Sml29623 	}
4893859Sml29623 	return (NXGE_OK);
4903859Sml29623 }
4913859Sml29623 
4923859Sml29623 /*
4933859Sml29623  * Initialize hostinfo registers for alternate MAC addresses and
4943859Sml29623  * multicast MAC address.
4953859Sml29623  */
4963859Sml29623 nxge_status_t
nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)4973859Sml29623 nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)
4983859Sml29623 {
4993859Sml29623 	npi_status_t rs = NPI_SUCCESS;
5003859Sml29623 	hostinfo_t mac_rdc;
5013859Sml29623 	npi_handle_t handle;
5023859Sml29623 
5033859Sml29623 	handle = nxgep->npi_reg_handle;
5043859Sml29623 	mac_rdc.value = 0;
5053859Sml29623 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp;
5063859Sml29623 	mac_rdc.bits.w0.mac_pref = 1;
5073859Sml29623 	switch (nxgep->function_num) {
5083859Sml29623 	case 0:
5093859Sml29623 	case 1:
5103859Sml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
511*11878SVenu.Iyer@Sun.COM 		    nxgep->function_num, XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
5123859Sml29623 		break;
5133859Sml29623 	case 2:
5143859Sml29623 	case 3:
515*11878SVenu.Iyer@Sun.COM 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
516*11878SVenu.Iyer@Sun.COM 		    nxgep->function_num, BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
5173859Sml29623 		break;
5183859Sml29623 	default:
5193859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5206929Smisaki 		    "failed Assign RDC table (invalid function #)"));
5213859Sml29623 		return (NXGE_ERROR);
5223859Sml29623 	}
5233859Sml29623 
5243859Sml29623 	if (rs != NPI_SUCCESS) {
5253859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5266929Smisaki 		    "failed Assign RDC table"));
5273859Sml29623 		return (NXGE_ERROR | rs);
5283859Sml29623 	}
5293859Sml29623 	return (NXGE_OK);
5303859Sml29623 }
5313859Sml29623 
5323859Sml29623 nxge_status_t
nxge_fflp_init_hostinfo(p_nxge_t nxgep)5333859Sml29623 nxge_fflp_init_hostinfo(p_nxge_t nxgep)
5343859Sml29623 {
5353859Sml29623 	nxge_status_t status = NXGE_OK;
5363859Sml29623 
5373859Sml29623 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
5383859Sml29623 	status |= nxge_main_mac_assign_rdc_table(nxgep);
5393859Sml29623 	return (status);
5403859Sml29623 }
5413859Sml29623 
5423859Sml29623 nxge_status_t
nxge_fflp_hw_reset(p_nxge_t nxgep)5433859Sml29623 nxge_fflp_hw_reset(p_nxge_t nxgep)
5443859Sml29623 {
5453859Sml29623 	npi_handle_t handle;
5463859Sml29623 	npi_status_t rs = NPI_SUCCESS;
5473859Sml29623 	nxge_status_t status = NXGE_OK;
5483859Sml29623 
5493859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
5503859Sml29623 
5514977Sraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
5523859Sml29623 		status = nxge_fflp_fcram_init(nxgep);
5533859Sml29623 		if (status != NXGE_OK) {
5543859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5556929Smisaki 			    " failed FCRAM init. "));
5563859Sml29623 			return (status);
5573859Sml29623 		}
5583859Sml29623 	}
5593859Sml29623 
5603859Sml29623 	status = nxge_fflp_tcam_init(nxgep);
5613859Sml29623 	if (status != NXGE_OK) {
5623859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5636929Smisaki 		    "failed TCAM init."));
5643859Sml29623 		return (status);
5653859Sml29623 	}
5663859Sml29623 
5673859Sml29623 	handle = nxgep->npi_reg_handle;
5683859Sml29623 	rs = npi_fflp_cfg_llcsnap_enable(handle);
5693859Sml29623 	if (rs != NPI_SUCCESS) {
5703859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5716929Smisaki 		    "failed LLCSNAP enable. "));
5723859Sml29623 		return (NXGE_ERROR | rs);
5733859Sml29623 	}
5743859Sml29623 
5753859Sml29623 	rs = npi_fflp_cfg_cam_errorcheck_disable(handle);
5763859Sml29623 	if (rs != NPI_SUCCESS) {
5773859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5786929Smisaki 		    "failed CAM Error Check enable. "));
5793859Sml29623 		return (NXGE_ERROR | rs);
5803859Sml29623 	}
5813859Sml29623 
5823859Sml29623 	/* init the hash generators */
5833859Sml29623 	rs = npi_fflp_cfg_hash_h1poly(handle, 0);
5843859Sml29623 	if (rs != NPI_SUCCESS) {
5853859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5866929Smisaki 		    "failed H1 Poly Init. "));
5873859Sml29623 		return (NXGE_ERROR | rs);
5883859Sml29623 	}
5893859Sml29623 
5903859Sml29623 	rs = npi_fflp_cfg_hash_h2poly(handle, 0);
5913859Sml29623 	if (rs != NPI_SUCCESS) {
5923859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5936929Smisaki 		    "failed H2 Poly Init. "));
5943859Sml29623 		return (NXGE_ERROR | rs);
5953859Sml29623 	}
5963859Sml29623 
5973859Sml29623 	/* invalidate TCAM entries */
5983859Sml29623 	status = nxge_fflp_tcam_invalidate_all(nxgep);
5993859Sml29623 	if (status != NXGE_OK) {
6003859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6016929Smisaki 		    "failed TCAM Entry Invalidate. "));
6023859Sml29623 		return (status);
6033859Sml29623 	}
6043859Sml29623 
6053859Sml29623 	/* invalidate FCRAM entries */
6064977Sraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6073859Sml29623 		status = nxge_fflp_fcram_invalidate_all(nxgep);
6083859Sml29623 		if (status != NXGE_OK) {
6093859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6106929Smisaki 			    "failed FCRAM Entry Invalidate."));
6113859Sml29623 			return (status);
6123859Sml29623 		}
6133859Sml29623 	}
6143859Sml29623 
6153859Sml29623 	/* invalidate VLAN RDC tables */
6163859Sml29623 	status = nxge_fflp_vlan_tbl_clear_all(nxgep);
6173859Sml29623 	if (status != NXGE_OK) {
6183859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6196929Smisaki 		    "failed VLAN Table Invalidate. "));
6203859Sml29623 		return (status);
6213859Sml29623 	}
6223859Sml29623 	nxgep->classifier.state |= NXGE_FFLP_HW_RESET;
6233859Sml29623 
6243859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset"));
6253859Sml29623 	return (NXGE_OK);
6263859Sml29623 }
6273859Sml29623 
6283859Sml29623 nxge_status_t
nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep,tcam_class_t l3_class,uint32_t class_config)6293859Sml29623 nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class,
6303859Sml29623 	uint32_t class_config)
6313859Sml29623 {
6323859Sml29623 	flow_key_cfg_t fcfg;
6333859Sml29623 	npi_handle_t handle;
6343859Sml29623 	npi_status_t rs = NPI_SUCCESS;
6353859Sml29623 
6363859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key"));
6373859Sml29623 	handle = nxgep->npi_reg_handle;
6383859Sml29623 	bzero(&fcfg, sizeof (flow_key_cfg_t));
6393859Sml29623 
6403859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_PROTO)
6413859Sml29623 		fcfg.use_proto = 1;
6423859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT)
6433859Sml29623 		fcfg.use_dport = 1;
6443859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT)
6453859Sml29623 		fcfg.use_sport = 1;
6463859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_IPDST)
6473859Sml29623 		fcfg.use_daddr = 1;
6483859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_IPSRC)
6493859Sml29623 		fcfg.use_saddr = 1;
6503859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_VLAN)
6513859Sml29623 		fcfg.use_vlan = 1;
6523859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_L2DA)
6533859Sml29623 		fcfg.use_l2da = 1;
6543859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM)
6553859Sml29623 		fcfg.use_portnum = 1;
6563859Sml29623 	fcfg.ip_opts_exist = 0;
6573859Sml29623 
6583859Sml29623 	rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg);
6593859Sml29623 	if (rs & NPI_FFLP_ERROR) {
6603859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
6616929Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
6623859Sml29623 		return (NXGE_ERROR | rs);
6633859Sml29623 	}
6643859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key"));
6653859Sml29623 	return (NXGE_OK);
6663859Sml29623 }
6673859Sml29623 
6683859Sml29623 nxge_status_t
nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep,tcam_class_t l3_class,uint32_t * class_config)6693859Sml29623 nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class,
6703859Sml29623 	uint32_t *class_config)
6713859Sml29623 {
6723859Sml29623 	flow_key_cfg_t fcfg;
6733859Sml29623 	npi_handle_t handle;
6743859Sml29623 	npi_status_t rs = NPI_SUCCESS;
6753859Sml29623 	uint32_t ccfg = 0;
6763859Sml29623 
6773859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get"));
6783859Sml29623 	handle = nxgep->npi_reg_handle;
6793859Sml29623 	bzero(&fcfg, sizeof (flow_key_cfg_t));
6803859Sml29623 
6813859Sml29623 	rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg);
6823859Sml29623 	if (rs & NPI_FFLP_ERROR) {
6833859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
6846929Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
6853859Sml29623 		return (NXGE_ERROR | rs);
6863859Sml29623 	}
6873859Sml29623 
6883859Sml29623 	if (fcfg.use_proto)
6893859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_PROTO;
6903859Sml29623 	if (fcfg.use_dport)
6913859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT;
6923859Sml29623 	if (fcfg.use_sport)
6933859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT;
6943859Sml29623 	if (fcfg.use_daddr)
6953859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_IPDST;
6963859Sml29623 	if (fcfg.use_saddr)
6973859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_IPSRC;
6983859Sml29623 	if (fcfg.use_vlan)
6993859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_VLAN;
7003859Sml29623 	if (fcfg.use_l2da)
7013859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_L2DA;
7023859Sml29623 	if (fcfg.use_portnum)
7033859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM;
7043859Sml29623 
7053859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7066929Smisaki 	    " nxge_cfg_ip_cls_flow_key_get %x", ccfg));
7073859Sml29623 	*class_config = ccfg;
7083859Sml29623 
7093859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7106929Smisaki 	    " <== nxge_cfg_ip_cls_flow_key_get"));
7113859Sml29623 	return (NXGE_OK);
7123859Sml29623 }
7133859Sml29623 
7143859Sml29623 static nxge_status_t
nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep,tcam_class_t class,uint32_t * class_config)7153859Sml29623 nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class,
7163859Sml29623 	uint32_t *class_config)
7173859Sml29623 {
7183859Sml29623 	npi_status_t rs = NPI_SUCCESS;
7193859Sml29623 	tcam_key_cfg_t cfg;
7203859Sml29623 	npi_handle_t handle;
7213859Sml29623 	uint32_t ccfg = 0;
7223859Sml29623 
7233859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
7243859Sml29623 
7253859Sml29623 	bzero(&cfg, sizeof (tcam_key_cfg_t));
7263859Sml29623 	handle = nxgep->npi_reg_handle;
7273859Sml29623 
7283859Sml29623 	rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg);
7293859Sml29623 	if (rs & NPI_FFLP_ERROR) {
7303859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
7316929Smisaki 		    " opt %x for class %d failed ", class_config, class));
7323859Sml29623 		return (NXGE_ERROR | rs);
7333859Sml29623 	}
7343859Sml29623 	if (cfg.discard)
7353859Sml29623 		ccfg |= NXGE_CLASS_DISCARD;
7363859Sml29623 	if (cfg.lookup_enable)
7373859Sml29623 		ccfg |= NXGE_CLASS_TCAM_LOOKUP;
7383859Sml29623 	if (cfg.use_ip_daddr)
7393859Sml29623 		ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR;
7403859Sml29623 	*class_config = ccfg;
7413859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7426929Smisaki 	    " ==> nxge_cfg_tcam_ip_class %x", ccfg));
7433859Sml29623 	return (NXGE_OK);
7443859Sml29623 }
7453859Sml29623 
7463859Sml29623 static nxge_status_t
nxge_cfg_tcam_ip_class(p_nxge_t nxgep,tcam_class_t class,uint32_t class_config)7473859Sml29623 nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class,
7483859Sml29623 	uint32_t class_config)
7493859Sml29623 {
7503859Sml29623 	npi_status_t rs = NPI_SUCCESS;
7513859Sml29623 	tcam_key_cfg_t cfg;
7523859Sml29623 	npi_handle_t handle;
7533859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
7543859Sml29623 
7553859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
7563859Sml29623 
7573859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7583859Sml29623 	p_class_cfgp->class_cfg[class] = class_config;
7593859Sml29623 
7603859Sml29623 	bzero(&cfg, sizeof (tcam_key_cfg_t));
7613859Sml29623 	handle = nxgep->npi_reg_handle;
7623859Sml29623 	cfg.discard = 0;
7633859Sml29623 	cfg.lookup_enable = 0;
7643859Sml29623 	cfg.use_ip_daddr = 0;
7653859Sml29623 	if (class_config & NXGE_CLASS_DISCARD)
7663859Sml29623 		cfg.discard = 1;
7673859Sml29623 	if (class_config & NXGE_CLASS_TCAM_LOOKUP)
7683859Sml29623 		cfg.lookup_enable = 1;
7693859Sml29623 	if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR)
7703859Sml29623 		cfg.use_ip_daddr = 1;
7713859Sml29623 
7723859Sml29623 	rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg);
7733859Sml29623 	if (rs & NPI_FFLP_ERROR) {
7743859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
7756929Smisaki 		    " opt %x for class %d failed ", class_config, class));
7763859Sml29623 		return (NXGE_ERROR | rs);
7773859Sml29623 	}
7783859Sml29623 	return (NXGE_OK);
7793859Sml29623 }
7803859Sml29623 
7813859Sml29623 nxge_status_t
nxge_fflp_set_hash1(p_nxge_t nxgep,uint32_t h1)7823859Sml29623 nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1)
7833859Sml29623 {
7843859Sml29623 	npi_status_t rs = NPI_SUCCESS;
7853859Sml29623 	npi_handle_t handle;
7863859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
7873859Sml29623 
7883859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1"));
7893859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7903859Sml29623 	p_class_cfgp->init_h1 = h1;
7913859Sml29623 	handle = nxgep->npi_reg_handle;
7923859Sml29623 	rs = npi_fflp_cfg_hash_h1poly(handle, h1);
7933859Sml29623 	if (rs & NPI_FFLP_ERROR) {
7943859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
7956929Smisaki 		    " nxge_fflp_init_h1 %x failed ", h1));
7963859Sml29623 		return (NXGE_ERROR | rs);
7973859Sml29623 	}
7983859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1"));
7993859Sml29623 	return (NXGE_OK);
8003859Sml29623 }
8013859Sml29623 
8023859Sml29623 nxge_status_t
nxge_fflp_set_hash2(p_nxge_t nxgep,uint16_t h2)8033859Sml29623 nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2)
8043859Sml29623 {
8053859Sml29623 	npi_status_t rs = NPI_SUCCESS;
8063859Sml29623 	npi_handle_t handle;
8073859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
8083859Sml29623 
8093859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2"));
8103859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
8113859Sml29623 	p_class_cfgp->init_h2 = h2;
8123859Sml29623 
8133859Sml29623 	handle = nxgep->npi_reg_handle;
8143859Sml29623 	rs = npi_fflp_cfg_hash_h2poly(handle, h2);
8153859Sml29623 	if (rs & NPI_FFLP_ERROR) {
8163859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8176929Smisaki 		    " nxge_fflp_init_h2 %x failed ", h2));
8183859Sml29623 		return (NXGE_ERROR | rs);
8193859Sml29623 	}
8203859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2"));
8213859Sml29623 	return (NXGE_OK);
8223859Sml29623 }
8233859Sml29623 
8243859Sml29623 nxge_status_t
nxge_classify_init_sw(p_nxge_t nxgep)8253859Sml29623 nxge_classify_init_sw(p_nxge_t nxgep)
8263859Sml29623 {
8273859Sml29623 	nxge_classify_t *classify_ptr;
8283859Sml29623 
8293859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw"));
8303859Sml29623 	classify_ptr = &nxgep->classifier;
8313859Sml29623 
8323859Sml29623 	if (classify_ptr->state & NXGE_FFLP_SW_INIT) {
8333859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
8346929Smisaki 		    "nxge_classify_init_sw already init"));
8353859Sml29623 		return (NXGE_OK);
8363859Sml29623 	}
83711304SJanie.Lu@Sun.COM 
83811304SJanie.Lu@Sun.COM 	classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports;
83911304SJanie.Lu@Sun.COM 	classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam;
84011304SJanie.Lu@Sun.COM 	classify_ptr->tcam_top = nxgep->function_num;
8413859Sml29623 
8423859Sml29623 	/* Init defaults */
8433859Sml29623 	/*
8443859Sml29623 	 * add hacks required for HW shortcomings for example, code to handle
8453859Sml29623 	 * fragmented packets
8463859Sml29623 	 */
8473859Sml29623 	nxge_init_h1_table();
8483859Sml29623 	nxge_crc_ccitt_init();
8493859Sml29623 	nxgep->classifier.tcam_location = nxgep->function_num;
8503859Sml29623 	nxgep->classifier.fragment_bug = 1;
8513859Sml29623 	classify_ptr->state |= NXGE_FFLP_SW_INIT;
8523859Sml29623 
8533859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw"));
8543859Sml29623 	return (NXGE_OK);
8553859Sml29623 }
8563859Sml29623 
8573859Sml29623 nxge_status_t
nxge_classify_exit_sw(p_nxge_t nxgep)8583859Sml29623 nxge_classify_exit_sw(p_nxge_t nxgep)
8593859Sml29623 {
8603859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw"));
8613859Sml29623 	nxgep->classifier.state = NULL;
8623859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw"));
8633859Sml29623 	return (NXGE_OK);
8643859Sml29623 }
8653859Sml29623 
8663859Sml29623 /*
8673859Sml29623  * Figures out the RDC Group for the entry
8683859Sml29623  *
8693859Sml29623  * The current implementation is just a place holder and it
8703859Sml29623  * returns 0.
8713859Sml29623  * The real location determining algorithm would consider
8723859Sml29623  * the partition etc ... before deciding w
8733859Sml29623  *
8743859Sml29623  */
8753859Sml29623 
8763859Sml29623 /* ARGSUSED */
8773859Sml29623 static uint8_t
nxge_get_rdc_group(p_nxge_t nxgep,uint8_t class,uint64_t cookie)87811304SJanie.Lu@Sun.COM nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
8793859Sml29623 {
8803859Sml29623 	int use_port_rdc_grp = 0;
8813859Sml29623 	uint8_t rdc_grp = 0;
8823859Sml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
8833859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
8843859Sml29623 	p_nxge_rdc_grp_t rdc_grp_p;
8853859Sml29623 
8863859Sml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
8873859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
8883859Sml29623 	rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp];
8896495Sspeer 	rdc_grp = p_cfgp->def_mac_rxdma_grpid;
8903859Sml29623 
8913859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8926929Smisaki 	    "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
8936929Smisaki 	    cookie, rdc_grp, rdc_grp_p));
8943859Sml29623 	return (rdc_grp);
8953859Sml29623 }
8963859Sml29623 
8973859Sml29623 /* ARGSUSED */
8983859Sml29623 static uint8_t
nxge_get_rdc_offset(p_nxge_t nxgep,uint8_t class,uint64_t cookie)89911304SJanie.Lu@Sun.COM nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
9003859Sml29623 {
9013859Sml29623 	return ((uint8_t)cookie);
9023859Sml29623 }
9033859Sml29623 
9043859Sml29623 /* ARGSUSED */
9053859Sml29623 static void
nxge_fill_tcam_entry_udp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9063859Sml29623 nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9073859Sml29623 	tcam_entry_t *tcam_ptr)
9083859Sml29623 {
9093859Sml29623 	udpip4_spec_t *fspec_key;
9103859Sml29623 	udpip4_spec_t *fspec_mask;
9113859Sml29623 
9123859Sml29623 	fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec;
9133859Sml29623 	fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec;
9143859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
9153859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
9163859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
9173859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
9183859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
9196929Smisaki 	    fspec_key->pdst, fspec_key->psrc);
9203859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
9216929Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
9223859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
9236929Smisaki 	    tcam_ptr->ip4_class_mask,
9246929Smisaki 	    TCAM_CLASS_UDP_IPV4);
9253859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
9266929Smisaki 	    tcam_ptr->ip4_proto_mask,
9276929Smisaki 	    IPPROTO_UDP);
92811304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_tos_key = fspec_key->tos;
92911304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
9303859Sml29623 }
9313859Sml29623 
9323859Sml29623 static void
nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9333859Sml29623 nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
9343859Sml29623 	tcam_entry_t *tcam_ptr)
9353859Sml29623 {
9363859Sml29623 	udpip6_spec_t *fspec_key;
9373859Sml29623 	udpip6_spec_t *fspec_mask;
9383859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
9393859Sml29623 
9403859Sml29623 	fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec;
9413859Sml29623 	fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec;
9423859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
9433859Sml29623 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
9446929Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
9453859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
9463859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
9473859Sml29623 	} else {
9483859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
9493859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
9503859Sml29623 	}
9513859Sml29623 
9523859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
9536929Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6);
9543859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
9556929Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP);
9563859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
9576929Smisaki 	    fspec_key->pdst, fspec_key->psrc);
9583859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
9596929Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
96011304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_tos_key = fspec_key->tos;
96111304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
9623859Sml29623 }
9633859Sml29623 
9643859Sml29623 /* ARGSUSED */
9653859Sml29623 static void
nxge_fill_tcam_entry_tcp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9663859Sml29623 nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9673859Sml29623 	tcam_entry_t *tcam_ptr)
9683859Sml29623 {
9693859Sml29623 	tcpip4_spec_t *fspec_key;
9703859Sml29623 	tcpip4_spec_t *fspec_mask;
9713859Sml29623 
9723859Sml29623 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
9733859Sml29623 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
9743859Sml29623 
9753859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
9763859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
9773859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
9783859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
9793859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
9806929Smisaki 	    fspec_key->pdst, fspec_key->psrc);
9813859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
9826929Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
9833859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
9846929Smisaki 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4);
9853859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
9866929Smisaki 	    tcam_ptr->ip4_proto_mask, IPPROTO_TCP);
98711304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_tos_key = fspec_key->tos;
98811304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
9893859Sml29623 }
9903859Sml29623 
9913859Sml29623 /* ARGSUSED */
9923859Sml29623 static void
nxge_fill_tcam_entry_sctp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9933859Sml29623 nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9943859Sml29623 	tcam_entry_t *tcam_ptr)
9953859Sml29623 {
9963859Sml29623 	tcpip4_spec_t *fspec_key;
9973859Sml29623 	tcpip4_spec_t *fspec_mask;
9983859Sml29623 
9993859Sml29623 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
10003859Sml29623 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
10013859Sml29623 
10023859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
10033859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
10043859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
10053859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
10063859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
10076929Smisaki 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4);
10083859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
10096929Smisaki 	    tcam_ptr->ip4_proto_mask, IPPROTO_SCTP);
10103859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
10116929Smisaki 	    fspec_key->pdst, fspec_key->psrc);
10123859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
10136929Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
101411304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_tos_key = fspec_key->tos;
101511304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
10163859Sml29623 }
10173859Sml29623 
10183859Sml29623 static void
nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)10193859Sml29623 nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
10203859Sml29623 	tcam_entry_t *tcam_ptr)
10213859Sml29623 {
10223859Sml29623 	tcpip6_spec_t *fspec_key;
10233859Sml29623 	tcpip6_spec_t *fspec_mask;
10243859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
10253859Sml29623 
10263859Sml29623 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10273859Sml29623 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10283859Sml29623 
10293859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10303859Sml29623 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
10316929Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
10323859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
10333859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
10343859Sml29623 	} else {
10353859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
10363859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
10373859Sml29623 	}
10383859Sml29623 
10393859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
10406929Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6);
10413859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
10426929Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP);
10433859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
10446929Smisaki 	    fspec_key->pdst, fspec_key->psrc);
10453859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
10466929Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
104711304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_tos_key = fspec_key->tos;
104811304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
10493859Sml29623 }
10503859Sml29623 
10513859Sml29623 static void
nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)10523859Sml29623 nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
10533859Sml29623 	tcam_entry_t *tcam_ptr)
10543859Sml29623 {
10553859Sml29623 	tcpip6_spec_t *fspec_key;
10563859Sml29623 	tcpip6_spec_t *fspec_mask;
10573859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
10583859Sml29623 
10593859Sml29623 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10603859Sml29623 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10613859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10623859Sml29623 
10633859Sml29623 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
10646929Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
10653859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
10663859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
10673859Sml29623 	} else {
10683859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
10693859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
10703859Sml29623 	}
10713859Sml29623 
10723859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
10736929Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6);
10743859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
10756929Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP);
10763859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
10776929Smisaki 	    fspec_key->pdst, fspec_key->psrc);
10783859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
10796929Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
108011304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_tos_key = fspec_key->tos;
108111304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
10823859Sml29623 }
10833859Sml29623 
108411304SJanie.Lu@Sun.COM /* ARGSUSED */
108511304SJanie.Lu@Sun.COM static void
nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)108611304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec,
108711304SJanie.Lu@Sun.COM 	tcam_entry_t *tcam_ptr)
108811304SJanie.Lu@Sun.COM {
108911304SJanie.Lu@Sun.COM 	ahip4_spec_t *fspec_key;
109011304SJanie.Lu@Sun.COM 	ahip4_spec_t *fspec_mask;
109111304SJanie.Lu@Sun.COM 
109211304SJanie.Lu@Sun.COM 	fspec_key = (ahip4_spec_t *)&flow_spec->uh.ahip4spec;
109311304SJanie.Lu@Sun.COM 	fspec_mask = (ahip4_spec_t *)&flow_spec->um.ahip4spec;
109411304SJanie.Lu@Sun.COM 
109511304SJanie.Lu@Sun.COM 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
109611304SJanie.Lu@Sun.COM 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
109711304SJanie.Lu@Sun.COM 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
109811304SJanie.Lu@Sun.COM 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
109911304SJanie.Lu@Sun.COM 
110011304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_port_key = fspec_key->spi;
110111304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_port_mask = fspec_mask->spi;
110211304SJanie.Lu@Sun.COM 
110311304SJanie.Lu@Sun.COM 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
110411304SJanie.Lu@Sun.COM 	    tcam_ptr->ip4_class_mask,
110511304SJanie.Lu@Sun.COM 	    TCAM_CLASS_AH_ESP_IPV4);
110611304SJanie.Lu@Sun.COM 
110711304SJanie.Lu@Sun.COM 	if (flow_spec->flow_type == FSPEC_AHIP4) {
110811304SJanie.Lu@Sun.COM 		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
110911304SJanie.Lu@Sun.COM 		    tcam_ptr->ip4_proto_mask, IPPROTO_AH);
111011304SJanie.Lu@Sun.COM 	} else {
111111304SJanie.Lu@Sun.COM 		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
111211304SJanie.Lu@Sun.COM 		    tcam_ptr->ip4_proto_mask, IPPROTO_ESP);
111311304SJanie.Lu@Sun.COM 	}
111411304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_tos_key = fspec_key->tos;
111511304SJanie.Lu@Sun.COM 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
111611304SJanie.Lu@Sun.COM }
111711304SJanie.Lu@Sun.COM 
111811304SJanie.Lu@Sun.COM static void
nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)111911304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
112011304SJanie.Lu@Sun.COM 	tcam_entry_t *tcam_ptr)
112111304SJanie.Lu@Sun.COM {
112211304SJanie.Lu@Sun.COM 	ahip6_spec_t *fspec_key;
112311304SJanie.Lu@Sun.COM 	ahip6_spec_t *fspec_mask;
112411304SJanie.Lu@Sun.COM 	p_nxge_class_pt_cfg_t p_class_cfgp;
112511304SJanie.Lu@Sun.COM 
112611304SJanie.Lu@Sun.COM 	fspec_key = (ahip6_spec_t *)&flow_spec->uh.ahip6spec;
112711304SJanie.Lu@Sun.COM 	fspec_mask = (ahip6_spec_t *)&flow_spec->um.ahip6spec;
112811304SJanie.Lu@Sun.COM 
112911304SJanie.Lu@Sun.COM 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
113011304SJanie.Lu@Sun.COM 	if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] &
113111304SJanie.Lu@Sun.COM 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
113211304SJanie.Lu@Sun.COM 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
113311304SJanie.Lu@Sun.COM 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
113411304SJanie.Lu@Sun.COM 	} else {
113511304SJanie.Lu@Sun.COM 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
113611304SJanie.Lu@Sun.COM 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
113711304SJanie.Lu@Sun.COM 	}
113811304SJanie.Lu@Sun.COM 
113911304SJanie.Lu@Sun.COM 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
114011304SJanie.Lu@Sun.COM 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6);
114111304SJanie.Lu@Sun.COM 
114211304SJanie.Lu@Sun.COM 	if (flow_spec->flow_type == FSPEC_AHIP6) {
114311304SJanie.Lu@Sun.COM 		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
114411304SJanie.Lu@Sun.COM 		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH);
114511304SJanie.Lu@Sun.COM 	} else {
114611304SJanie.Lu@Sun.COM 		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
114711304SJanie.Lu@Sun.COM 		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP);
114811304SJanie.Lu@Sun.COM 	}
114911304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_port_key = fspec_key->spi;
115011304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_port_mask = fspec_mask->spi;
115111304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_tos_key = fspec_key->tos;
115211304SJanie.Lu@Sun.COM 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
115311304SJanie.Lu@Sun.COM }
115411304SJanie.Lu@Sun.COM 
115511304SJanie.Lu@Sun.COM /* ARGSUSED */
115611304SJanie.Lu@Sun.COM static void
nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr,tcam_class_t class)115711304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec,
115811304SJanie.Lu@Sun.COM 	tcam_entry_t *tcam_ptr, tcam_class_t class)
115911304SJanie.Lu@Sun.COM {
116011304SJanie.Lu@Sun.COM 	ip_user_spec_t *fspec_key;
116111304SJanie.Lu@Sun.COM 	ip_user_spec_t *fspec_mask;
116211304SJanie.Lu@Sun.COM 
116311304SJanie.Lu@Sun.COM 	fspec_key = (ip_user_spec_t *)&flow_spec->uh.ip_usr_spec;
116411304SJanie.Lu@Sun.COM 	fspec_mask = (ip_user_spec_t *)&flow_spec->um.ip_usr_spec;
116511304SJanie.Lu@Sun.COM 
116611304SJanie.Lu@Sun.COM 	if (fspec_key->ip_ver == FSPEC_IP4) {
116711304SJanie.Lu@Sun.COM 		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
116811304SJanie.Lu@Sun.COM 		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
116911304SJanie.Lu@Sun.COM 		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
117011304SJanie.Lu@Sun.COM 		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
117111304SJanie.Lu@Sun.COM 
117211304SJanie.Lu@Sun.COM 		tcam_ptr->ip4_port_key = fspec_key->l4_4_bytes;
117311304SJanie.Lu@Sun.COM 		tcam_ptr->ip4_port_mask = fspec_mask->l4_4_bytes;
117411304SJanie.Lu@Sun.COM 
117511304SJanie.Lu@Sun.COM 		TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
117611304SJanie.Lu@Sun.COM 		    tcam_ptr->ip4_class_mask, class);
117711304SJanie.Lu@Sun.COM 
117811304SJanie.Lu@Sun.COM 		tcam_ptr->ip4_proto_key = fspec_key->proto;
117911304SJanie.Lu@Sun.COM 		tcam_ptr->ip4_proto_mask = fspec_mask->proto;
118011304SJanie.Lu@Sun.COM 
118111304SJanie.Lu@Sun.COM 		tcam_ptr->ip4_tos_key = fspec_key->tos;
118211304SJanie.Lu@Sun.COM 		tcam_ptr->ip4_tos_mask = fspec_mask->tos;
118311304SJanie.Lu@Sun.COM 	}
118411304SJanie.Lu@Sun.COM }
118511304SJanie.Lu@Sun.COM 
118611304SJanie.Lu@Sun.COM 
11873859Sml29623 nxge_status_t
nxge_flow_get_hash(p_nxge_t nxgep,flow_resource_t * flow_res,uint32_t * H1,uint16_t * H2)11883859Sml29623 nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res,
11893859Sml29623 	uint32_t *H1, uint16_t *H2)
11903859Sml29623 {
11913859Sml29623 	flow_spec_t *flow_spec;
11923859Sml29623 	uint32_t class_cfg;
11933859Sml29623 	flow_template_t ft;
11943859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
11953859Sml29623 
11963859Sml29623 	int ft_size = sizeof (flow_template_t);
11973859Sml29623 
11983859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash"));
11993859Sml29623 
12003859Sml29623 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
12013859Sml29623 	bzero((char *)&ft, ft_size);
12023859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
12033859Sml29623 
12043859Sml29623 	switch (flow_spec->flow_type) {
12053859Sml29623 	case FSPEC_TCPIP4:
12063859Sml29623 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4];
12073859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
12083859Sml29623 			ft.ip_proto = IPPROTO_TCP;
12093859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
12103859Sml29623 			ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src;
12113859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
12123859Sml29623 			ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst;
12133859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
12143859Sml29623 			ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc;
12153859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
12163859Sml29623 			ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst;
12173859Sml29623 		break;
12183859Sml29623 
12193859Sml29623 	case FSPEC_UDPIP4:
12203859Sml29623 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4];
12213859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
12223859Sml29623 			ft.ip_proto = IPPROTO_UDP;
12233859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
12243859Sml29623 			ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src;
12253859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
12263859Sml29623 			ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst;
12273859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
12283859Sml29623 			ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc;
12293859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
12303859Sml29623 			ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst;
12313859Sml29623 		break;
12323859Sml29623 
12333859Sml29623 	default:
12343859Sml29623 		return (NXGE_ERROR);
12353859Sml29623 	}
12363859Sml29623 
12373859Sml29623 	*H1 = nxge_compute_h1(p_class_cfgp->init_h1,
12386929Smisaki 	    (uint32_t *)&ft, ft_size) & 0xfffff;
12393859Sml29623 	*H2 = nxge_compute_h2(p_class_cfgp->init_h2,
12406929Smisaki 	    (uint8_t *)&ft, ft_size);
12413859Sml29623 
12423859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash"));
12433859Sml29623 	return (NXGE_OK);
12443859Sml29623 }
12453859Sml29623 
12463859Sml29623 nxge_status_t
nxge_add_fcram_entry(p_nxge_t nxgep,flow_resource_t * flow_res)12473859Sml29623 nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
12483859Sml29623 {
12493859Sml29623 	uint32_t H1;
12503859Sml29623 	uint16_t H2;
12513859Sml29623 	nxge_status_t status = NXGE_OK;
12523859Sml29623 
12533859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry"));
12543859Sml29623 	status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2);
12553859Sml29623 	if (status != NXGE_OK) {
12563859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
12576929Smisaki 		    " nxge_add_fcram_entry failed "));
12583859Sml29623 		return (status);
12593859Sml29623 	}
12603859Sml29623 
12613859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry"));
12623859Sml29623 	return (NXGE_OK);
12633859Sml29623 }
12643859Sml29623 
12653859Sml29623 /*
12663859Sml29623  * Already decided this flow goes into the tcam
12673859Sml29623  */
12683859Sml29623 
12693859Sml29623 nxge_status_t
nxge_add_tcam_entry(p_nxge_t nxgep,flow_resource_t * flow_res)12703859Sml29623 nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
12713859Sml29623 {
12723859Sml29623 	npi_handle_t handle;
127311304SJanie.Lu@Sun.COM 	uint64_t channel_cookie;
127411304SJanie.Lu@Sun.COM 	uint64_t flow_cookie;
12753859Sml29623 	flow_spec_t *flow_spec;
12763859Sml29623 	npi_status_t rs = NPI_SUCCESS;
12773859Sml29623 	tcam_entry_t tcam_ptr;
127811304SJanie.Lu@Sun.COM 	tcam_location_t location;
12793859Sml29623 	uint8_t offset, rdc_grp;
12803859Sml29623 	p_nxge_hw_list_t hw_p;
128111304SJanie.Lu@Sun.COM 	uint64_t class;
12823859Sml29623 
12833859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry"));
12843859Sml29623 	handle = nxgep->npi_reg_handle;
12853859Sml29623 
12863859Sml29623 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
12873859Sml29623 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
12883859Sml29623 	flow_cookie = flow_res->flow_cookie;
12893859Sml29623 	channel_cookie = flow_res->channel_cookie;
129011304SJanie.Lu@Sun.COM 	location = (tcam_location_t)nxge_tcam_get_index(nxgep,
129111304SJanie.Lu@Sun.COM 	    (uint16_t)flow_res->location);
129211304SJanie.Lu@Sun.COM 
129311304SJanie.Lu@Sun.COM 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
129411304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
129511304SJanie.Lu@Sun.COM 		    " nxge_add_tcam_entry: common hardware not set",
129611304SJanie.Lu@Sun.COM 		    nxgep->niu_type));
129711304SJanie.Lu@Sun.COM 		return (NXGE_ERROR);
129811304SJanie.Lu@Sun.COM 	}
129911304SJanie.Lu@Sun.COM 
130011304SJanie.Lu@Sun.COM 	if (flow_spec->flow_type == FSPEC_IP_USR) {
130111304SJanie.Lu@Sun.COM 		int i;
130211304SJanie.Lu@Sun.COM 		int add_usr_cls = 0;
130311304SJanie.Lu@Sun.COM 		int ipv6 = 0;
130411304SJanie.Lu@Sun.COM 		ip_user_spec_t *uspec = &flow_spec->uh.ip_usr_spec;
130511304SJanie.Lu@Sun.COM 		ip_user_spec_t *umask = &flow_spec->um.ip_usr_spec;
130611304SJanie.Lu@Sun.COM 		nxge_usr_l3_cls_t *l3_ucls_p;
130711304SJanie.Lu@Sun.COM 
130811304SJanie.Lu@Sun.COM 		MUTEX_ENTER(&hw_p->nxge_tcam_lock);
130911304SJanie.Lu@Sun.COM 
131011304SJanie.Lu@Sun.COM 		for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
131111304SJanie.Lu@Sun.COM 			l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
131211304SJanie.Lu@Sun.COM 			if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) {
131311304SJanie.Lu@Sun.COM 				if (uspec->proto == l3_ucls_p->pid) {
131411304SJanie.Lu@Sun.COM 					class = l3_ucls_p->cls;
131511304SJanie.Lu@Sun.COM 					l3_ucls_p->tcam_ref_cnt++;
131611304SJanie.Lu@Sun.COM 					add_usr_cls = 1;
131711304SJanie.Lu@Sun.COM 					break;
131811304SJanie.Lu@Sun.COM 				}
131911304SJanie.Lu@Sun.COM 			} else if (l3_ucls_p->valid == 0) {
132011304SJanie.Lu@Sun.COM 				/* Program new user IP class */
132111304SJanie.Lu@Sun.COM 				switch (i) {
132211304SJanie.Lu@Sun.COM 				case 0:
132311304SJanie.Lu@Sun.COM 					class = TCAM_CLASS_IP_USER_4;
132411304SJanie.Lu@Sun.COM 					break;
132511304SJanie.Lu@Sun.COM 				case 1:
132611304SJanie.Lu@Sun.COM 					class = TCAM_CLASS_IP_USER_5;
132711304SJanie.Lu@Sun.COM 					break;
132811304SJanie.Lu@Sun.COM 				case 2:
132911304SJanie.Lu@Sun.COM 					class = TCAM_CLASS_IP_USER_6;
133011304SJanie.Lu@Sun.COM 					break;
133111304SJanie.Lu@Sun.COM 				case 3:
133211304SJanie.Lu@Sun.COM 					class = TCAM_CLASS_IP_USER_7;
133311304SJanie.Lu@Sun.COM 					break;
133411304SJanie.Lu@Sun.COM 				default:
133511304SJanie.Lu@Sun.COM 					break;
133611304SJanie.Lu@Sun.COM 				}
133711304SJanie.Lu@Sun.COM 				if (uspec->ip_ver == FSPEC_IP6)
133811304SJanie.Lu@Sun.COM 					ipv6 = 1;
133911304SJanie.Lu@Sun.COM 				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
134011304SJanie.Lu@Sun.COM 				    (tcam_class_t)class, uspec->tos,
134111304SJanie.Lu@Sun.COM 				    umask->tos, uspec->proto, ipv6);
134211304SJanie.Lu@Sun.COM 				if (rs != NPI_SUCCESS)
134311304SJanie.Lu@Sun.COM 					goto fail;
134411304SJanie.Lu@Sun.COM 
134511304SJanie.Lu@Sun.COM 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
134611304SJanie.Lu@Sun.COM 				    (tcam_class_t)class);
134711304SJanie.Lu@Sun.COM 				if (rs != NPI_SUCCESS)
134811304SJanie.Lu@Sun.COM 					goto fail;
134911304SJanie.Lu@Sun.COM 
135011304SJanie.Lu@Sun.COM 				l3_ucls_p->cls = class;
135111304SJanie.Lu@Sun.COM 				l3_ucls_p->pid = uspec->proto;
135211304SJanie.Lu@Sun.COM 				l3_ucls_p->tcam_ref_cnt++;
135311304SJanie.Lu@Sun.COM 				l3_ucls_p->valid = 1;
135411304SJanie.Lu@Sun.COM 				add_usr_cls = 1;
135511304SJanie.Lu@Sun.COM 				break;
135611304SJanie.Lu@Sun.COM 			} else if (l3_ucls_p->tcam_ref_cnt == 0 &&
135711304SJanie.Lu@Sun.COM 			    uspec->proto == l3_ucls_p->pid) {
135811304SJanie.Lu@Sun.COM 				/*
135911304SJanie.Lu@Sun.COM 				 * The class has already been programmed,
136011304SJanie.Lu@Sun.COM 				 * probably for flow hash
136111304SJanie.Lu@Sun.COM 				 */
136211304SJanie.Lu@Sun.COM 				class = l3_ucls_p->cls;
136311304SJanie.Lu@Sun.COM 				if (uspec->ip_ver == FSPEC_IP6)
136411304SJanie.Lu@Sun.COM 					ipv6 = 1;
136511304SJanie.Lu@Sun.COM 				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
136611304SJanie.Lu@Sun.COM 				    (tcam_class_t)class, uspec->tos,
136711304SJanie.Lu@Sun.COM 				    umask->tos, uspec->proto, ipv6);
136811304SJanie.Lu@Sun.COM 				if (rs != NPI_SUCCESS)
136911304SJanie.Lu@Sun.COM 					goto fail;
137011304SJanie.Lu@Sun.COM 
137111304SJanie.Lu@Sun.COM 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
137211304SJanie.Lu@Sun.COM 				    (tcam_class_t)class);
137311304SJanie.Lu@Sun.COM 				if (rs != NPI_SUCCESS)
137411304SJanie.Lu@Sun.COM 					goto fail;
137511304SJanie.Lu@Sun.COM 
137611304SJanie.Lu@Sun.COM 				l3_ucls_p->pid = uspec->proto;
137711304SJanie.Lu@Sun.COM 				l3_ucls_p->tcam_ref_cnt++;
137811304SJanie.Lu@Sun.COM 				add_usr_cls = 1;
137911304SJanie.Lu@Sun.COM 				break;
138011304SJanie.Lu@Sun.COM 			}
138111304SJanie.Lu@Sun.COM 		}
138211304SJanie.Lu@Sun.COM 		if (!add_usr_cls) {
138311304SJanie.Lu@Sun.COM 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
138411304SJanie.Lu@Sun.COM 			    "nxge_add_tcam_entry: Could not find/insert class"
138511304SJanie.Lu@Sun.COM 			    "for pid %d", uspec->proto));
138611304SJanie.Lu@Sun.COM 			goto fail;
138711304SJanie.Lu@Sun.COM 		}
138811304SJanie.Lu@Sun.COM 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
138911304SJanie.Lu@Sun.COM 	}
13903859Sml29623 
13913859Sml29623 	switch (flow_spec->flow_type) {
13923859Sml29623 	case FSPEC_TCPIP4:
13933859Sml29623 		nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr);
13943859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4,
13956929Smisaki 		    flow_cookie);
13963859Sml29623 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4,
13976929Smisaki 		    channel_cookie);
13983859Sml29623 		break;
13993859Sml29623 
14003859Sml29623 	case FSPEC_UDPIP4:
14013859Sml29623 		nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr);
14023859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
14036929Smisaki 		    TCAM_CLASS_UDP_IPV4,
14046929Smisaki 		    flow_cookie);
14053859Sml29623 		offset = nxge_get_rdc_offset(nxgep,
14066929Smisaki 		    TCAM_CLASS_UDP_IPV4,
14076929Smisaki 		    channel_cookie);
14083859Sml29623 		break;
14093859Sml29623 
14103859Sml29623 	case FSPEC_TCPIP6:
14113859Sml29623 		nxge_fill_tcam_entry_tcp_ipv6(nxgep,
14126929Smisaki 		    flow_spec, &tcam_ptr);
14133859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6,
14146929Smisaki 		    flow_cookie);
14153859Sml29623 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6,
14166929Smisaki 		    channel_cookie);
14173859Sml29623 		break;
14183859Sml29623 
14193859Sml29623 	case FSPEC_UDPIP6:
14203859Sml29623 		nxge_fill_tcam_entry_udp_ipv6(nxgep,
14216929Smisaki 		    flow_spec, &tcam_ptr);
14223859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
14236929Smisaki 		    TCAM_CLASS_UDP_IPV6,
142411304SJanie.Lu@Sun.COM 		    flow_cookie);
14253859Sml29623 		offset = nxge_get_rdc_offset(nxgep,
14266929Smisaki 		    TCAM_CLASS_UDP_IPV6,
142711304SJanie.Lu@Sun.COM 		    channel_cookie);
14283859Sml29623 		break;
14293859Sml29623 
14303859Sml29623 	case FSPEC_SCTPIP4:
14313859Sml29623 		nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr);
14323859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
14336929Smisaki 		    TCAM_CLASS_SCTP_IPV4,
143411304SJanie.Lu@Sun.COM 		    flow_cookie);
14353859Sml29623 		offset = nxge_get_rdc_offset(nxgep,
14366929Smisaki 		    TCAM_CLASS_SCTP_IPV4,
143711304SJanie.Lu@Sun.COM 		    channel_cookie);
14383859Sml29623 		break;
14393859Sml29623 
14403859Sml29623 	case FSPEC_SCTPIP6:
14413859Sml29623 		nxge_fill_tcam_entry_sctp_ipv6(nxgep,
14426929Smisaki 		    flow_spec, &tcam_ptr);
14433859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
14446929Smisaki 		    TCAM_CLASS_SCTP_IPV6,
144511304SJanie.Lu@Sun.COM 		    flow_cookie);
144611304SJanie.Lu@Sun.COM 		offset = nxge_get_rdc_offset(nxgep,
144711304SJanie.Lu@Sun.COM 		    TCAM_CLASS_SCTP_IPV6,
14486929Smisaki 		    channel_cookie);
144911304SJanie.Lu@Sun.COM 		break;
145011304SJanie.Lu@Sun.COM 
145111304SJanie.Lu@Sun.COM 	case FSPEC_AHIP4:
145211304SJanie.Lu@Sun.COM 	case FSPEC_ESPIP4:
145311304SJanie.Lu@Sun.COM 		nxge_fill_tcam_entry_ah_esp(nxgep, flow_spec, &tcam_ptr);
145411304SJanie.Lu@Sun.COM 		rdc_grp = nxge_get_rdc_group(nxgep,
145511304SJanie.Lu@Sun.COM 		    TCAM_CLASS_AH_ESP_IPV4,
145611304SJanie.Lu@Sun.COM 		    flow_cookie);
14573859Sml29623 		offset = nxge_get_rdc_offset(nxgep,
145811304SJanie.Lu@Sun.COM 		    TCAM_CLASS_AH_ESP_IPV4,
145911304SJanie.Lu@Sun.COM 		    channel_cookie);
14603859Sml29623 		break;
14613859Sml29623 
146211304SJanie.Lu@Sun.COM 	case FSPEC_AHIP6:
146311304SJanie.Lu@Sun.COM 	case FSPEC_ESPIP6:
146411304SJanie.Lu@Sun.COM 		nxge_fill_tcam_entry_ah_esp_ipv6(nxgep,
146511304SJanie.Lu@Sun.COM 		    flow_spec, &tcam_ptr);
146611304SJanie.Lu@Sun.COM 		rdc_grp = nxge_get_rdc_group(nxgep,
146711304SJanie.Lu@Sun.COM 		    TCAM_CLASS_AH_ESP_IPV6,
146811304SJanie.Lu@Sun.COM 		    flow_cookie);
146911304SJanie.Lu@Sun.COM 		offset = nxge_get_rdc_offset(nxgep,
147011304SJanie.Lu@Sun.COM 		    TCAM_CLASS_AH_ESP_IPV6,
147111304SJanie.Lu@Sun.COM 		    channel_cookie);
147211304SJanie.Lu@Sun.COM 		break;
147311304SJanie.Lu@Sun.COM 
147411304SJanie.Lu@Sun.COM 	case FSPEC_IP_USR:
147511304SJanie.Lu@Sun.COM 		nxge_fill_tcam_entry_ip_usr(nxgep, flow_spec, &tcam_ptr,
147611304SJanie.Lu@Sun.COM 		    (tcam_class_t)class);
147711304SJanie.Lu@Sun.COM 		rdc_grp = nxge_get_rdc_group(nxgep,
147811304SJanie.Lu@Sun.COM 		    (tcam_class_t)class, flow_cookie);
147911304SJanie.Lu@Sun.COM 		offset = nxge_get_rdc_offset(nxgep,
148011304SJanie.Lu@Sun.COM 		    (tcam_class_t)class, channel_cookie);
148111304SJanie.Lu@Sun.COM 		break;
14823859Sml29623 	default:
148311304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
148411304SJanie.Lu@Sun.COM 		    "nxge_add_tcam_entry: Unknown flow spec 0x%x",
148511304SJanie.Lu@Sun.COM 		    flow_spec->flow_type));
148611304SJanie.Lu@Sun.COM 		return (NXGE_ERROR);
14873859Sml29623 	}
14883859Sml29623 
14893859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
14906929Smisaki 	    " nxge_add_tcam_entry write"
14916929Smisaki 	    " for location %d offset %d", location, offset));
14923859Sml29623 
14933859Sml29623 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
14943859Sml29623 	rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr);
14953859Sml29623 
14963859Sml29623 	if (rs & NPI_FFLP_ERROR) {
14973859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14986929Smisaki 		    " nxge_add_tcam_entry write"
14996929Smisaki 		    " failed for location %d", location));
150011304SJanie.Lu@Sun.COM 		goto fail;
15013859Sml29623 	}
15023859Sml29623 
15033859Sml29623 	tcam_ptr.match_action.value = 0;
15043859Sml29623 	tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp;
15053859Sml29623 	tcam_ptr.match_action.bits.ldw.offset = offset;
15063859Sml29623 	tcam_ptr.match_action.bits.ldw.tres =
15076929Smisaki 	    TRES_TERM_OVRD_L2RDC;
150811304SJanie.Lu@Sun.COM 	if (channel_cookie == NXGE_PKT_DISCARD)
15093859Sml29623 		tcam_ptr.match_action.bits.ldw.disc = 1;
15103859Sml29623 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
15116929Smisaki 	    location, tcam_ptr.match_action.value);
15123859Sml29623 	if (rs & NPI_FFLP_ERROR) {
15133859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15146929Smisaki 		    " nxge_add_tcam_entry write"
15156929Smisaki 		    " failed for ASC RAM location %d", location));
151611304SJanie.Lu@Sun.COM 		goto fail;
15173859Sml29623 	}
15183859Sml29623 	bcopy((void *) &tcam_ptr,
15196929Smisaki 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
15206929Smisaki 	    sizeof (tcam_entry_t));
152111304SJanie.Lu@Sun.COM 	nxgep->classifier.tcam_entry_cnt++;
152211304SJanie.Lu@Sun.COM 	nxgep->classifier.tcam_entries[location].valid = 1;
15233859Sml29623 
15243859Sml29623 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15253859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry"));
15263859Sml29623 	return (NXGE_OK);
152711304SJanie.Lu@Sun.COM fail:
152811304SJanie.Lu@Sun.COM 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
152911304SJanie.Lu@Sun.COM 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_tcam_entry FAILED"));
153011304SJanie.Lu@Sun.COM 	return (NXGE_ERROR);
15313859Sml29623 }
15323859Sml29623 
15333859Sml29623 static nxge_status_t
nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)15343859Sml29623 nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)
15353859Sml29623 {
15363859Sml29623 	tcam_entry_t tcam_ptr;
15373859Sml29623 	tcam_location_t location;
15383859Sml29623 	uint8_t class;
15393859Sml29623 	uint32_t class_config;
15403859Sml29623 	npi_handle_t handle;
15413859Sml29623 	npi_status_t rs = NPI_SUCCESS;
15423859Sml29623 	p_nxge_hw_list_t hw_p;
15433859Sml29623 	nxge_status_t status = NXGE_OK;
15443859Sml29623 
15453859Sml29623 	handle = nxgep->npi_reg_handle;
15463859Sml29623 	class = 0;
15473859Sml29623 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
15483859Sml29623 	tcam_ptr.ip4_noport_key = 1;
15493859Sml29623 	tcam_ptr.ip4_noport_mask = 1;
15503859Sml29623 	location = nxgep->function_num;
15513859Sml29623 	nxgep->classifier.fragment_bug_location = location;
15523859Sml29623 
15533859Sml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
15543859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15556929Smisaki 		    " nxge_tcam_handle_ip_fragment: common hardware not set",
15566929Smisaki 		    nxgep->niu_type));
15573859Sml29623 		return (NXGE_ERROR);
15583859Sml29623 	}
15593859Sml29623 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
15603859Sml29623 	rs = npi_fflp_tcam_entry_write(handle,
15616929Smisaki 	    location, &tcam_ptr);
15623859Sml29623 
15633859Sml29623 	if (rs & NPI_FFLP_ERROR) {
15643859Sml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15653859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15666929Smisaki 		    " nxge_tcam_handle_ip_fragment "
15676929Smisaki 		    " tcam_entry write"
15686929Smisaki 		    " failed for location %d", location));
15693859Sml29623 		return (NXGE_ERROR);
15703859Sml29623 	}
15713859Sml29623 	tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp;
15723859Sml29623 	tcam_ptr.match_action.bits.ldw.offset = 0;	/* use the default */
15733859Sml29623 	tcam_ptr.match_action.bits.ldw.tres =
15746929Smisaki 	    TRES_TERM_USE_OFFSET;
15753859Sml29623 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
15766929Smisaki 	    location, tcam_ptr.match_action.value);
15773859Sml29623 
15783859Sml29623 	if (rs & NPI_FFLP_ERROR) {
15793859Sml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15803859Sml29623 		NXGE_DEBUG_MSG((nxgep,
15816929Smisaki 		    FFLP_CTL,
15826929Smisaki 		    " nxge_tcam_handle_ip_fragment "
15836929Smisaki 		    " tcam_entry write"
15846929Smisaki 		    " failed for ASC RAM location %d", location));
15853859Sml29623 		return (NXGE_ERROR);
15863859Sml29623 	}
15873859Sml29623 	bcopy((void *) &tcam_ptr,
15886929Smisaki 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
15896929Smisaki 	    sizeof (tcam_entry_t));
159011304SJanie.Lu@Sun.COM 	nxgep->classifier.tcam_entry_cnt++;
159111304SJanie.Lu@Sun.COM 	nxgep->classifier.tcam_entries[location].valid = 1;
15923859Sml29623 	for (class = TCAM_CLASS_TCP_IPV4;
15936929Smisaki 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
15943859Sml29623 		class_config = nxgep->class_config.class_cfg[class];
15953859Sml29623 		class_config |= NXGE_CLASS_TCAM_LOOKUP;
15963859Sml29623 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
15973859Sml29623 
15983859Sml29623 		if (status & NPI_FFLP_ERROR) {
15993859Sml29623 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
16003859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16016929Smisaki 			    "nxge_tcam_handle_ip_fragment "
16026929Smisaki 			    "nxge_fflp_ip_class_config failed "
16036929Smisaki 			    " class %d config %x ", class, class_config));
16043859Sml29623 			return (NXGE_ERROR);
16053859Sml29623 		}
16063859Sml29623 	}
16073859Sml29623 
16083859Sml29623 	rs = npi_fflp_cfg_tcam_enable(handle);
16093859Sml29623 	if (rs & NPI_FFLP_ERROR) {
16103859Sml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
16113859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16126929Smisaki 		    "nxge_tcam_handle_ip_fragment "
16136929Smisaki 		    " nxge_fflp_config_tcam_enable failed"));
16143859Sml29623 		return (NXGE_ERROR);
16153859Sml29623 	}
16163859Sml29623 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
16173859Sml29623 	return (NXGE_OK);
16183859Sml29623 }
16193859Sml29623 
16203859Sml29623 /* ARGSUSED */
16213859Sml29623 static int
nxge_flow_need_hash_lookup(p_nxge_t nxgep,flow_resource_t * flow_res)16223859Sml29623 nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res)
16233859Sml29623 {
16243859Sml29623 	return (0);
16253859Sml29623 }
16263859Sml29623 
16273859Sml29623 nxge_status_t
nxge_add_flow(p_nxge_t nxgep,flow_resource_t * flow_res)16283859Sml29623 nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res)
16293859Sml29623 {
16303859Sml29623 
16313859Sml29623 	int insert_hash = 0;
16323859Sml29623 	nxge_status_t status = NXGE_OK;
16333859Sml29623 
16344977Sraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
16353859Sml29623 		/* determine whether to do TCAM or Hash flow */
16363859Sml29623 		insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res);
16373859Sml29623 	}
16383859Sml29623 	if (insert_hash) {
16393859Sml29623 		status = nxge_add_fcram_entry(nxgep, flow_res);
16403859Sml29623 	} else {
16413859Sml29623 		status = nxge_add_tcam_entry(nxgep, flow_res);
16423859Sml29623 	}
16433859Sml29623 	return (status);
16443859Sml29623 }
16453859Sml29623 
16463859Sml29623 void
nxge_put_tcam(p_nxge_t nxgep,p_mblk_t mp)16473859Sml29623 nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp)
16483859Sml29623 {
16493859Sml29623 	flow_resource_t *fs;
16503859Sml29623 
16513859Sml29623 	fs = (flow_resource_t *)mp->b_rptr;
16523859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16536929Smisaki 	    "nxge_put_tcam addr fs $%p  type %x offset %x",
16546929Smisaki 	    fs, fs->flow_spec.flow_type, fs->channel_cookie));
16553859Sml29623 	(void) nxge_add_tcam_entry(nxgep, fs);
16563859Sml29623 }
16573859Sml29623 
16583859Sml29623 nxge_status_t
nxge_fflp_config_tcam_enable(p_nxge_t nxgep)16593859Sml29623 nxge_fflp_config_tcam_enable(p_nxge_t nxgep)
16603859Sml29623 {
16613859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
16623859Sml29623 	npi_status_t rs = NPI_SUCCESS;
16633859Sml29623 
16643859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable"));
16653859Sml29623 	rs = npi_fflp_cfg_tcam_enable(handle);
16663859Sml29623 	if (rs & NPI_FFLP_ERROR) {
16673859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16686929Smisaki 		    " nxge_fflp_config_tcam_enable failed"));
16693859Sml29623 		return (NXGE_ERROR | rs);
16703859Sml29623 	}
16713859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable"));
16723859Sml29623 	return (NXGE_OK);
16733859Sml29623 }
16743859Sml29623 
16753859Sml29623 nxge_status_t
nxge_fflp_config_tcam_disable(p_nxge_t nxgep)16763859Sml29623 nxge_fflp_config_tcam_disable(p_nxge_t nxgep)
16773859Sml29623 {
16783859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
16793859Sml29623 	npi_status_t rs = NPI_SUCCESS;
16803859Sml29623 
16813859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
16826929Smisaki 	    " ==> nxge_fflp_config_tcam_disable"));
16833859Sml29623 	rs = npi_fflp_cfg_tcam_disable(handle);
16843859Sml29623 	if (rs & NPI_FFLP_ERROR) {
16853859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16866929Smisaki 		    " nxge_fflp_config_tcam_disable failed"));
16873859Sml29623 		return (NXGE_ERROR | rs);
16883859Sml29623 	}
16893859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
16906929Smisaki 	    " <== nxge_fflp_config_tcam_disable"));
16913859Sml29623 	return (NXGE_OK);
16923859Sml29623 }
16933859Sml29623 
16943859Sml29623 nxge_status_t
nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)16953859Sml29623 nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)
16963859Sml29623 {
16973859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
16983859Sml29623 	npi_status_t rs = NPI_SUCCESS;
16993859Sml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
17003859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
17013859Sml29623 	uint8_t partition;
17023859Sml29623 
17033859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17046929Smisaki 	    " ==> nxge_fflp_config_hash_lookup_enable"));
17053859Sml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
17063859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
17073859Sml29623 
17086495Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
17096495Sspeer 		if (p_cfgp->grpids[partition]) {
17106495Sspeer 			rs = npi_fflp_cfg_fcram_partition_enable(
17116929Smisaki 			    handle, partition);
17126495Sspeer 			if (rs != NPI_SUCCESS) {
17136495Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17146495Sspeer 				    " nxge_fflp_config_hash_lookup_enable"
17156495Sspeer 				    "failed FCRAM partition"
17166495Sspeer 				    " enable for partition %d ", partition));
17176495Sspeer 				return (NXGE_ERROR | rs);
17186495Sspeer 			}
17193859Sml29623 		}
17203859Sml29623 	}
17213859Sml29623 
17223859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17236929Smisaki 	    " <== nxge_fflp_config_hash_lookup_enable"));
17243859Sml29623 	return (NXGE_OK);
17253859Sml29623 }
17263859Sml29623 
17273859Sml29623 nxge_status_t
nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)17283859Sml29623 nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)
17293859Sml29623 {
17303859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
17313859Sml29623 	npi_status_t rs = NPI_SUCCESS;
17323859Sml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
17333859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
17343859Sml29623 	uint8_t partition;
17353859Sml29623 
17363859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17376929Smisaki 	    " ==> nxge_fflp_config_hash_lookup_disable"));
17383859Sml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
17393859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
17403859Sml29623 
17416495Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
17426495Sspeer 		if (p_cfgp->grpids[partition]) {
17436495Sspeer 			rs = npi_fflp_cfg_fcram_partition_disable(handle,
17446495Sspeer 			    partition);
17456495Sspeer 			if (rs != NPI_SUCCESS) {
17466495Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17476495Sspeer 				    " nxge_fflp_config_hash_lookup_disable"
17486495Sspeer 				    " failed FCRAM partition"
17496495Sspeer 				    " disable for partition %d ", partition));
17506495Sspeer 				return (NXGE_ERROR | rs);
17516495Sspeer 			}
17523859Sml29623 		}
17533859Sml29623 	}
17543859Sml29623 
17553859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17566929Smisaki 	    " <== nxge_fflp_config_hash_lookup_disable"));
17573859Sml29623 	return (NXGE_OK);
17583859Sml29623 }
17593859Sml29623 
17603859Sml29623 nxge_status_t
nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)17613859Sml29623 nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)
17623859Sml29623 {
17633859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
17643859Sml29623 	npi_status_t rs = NPI_SUCCESS;
17653859Sml29623 
17663859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17676929Smisaki 	    " ==> nxge_fflp_config_llc_snap_enable"));
17683859Sml29623 	rs = npi_fflp_cfg_llcsnap_enable(handle);
17693859Sml29623 	if (rs & NPI_FFLP_ERROR) {
17703859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17716929Smisaki 		    " nxge_fflp_config_llc_snap_enable failed"));
17723859Sml29623 		return (NXGE_ERROR | rs);
17733859Sml29623 	}
17743859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17756929Smisaki 	    " <== nxge_fflp_config_llc_snap_enable"));
17763859Sml29623 	return (NXGE_OK);
17773859Sml29623 }
17783859Sml29623 
17793859Sml29623 nxge_status_t
nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)17803859Sml29623 nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)
17813859Sml29623 {
17823859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
17833859Sml29623 	npi_status_t rs = NPI_SUCCESS;
17843859Sml29623 
17853859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17866929Smisaki 	    " ==> nxge_fflp_config_llc_snap_disable"));
17873859Sml29623 	rs = npi_fflp_cfg_llcsnap_disable(handle);
17883859Sml29623 	if (rs & NPI_FFLP_ERROR) {
17893859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17906929Smisaki 		    " nxge_fflp_config_llc_snap_disable failed"));
17913859Sml29623 		return (NXGE_ERROR | rs);
17923859Sml29623 	}
17933859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17946929Smisaki 	    " <== nxge_fflp_config_llc_snap_disable"));
17953859Sml29623 	return (NXGE_OK);
17963859Sml29623 }
17973859Sml29623 
17983859Sml29623 nxge_status_t
nxge_fflp_ip_usr_class_config(p_nxge_t nxgep,tcam_class_t class,uint32_t config)17993859Sml29623 nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class,
18003859Sml29623 	uint32_t config)
18013859Sml29623 {
18023859Sml29623 	npi_status_t rs = NPI_SUCCESS;
18033859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
18043859Sml29623 	uint8_t tos, tos_mask, proto, ver = 0;
18053859Sml29623 	uint8_t class_enable = 0;
18063859Sml29623 
18073859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config"));
18083859Sml29623 
18093859Sml29623 	tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >>
18106929Smisaki 	    NXGE_CLASS_CFG_IP_TOS_SHIFT;
18113859Sml29623 	tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >>
18126929Smisaki 	    NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT;
18133859Sml29623 	proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >>
18146929Smisaki 	    NXGE_CLASS_CFG_IP_PROTO_SHIFT;
18153859Sml29623 	if (config & NXGE_CLASS_CFG_IP_IPV6_MASK)
18163859Sml29623 		ver = 1;
18173859Sml29623 	if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK)
18183859Sml29623 		class_enable = 1;
18193859Sml29623 	rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask,
18206929Smisaki 	    proto, ver);
18213859Sml29623 	if (rs & NPI_FFLP_ERROR) {
18223859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18236929Smisaki 		    " nxge_fflp_ip_usr_class_config"
18246929Smisaki 		    " for class %d failed ", class));
18253859Sml29623 		return (NXGE_ERROR | rs);
18263859Sml29623 	}
18273859Sml29623 	if (class_enable)
18283859Sml29623 		rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class);
18293859Sml29623 	else
18303859Sml29623 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
18313859Sml29623 
18323859Sml29623 	if (rs & NPI_FFLP_ERROR) {
18333859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18346929Smisaki 		    " nxge_fflp_ip_usr_class_config"
18356929Smisaki 		    " TCAM enable/disable for class %d failed ", class));
18363859Sml29623 		return (NXGE_ERROR | rs);
18373859Sml29623 	}
18383859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config"));
18393859Sml29623 	return (NXGE_OK);
18403859Sml29623 }
18413859Sml29623 
18423859Sml29623 nxge_status_t
nxge_fflp_ip_class_config(p_nxge_t nxgep,tcam_class_t class,uint32_t config)18433859Sml29623 nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config)
18443859Sml29623 {
18453859Sml29623 	uint32_t class_config;
18463859Sml29623 	nxge_status_t t_status = NXGE_OK;
18473859Sml29623 	nxge_status_t f_status = NXGE_OK;
18483859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
18493859Sml29623 
18503859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
18513859Sml29623 
18523859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
18533859Sml29623 	class_config = p_class_cfgp->class_cfg[class];
18543859Sml29623 
18553859Sml29623 	if (class_config != config) {
18563859Sml29623 		p_class_cfgp->class_cfg[class] = config;
18573859Sml29623 		class_config = config;
18583859Sml29623 	}
18593859Sml29623 
18603859Sml29623 	t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config);
18613859Sml29623 	f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config);
18623859Sml29623 
18633859Sml29623 	if (t_status & NPI_FFLP_ERROR) {
18643859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
18656929Smisaki 		    " nxge_fflp_ip_class_config %x"
18666929Smisaki 		    " for class %d tcam failed", config, class));
18673859Sml29623 		return (t_status);
18683859Sml29623 	}
18693859Sml29623 	if (f_status & NPI_FFLP_ERROR) {
18703859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18716929Smisaki 		    " nxge_fflp_ip_class_config %x"
18726929Smisaki 		    " for class %d flow key failed", config, class));
18733859Sml29623 		return (f_status);
18743859Sml29623 	}
18753859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
18763859Sml29623 	return (NXGE_OK);
18773859Sml29623 }
18783859Sml29623 
18793859Sml29623 nxge_status_t
nxge_fflp_ip_class_config_get(p_nxge_t nxgep,tcam_class_t class,uint32_t * config)18803859Sml29623 nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class,
18813859Sml29623 	uint32_t *config)
18823859Sml29623 {
18833859Sml29623 	uint32_t t_class_config, f_class_config;
18843859Sml29623 	int t_status = NXGE_OK;
18853859Sml29623 	int f_status = NXGE_OK;
18863859Sml29623 
18873859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
18883859Sml29623 
18893859Sml29623 	t_class_config = f_class_config = 0;
18903859Sml29623 	t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config);
18913859Sml29623 	f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config);
18923859Sml29623 
18933859Sml29623 	if (t_status & NPI_FFLP_ERROR) {
18943859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18956929Smisaki 		    " nxge_fflp_ip_class_config_get  "
18966929Smisaki 		    " for class %d tcam failed", class));
18973859Sml29623 		return (t_status);
18983859Sml29623 	}
18993859Sml29623 
19003859Sml29623 	if (f_status & NPI_FFLP_ERROR) {
19013859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
19026929Smisaki 		    " nxge_fflp_ip_class_config_get  "
19036929Smisaki 		    " for class %d flow key failed", class));
19043859Sml29623 		return (f_status);
19053859Sml29623 	}
19063859Sml29623 
19073859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
19086929Smisaki 	    " nxge_fflp_ip_class_config tcam %x flow %x",
19096929Smisaki 	    t_class_config, f_class_config));
19103859Sml29623 
19113859Sml29623 	*config = t_class_config | f_class_config;
19123859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get"));
19133859Sml29623 	return (NXGE_OK);
19143859Sml29623 }
19153859Sml29623 
19163859Sml29623 nxge_status_t
nxge_fflp_ip_class_config_all(p_nxge_t nxgep)19173859Sml29623 nxge_fflp_ip_class_config_all(p_nxge_t nxgep)
19183859Sml29623 {
19193859Sml29623 	uint32_t class_config;
19203859Sml29623 	tcam_class_t class;
19213859Sml29623 
19223859Sml29623 #ifdef	NXGE_DEBUG
19233859Sml29623 	int status = NXGE_OK;
19243859Sml29623 #endif
19253859Sml29623 
19263859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config"));
19273859Sml29623 	for (class = TCAM_CLASS_TCP_IPV4;
19286929Smisaki 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
19293859Sml29623 		class_config = nxgep->class_config.class_cfg[class];
19303859Sml29623 #ifndef	NXGE_DEBUG
19313859Sml29623 		(void) nxge_fflp_ip_class_config(nxgep, class, class_config);
19323859Sml29623 #else
19333859Sml29623 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
19343859Sml29623 		if (status & NPI_FFLP_ERROR) {
19353859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19366929Smisaki 			    "nxge_fflp_ip_class_config failed "
19376929Smisaki 			    " class %d config %x ",
19386929Smisaki 			    class, class_config));
19393859Sml29623 		}
19403859Sml29623 #endif
19413859Sml29623 	}
19423859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
19433859Sml29623 	return (NXGE_OK);
19443859Sml29623 }
19453859Sml29623 
19463859Sml29623 nxge_status_t
nxge_fflp_config_vlan_table(p_nxge_t nxgep,uint16_t vlan_id)19473859Sml29623 nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id)
19483859Sml29623 {
19493859Sml29623 	uint8_t port, rdc_grp;
19503859Sml29623 	npi_handle_t handle;
19513859Sml29623 	npi_status_t rs = NPI_SUCCESS;
19523859Sml29623 	uint8_t priority = 1;
19533859Sml29623 	p_nxge_mv_cfg_t vlan_table;
19543859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
19553859Sml29623 	p_nxge_hw_list_t hw_p;
19563859Sml29623 
19573859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table"));
19583859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
19593859Sml29623 	handle = nxgep->npi_reg_handle;
19603859Sml29623 	vlan_table = p_class_cfgp->vlan_tbl;
19613859Sml29623 	port = nxgep->function_num;
19623859Sml29623 
19633859Sml29623 	if (vlan_table[vlan_id].flag == 0) {
19643859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19656929Smisaki 		    " nxge_fflp_config_vlan_table"
19666929Smisaki 		    " vlan id is not configured %d", vlan_id));
19673859Sml29623 		return (NXGE_ERROR);
19683859Sml29623 	}
19693859Sml29623 
19703859Sml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
19713859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19726929Smisaki 		    " nxge_fflp_config_vlan_table:"
19736929Smisaki 		    " common hardware not set", nxgep->niu_type));
19743859Sml29623 		return (NXGE_ERROR);
19753859Sml29623 	}
19763859Sml29623 	MUTEX_ENTER(&hw_p->nxge_vlan_lock);
19773859Sml29623 	rdc_grp = vlan_table[vlan_id].rdctbl;
19783859Sml29623 	rs = npi_fflp_cfg_enet_vlan_table_assoc(handle,
19796929Smisaki 	    port, vlan_id,
19806929Smisaki 	    rdc_grp, priority);
19813859Sml29623 
19823859Sml29623 	MUTEX_EXIT(&hw_p->nxge_vlan_lock);
19833859Sml29623 	if (rs & NPI_FFLP_ERROR) {
19843859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19856929Smisaki 		    "nxge_fflp_config_vlan_table failed "
19866929Smisaki 		    " Port %d vlan_id %d rdc_grp %d",
19876929Smisaki 		    port, vlan_id, rdc_grp));
19883859Sml29623 		return (NXGE_ERROR | rs);
19893859Sml29623 	}
19903859Sml29623 
19913859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table"));
19923859Sml29623 	return (NXGE_OK);
19933859Sml29623 }
19943859Sml29623 
19953859Sml29623 nxge_status_t
nxge_fflp_update_hw(p_nxge_t nxgep)19963859Sml29623 nxge_fflp_update_hw(p_nxge_t nxgep)
19973859Sml29623 {
19983859Sml29623 	nxge_status_t status = NXGE_OK;
19993859Sml29623 	p_nxge_param_t pa;
20003859Sml29623 	uint64_t cfgd_vlans;
20013859Sml29623 	uint64_t *val_ptr;
20023859Sml29623 	int i;
20033859Sml29623 	int num_macs;
20043859Sml29623 	uint8_t alt_mac;
20053859Sml29623 	nxge_param_map_t *p_map;
20063859Sml29623 	p_nxge_mv_cfg_t vlan_table;
20073859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
20083859Sml29623 	p_nxge_dma_pt_cfg_t p_all_cfgp;
20093859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
20103859Sml29623 
20113859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw"));
20123859Sml29623 
20133859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
20143859Sml29623 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
20153859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
20163859Sml29623 
20173859Sml29623 	status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1);
20183859Sml29623 	if (status != NXGE_OK) {
20193859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20206929Smisaki 		    "nxge_fflp_set_hash1 Failed"));
20213859Sml29623 		return (NXGE_ERROR);
20223859Sml29623 	}
20233859Sml29623 
20243859Sml29623 	status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2);
20253859Sml29623 	if (status != NXGE_OK) {
20263859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20276929Smisaki 		    "nxge_fflp_set_hash2 Failed"));
20283859Sml29623 		return (NXGE_ERROR);
20293859Sml29623 	}
20303859Sml29623 	vlan_table = p_class_cfgp->vlan_tbl;
20313859Sml29623 
20323859Sml29623 	/* configure vlan tables */
20333859Sml29623 	pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp];
20345125Sjoycey #if defined(__i386)
20355125Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
20365125Sjoycey #else
20373859Sml29623 	val_ptr = (uint64_t *)pa->value;
20385125Sjoycey #endif
20393859Sml29623 	cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >>
20406929Smisaki 	    NXGE_PARAM_ARRAY_CNT_SHIFT);
20413859Sml29623 
20423859Sml29623 	for (i = 0; i < cfgd_vlans; i++) {
20433859Sml29623 		p_map = (nxge_param_map_t *)&val_ptr[i];
20443859Sml29623 		if (vlan_table[p_map->param_id].flag) {
20453859Sml29623 			status = nxge_fflp_config_vlan_table(nxgep,
20466929Smisaki 			    p_map->param_id);
20473859Sml29623 			if (status != NXGE_OK) {
20483859Sml29623 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20496929Smisaki 				    "nxge_fflp_config_vlan_table Failed"));
20503859Sml29623 				return (NXGE_ERROR);
20513859Sml29623 			}
20523859Sml29623 		}
20533859Sml29623 	}
20543859Sml29623 
20553859Sml29623 	/* config MAC addresses */
20563859Sml29623 	num_macs = p_cfgp->max_macs;
20573859Sml29623 	pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp];
20585125Sjoycey #if defined(__i386)
20595125Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
20605125Sjoycey #else
20613859Sml29623 	val_ptr = (uint64_t *)pa->value;
20625125Sjoycey #endif
20633859Sml29623 
20643859Sml29623 	for (alt_mac = 0; alt_mac < num_macs; alt_mac++) {
20653859Sml29623 		if (p_class_cfgp->mac_host_info[alt_mac].flag) {
20663859Sml29623 			status = nxge_logical_mac_assign_rdc_table(nxgep,
20676929Smisaki 			    alt_mac);
20683859Sml29623 			if (status != NXGE_OK) {
20693859Sml29623 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20706929Smisaki 				    "nxge_logical_mac_assign_rdc_table"
20716929Smisaki 				    " Failed"));
20723859Sml29623 				return (NXGE_ERROR);
20733859Sml29623 			}
20743859Sml29623 		}
20753859Sml29623 	}
20763859Sml29623 
20773859Sml29623 	/* Config Hash values */
20785523Syc148097 	/* config classes */
20793859Sml29623 	status = nxge_fflp_ip_class_config_all(nxgep);
20803859Sml29623 	if (status != NXGE_OK) {
20813859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
20826929Smisaki 		    "nxge_fflp_ip_class_config_all Failed"));
20833859Sml29623 		return (NXGE_ERROR);
20843859Sml29623 	}
20853859Sml29623 	return (NXGE_OK);
20863859Sml29623 }
20873859Sml29623 
20883859Sml29623 nxge_status_t
nxge_classify_init_hw(p_nxge_t nxgep)20893859Sml29623 nxge_classify_init_hw(p_nxge_t nxgep)
20903859Sml29623 {
20913859Sml29623 	nxge_status_t status = NXGE_OK;
20923859Sml29623 
20933859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw"));
20943859Sml29623 
20953859Sml29623 	if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) {
20963859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20976929Smisaki 		    "nxge_classify_init_hw already init"));
20983859Sml29623 		return (NXGE_OK);
20993859Sml29623 	}
21003859Sml29623 
21013859Sml29623 	/* Now do a real configuration */
21023859Sml29623 	status = nxge_fflp_update_hw(nxgep);
21033859Sml29623 	if (status != NXGE_OK) {
21043859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21056929Smisaki 		    "nxge_fflp_update_hw failed"));
21063859Sml29623 		return (NXGE_ERROR);
21073859Sml29623 	}
21083859Sml29623 
21093859Sml29623 	/* Init RDC tables? ? who should do that? rxdma or fflp ? */
21103859Sml29623 	/* attach rdc table to the MAC port. */
21113859Sml29623 	status = nxge_main_mac_assign_rdc_table(nxgep);
21123859Sml29623 	if (status != NXGE_OK) {
21133859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21146929Smisaki 		    "nxge_main_mac_assign_rdc_table failed"));
21153859Sml29623 		return (NXGE_ERROR);
21163859Sml29623 	}
21173859Sml29623 
21183859Sml29623 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
21193859Sml29623 	if (status != NXGE_OK) {
21203859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21216929Smisaki 		    "nxge_multicast_mac_assign_rdc_table failed"));
21223859Sml29623 		return (NXGE_ERROR);
21233859Sml29623 	}
21243859Sml29623 
212511304SJanie.Lu@Sun.COM 	if (nxgep->classifier.fragment_bug == 1) {
212611304SJanie.Lu@Sun.COM 		status = nxge_tcam_handle_ip_fragment(nxgep);
212711304SJanie.Lu@Sun.COM 		if (status != NXGE_OK) {
212811304SJanie.Lu@Sun.COM 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
212911304SJanie.Lu@Sun.COM 			    "nxge_tcam_handle_ip_fragment failed"));
213011304SJanie.Lu@Sun.COM 			return (NXGE_ERROR);
213111304SJanie.Lu@Sun.COM 		}
21323859Sml29623 	}
21333859Sml29623 
21343859Sml29623 	nxgep->classifier.state |= NXGE_FFLP_HW_INIT;
21353859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw"));
21363859Sml29623 	return (NXGE_OK);
21373859Sml29623 }
21383859Sml29623 
21393859Sml29623 nxge_status_t
nxge_fflp_handle_sys_errors(p_nxge_t nxgep)21403859Sml29623 nxge_fflp_handle_sys_errors(p_nxge_t nxgep)
21413859Sml29623 {
21423859Sml29623 	npi_handle_t handle;
21433859Sml29623 	p_nxge_fflp_stats_t statsp;
21443859Sml29623 	uint8_t portn, rdc_grp;
21453859Sml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
21463859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
21473859Sml29623 	vlan_par_err_t vlan_err;
21483859Sml29623 	tcam_err_t tcam_err;
21493859Sml29623 	hash_lookup_err_log1_t fcram1_err;
21503859Sml29623 	hash_lookup_err_log2_t fcram2_err;
21513859Sml29623 	hash_tbl_data_log_t fcram_err;
21523859Sml29623 
21533859Sml29623 	handle = nxgep->npi_handle;
21543859Sml29623 	statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats;
21553859Sml29623 	portn = nxgep->mac.portnum;
21563859Sml29623 
21573859Sml29623 	/*
21583859Sml29623 	 * need to read the fflp error registers to figure out what the error
21593859Sml29623 	 * is
21603859Sml29623 	 */
21613859Sml29623 	npi_fflp_vlan_error_get(handle, &vlan_err);
21623859Sml29623 	npi_fflp_tcam_error_get(handle, &tcam_err);
21633859Sml29623 
21643859Sml29623 	if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) {
21653859Sml29623 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21666929Smisaki 		    " vlan table parity error on port %d"
21676929Smisaki 		    " addr: 0x%x data: 0x%x",
21686929Smisaki 		    portn, vlan_err.bits.ldw.addr,
21696929Smisaki 		    vlan_err.bits.ldw.data));
21703859Sml29623 		statsp->vlan_parity_err++;
21713859Sml29623 
21723859Sml29623 		if (vlan_err.bits.ldw.m_err) {
21733859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21746929Smisaki 			    " vlan table multiple errors on port %d",
21756929Smisaki 			    portn));
21763859Sml29623 		}
21773859Sml29623 		statsp->errlog.vlan = (uint32_t)vlan_err.value;
21783859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
21796929Smisaki 		    NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR);
21803859Sml29623 		npi_fflp_vlan_error_clear(handle);
21813859Sml29623 	}
21823859Sml29623 
21833859Sml29623 	if (tcam_err.bits.ldw.err) {
21843859Sml29623 		if (tcam_err.bits.ldw.p_ecc != 0) {
21853859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21866929Smisaki 			    " TCAM ECC error on port %d"
21876929Smisaki 			    " TCAM entry: 0x%x syndrome: 0x%x",
21886929Smisaki 			    portn, tcam_err.bits.ldw.addr,
21896929Smisaki 			    tcam_err.bits.ldw.syndrome));
21903859Sml29623 			statsp->tcam_ecc_err++;
21913859Sml29623 		} else {
21923859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21936929Smisaki 			    " TCAM Parity error on port %d"
21946929Smisaki 			    " addr: 0x%x parity value: 0x%x",
21956929Smisaki 			    portn, tcam_err.bits.ldw.addr,
21966929Smisaki 			    tcam_err.bits.ldw.syndrome));
21973859Sml29623 			statsp->tcam_parity_err++;
21983859Sml29623 		}
21993859Sml29623 
22003859Sml29623 		if (tcam_err.bits.ldw.mult) {
22013859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22026929Smisaki 			    " TCAM Multiple errors on port %d", portn));
22033859Sml29623 		} else {
22043859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22056929Smisaki 			    " TCAM PIO error on port %d", portn));
22063859Sml29623 		}
22073859Sml29623 
22083859Sml29623 		statsp->errlog.tcam = (uint32_t)tcam_err.value;
22093859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
22106929Smisaki 		    NXGE_FM_EREPORT_FFLP_TCAM_ERR);
22113859Sml29623 		npi_fflp_tcam_error_clear(handle);
22123859Sml29623 	}
22133859Sml29623 
22143859Sml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
22153859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
22163859Sml29623 
22176495Sspeer 	for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) {
22186495Sspeer 		if (p_cfgp->grpids[rdc_grp]) {
22196495Sspeer 			npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp);
22206495Sspeer 			if (fcram_err.bits.ldw.pio_err) {
22216495Sspeer 				NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22226929Smisaki 				    " FCRAM PIO ECC error on port %d"
22236929Smisaki 				    " rdc group: %d Hash Table addr: 0x%x"
22246929Smisaki 				    " syndrome: 0x%x",
22256929Smisaki 				    portn, rdc_grp,
22266929Smisaki 				    fcram_err.bits.ldw.fcram_addr,
22276929Smisaki 				    fcram_err.bits.ldw.syndrome));
22286495Sspeer 				statsp->hash_pio_err[rdc_grp]++;
22296495Sspeer 				statsp->errlog.hash_pio[rdc_grp] =
22306495Sspeer 				    (uint32_t)fcram_err.value;
22316495Sspeer 				NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
22326495Sspeer 				    NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR);
22336495Sspeer 				npi_fflp_fcram_error_clear(handle, rdc_grp);
22346495Sspeer 			}
22353859Sml29623 		}
22363859Sml29623 	}
22373859Sml29623 
22383859Sml29623 	npi_fflp_fcram_error_log1_get(handle, &fcram1_err);
22393859Sml29623 	if (fcram1_err.bits.ldw.ecc_err) {
22403859Sml29623 		char *multi_str = "";
22413859Sml29623 		char *multi_bit_str = "";
22423859Sml29623 
22433859Sml29623 		npi_fflp_fcram_error_log2_get(handle, &fcram2_err);
22443859Sml29623 		if (fcram1_err.bits.ldw.mult_lk) {
22453859Sml29623 			multi_str = "multiple";
22463859Sml29623 		}
22473859Sml29623 		if (fcram1_err.bits.ldw.mult_bit) {
22483859Sml29623 			multi_bit_str = "multiple bits";
22493859Sml29623 		}
22505523Syc148097 		statsp->hash_lookup_err++;
22513859Sml29623 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22526929Smisaki 		    " FCRAM %s lookup %s ECC error on port %d"
22536929Smisaki 		    " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x",
22546929Smisaki 		    multi_str, multi_bit_str, portn,
22556929Smisaki 		    fcram2_err.bits.ldw.h1,
22566929Smisaki 		    fcram2_err.bits.ldw.subarea,
22576929Smisaki 		    fcram2_err.bits.ldw.syndrome));
22583859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
22596929Smisaki 		    NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR);
22603859Sml29623 	}
22613859Sml29623 	statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value;
22623859Sml29623 	statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value;
22633859Sml29623 	return (NXGE_OK);
22643859Sml29623 }
226511304SJanie.Lu@Sun.COM 
226611304SJanie.Lu@Sun.COM int
nxge_get_valid_tcam_cnt(p_nxge_t nxgep)226711304SJanie.Lu@Sun.COM nxge_get_valid_tcam_cnt(p_nxge_t nxgep) {
226811304SJanie.Lu@Sun.COM 	return ((nxgep->classifier.fragment_bug == 1) ?
226911304SJanie.Lu@Sun.COM 		nxgep->classifier.tcam_entry_cnt - 1 :
227011304SJanie.Lu@Sun.COM 		nxgep->classifier.tcam_entry_cnt);
227111304SJanie.Lu@Sun.COM }
227211304SJanie.Lu@Sun.COM 
227311304SJanie.Lu@Sun.COM int
nxge_rxdma_channel_cnt(p_nxge_t nxgep)227411304SJanie.Lu@Sun.COM nxge_rxdma_channel_cnt(p_nxge_t nxgep)
227511304SJanie.Lu@Sun.COM {
227611304SJanie.Lu@Sun.COM 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
227711304SJanie.Lu@Sun.COM 	p_nxge_hw_pt_cfg_t p_cfgp;
227811304SJanie.Lu@Sun.COM 
227911304SJanie.Lu@Sun.COM 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
228011304SJanie.Lu@Sun.COM 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
228111304SJanie.Lu@Sun.COM 	return (p_cfgp->max_rdcs);
228211304SJanie.Lu@Sun.COM }
228311304SJanie.Lu@Sun.COM 
228411304SJanie.Lu@Sun.COM /* ARGSUSED */
228511304SJanie.Lu@Sun.COM int
nxge_rxclass_ioctl(p_nxge_t nxgep,queue_t * wq,mblk_t * mp)228611304SJanie.Lu@Sun.COM nxge_rxclass_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
228711304SJanie.Lu@Sun.COM {
228811304SJanie.Lu@Sun.COM 	uint32_t cmd;
228911304SJanie.Lu@Sun.COM 	rx_class_cfg_t *cfg_info = (rx_class_cfg_t *)mp->b_rptr;
229011304SJanie.Lu@Sun.COM 
229111304SJanie.Lu@Sun.COM 	if (nxgep == NULL) {
229211304SJanie.Lu@Sun.COM 		return (-1);
229311304SJanie.Lu@Sun.COM 	}
229411304SJanie.Lu@Sun.COM 	cmd = cfg_info->cmd;
229511304SJanie.Lu@Sun.COM 	switch (cmd) {
229611304SJanie.Lu@Sun.COM 	default:
229711304SJanie.Lu@Sun.COM 		return (-1);
229811304SJanie.Lu@Sun.COM 
229911304SJanie.Lu@Sun.COM 	case NXGE_RX_CLASS_GCHAN:
230011304SJanie.Lu@Sun.COM 		cfg_info->data = nxge_rxdma_channel_cnt(nxgep);
230111304SJanie.Lu@Sun.COM 		break;
230211304SJanie.Lu@Sun.COM 	case NXGE_RX_CLASS_GRULE_CNT:
230311304SJanie.Lu@Sun.COM 		MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
230411304SJanie.Lu@Sun.COM 		cfg_info->rule_cnt = nxge_get_valid_tcam_cnt(nxgep);
230511304SJanie.Lu@Sun.COM 		MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
230611304SJanie.Lu@Sun.COM 		break;
230711304SJanie.Lu@Sun.COM 	case NXGE_RX_CLASS_GRULE:
230811304SJanie.Lu@Sun.COM 		nxge_get_tcam_entry(nxgep, &cfg_info->fs);
230911304SJanie.Lu@Sun.COM 		break;
231011304SJanie.Lu@Sun.COM 	case NXGE_RX_CLASS_GRULE_ALL:
231111304SJanie.Lu@Sun.COM 		nxge_get_tcam_entry_all(nxgep, cfg_info);
231211304SJanie.Lu@Sun.COM 		break;
231311304SJanie.Lu@Sun.COM 	case NXGE_RX_CLASS_RULE_DEL:
231411304SJanie.Lu@Sun.COM 		nxge_del_tcam_entry(nxgep, cfg_info->fs.location);
231511304SJanie.Lu@Sun.COM 		break;
231611304SJanie.Lu@Sun.COM 	case NXGE_RX_CLASS_RULE_INS:
231711304SJanie.Lu@Sun.COM 		(void) nxge_add_tcam_entry(nxgep, &cfg_info->fs);
231811304SJanie.Lu@Sun.COM 		break;
231911304SJanie.Lu@Sun.COM 	}
232011304SJanie.Lu@Sun.COM 	return (0);
232111304SJanie.Lu@Sun.COM }
232211304SJanie.Lu@Sun.COM /* ARGSUSED */
232311304SJanie.Lu@Sun.COM int
nxge_rxhash_ioctl(p_nxge_t nxgep,queue_t * wq,mblk_t * mp)232411304SJanie.Lu@Sun.COM nxge_rxhash_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
232511304SJanie.Lu@Sun.COM {
232611304SJanie.Lu@Sun.COM 	uint32_t cmd;
232711304SJanie.Lu@Sun.COM 	cfg_cmd_t	*cfg_info = (cfg_cmd_t *)mp->b_rptr;
232811304SJanie.Lu@Sun.COM 
232911304SJanie.Lu@Sun.COM 	if (nxgep == NULL) {
233011304SJanie.Lu@Sun.COM 		return (-1);
233111304SJanie.Lu@Sun.COM 	}
233211304SJanie.Lu@Sun.COM 	cmd = cfg_info->cmd;
233311304SJanie.Lu@Sun.COM 
233411304SJanie.Lu@Sun.COM 	switch (cmd) {
233511304SJanie.Lu@Sun.COM 	default:
233611304SJanie.Lu@Sun.COM 		return (-1);
233711304SJanie.Lu@Sun.COM 	case NXGE_IPTUN_CFG_ADD_CLS:
233811304SJanie.Lu@Sun.COM 		nxge_add_iptun_class(nxgep, &cfg_info->iptun_cfg,
233911304SJanie.Lu@Sun.COM 		    &cfg_info->class_id);
234011304SJanie.Lu@Sun.COM 		break;
234111304SJanie.Lu@Sun.COM 	case NXGE_IPTUN_CFG_SET_HASH:
234211304SJanie.Lu@Sun.COM 		nxge_cfg_iptun_hash(nxgep, &cfg_info->iptun_cfg,
234311304SJanie.Lu@Sun.COM 		    cfg_info->class_id);
234411304SJanie.Lu@Sun.COM 		break;
234511304SJanie.Lu@Sun.COM 	case NXGE_IPTUN_CFG_DEL_CLS:
234611304SJanie.Lu@Sun.COM 		nxge_del_iptun_class(nxgep, cfg_info->class_id);
234711304SJanie.Lu@Sun.COM 		break;
234811304SJanie.Lu@Sun.COM 	case NXGE_IPTUN_CFG_GET_CLS:
234911304SJanie.Lu@Sun.COM 		nxge_get_iptun_class(nxgep, &cfg_info->iptun_cfg,
235011304SJanie.Lu@Sun.COM 		    cfg_info->class_id);
235111304SJanie.Lu@Sun.COM 		break;
235211304SJanie.Lu@Sun.COM 	case NXGE_CLS_CFG_SET_SYM:
235311304SJanie.Lu@Sun.COM 		nxge_set_ip_cls_sym(nxgep, cfg_info->class_id, cfg_info->sym);
235411304SJanie.Lu@Sun.COM 		break;
235511304SJanie.Lu@Sun.COM 	case NXGE_CLS_CFG_GET_SYM:
235611304SJanie.Lu@Sun.COM 		nxge_get_ip_cls_sym(nxgep, cfg_info->class_id, &cfg_info->sym);
235711304SJanie.Lu@Sun.COM 		break;
235811304SJanie.Lu@Sun.COM 	}
235911304SJanie.Lu@Sun.COM 	return (0);
236011304SJanie.Lu@Sun.COM }
236111304SJanie.Lu@Sun.COM 
236211304SJanie.Lu@Sun.COM void
nxge_get_tcam_entry_all(p_nxge_t nxgep,rx_class_cfg_t * cfgp)236311304SJanie.Lu@Sun.COM nxge_get_tcam_entry_all(p_nxge_t nxgep, rx_class_cfg_t *cfgp)
236411304SJanie.Lu@Sun.COM {
236511304SJanie.Lu@Sun.COM 	nxge_classify_t *clasp = &nxgep->classifier;
236611304SJanie.Lu@Sun.COM 	uint16_t	n_entries;
236711304SJanie.Lu@Sun.COM 	int		i, j, k;
236811304SJanie.Lu@Sun.COM 	tcam_flow_spec_t	*tcam_entryp;
236911304SJanie.Lu@Sun.COM 
237011304SJanie.Lu@Sun.COM 	cfgp->data = clasp->tcam_size;
237111304SJanie.Lu@Sun.COM 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
237211304SJanie.Lu@Sun.COM 	n_entries = cfgp->rule_cnt;
237311304SJanie.Lu@Sun.COM 
237411304SJanie.Lu@Sun.COM 	for (i = 0, j = 0; j < cfgp->data; j++) {
237511304SJanie.Lu@Sun.COM 		k = nxge_tcam_get_index(nxgep, j);
237611304SJanie.Lu@Sun.COM 		tcam_entryp = &clasp->tcam_entries[k];
237711304SJanie.Lu@Sun.COM 		if (tcam_entryp->valid != 1)
237811304SJanie.Lu@Sun.COM 			continue;
237911304SJanie.Lu@Sun.COM 		cfgp->rule_locs[i] = j;
238011304SJanie.Lu@Sun.COM 		i++;
238111304SJanie.Lu@Sun.COM 	};
238211304SJanie.Lu@Sun.COM 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
238311304SJanie.Lu@Sun.COM 
238411304SJanie.Lu@Sun.COM 	if (n_entries != i) {
238511304SJanie.Lu@Sun.COM 		/* print warning, this should not happen */
238611304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry_all"
238711304SJanie.Lu@Sun.COM 		    "n_entries[%d] != i[%d]!!!", n_entries, i));
238811304SJanie.Lu@Sun.COM 	}
238911304SJanie.Lu@Sun.COM }
239011304SJanie.Lu@Sun.COM 
239111304SJanie.Lu@Sun.COM 
239211304SJanie.Lu@Sun.COM /* Entries for the ports are interleaved in the TCAM */
239311304SJanie.Lu@Sun.COM static uint16_t
nxge_tcam_get_index(p_nxge_t nxgep,uint16_t index)239411304SJanie.Lu@Sun.COM nxge_tcam_get_index(p_nxge_t nxgep, uint16_t index)
239511304SJanie.Lu@Sun.COM {
239611304SJanie.Lu@Sun.COM 	/* One entry reserved for IP fragment rule */
239711304SJanie.Lu@Sun.COM 	if (index >= (nxgep->classifier.tcam_size - 1))
239811304SJanie.Lu@Sun.COM 		index = 0;
239911304SJanie.Lu@Sun.COM 	if (nxgep->classifier.fragment_bug == 1)
240011304SJanie.Lu@Sun.COM 		index++;
240111304SJanie.Lu@Sun.COM 	return (nxgep->classifier.tcam_top + (index * nxgep->nports));
240211304SJanie.Lu@Sun.COM }
240311304SJanie.Lu@Sun.COM 
240411304SJanie.Lu@Sun.COM static uint32_t
nxge_tcam_cls_to_flow(uint32_t class_code)240511304SJanie.Lu@Sun.COM nxge_tcam_cls_to_flow(uint32_t class_code) {
240611304SJanie.Lu@Sun.COM 	switch (class_code) {
240711304SJanie.Lu@Sun.COM 	case TCAM_CLASS_TCP_IPV4:
240811304SJanie.Lu@Sun.COM 		return (FSPEC_TCPIP4);
240911304SJanie.Lu@Sun.COM 	case TCAM_CLASS_UDP_IPV4:
241011304SJanie.Lu@Sun.COM 		return (FSPEC_UDPIP4);
241111304SJanie.Lu@Sun.COM 	case TCAM_CLASS_AH_ESP_IPV4:
241211304SJanie.Lu@Sun.COM 		return (FSPEC_AHIP4);
241311304SJanie.Lu@Sun.COM 	case TCAM_CLASS_SCTP_IPV4:
241411304SJanie.Lu@Sun.COM 		return (FSPEC_SCTPIP4);
241511304SJanie.Lu@Sun.COM 	case  TCAM_CLASS_TCP_IPV6:
241611304SJanie.Lu@Sun.COM 		return (FSPEC_TCPIP6);
241711304SJanie.Lu@Sun.COM 	case TCAM_CLASS_UDP_IPV6:
241811304SJanie.Lu@Sun.COM 		return (FSPEC_UDPIP6);
241911304SJanie.Lu@Sun.COM 	case TCAM_CLASS_AH_ESP_IPV6:
242011304SJanie.Lu@Sun.COM 		return (FSPEC_AHIP6);
242111304SJanie.Lu@Sun.COM 	case TCAM_CLASS_SCTP_IPV6:
242211304SJanie.Lu@Sun.COM 		return (FSPEC_SCTPIP6);
242311304SJanie.Lu@Sun.COM 	case TCAM_CLASS_IP_USER_4:
242411304SJanie.Lu@Sun.COM 	case TCAM_CLASS_IP_USER_5:
242511304SJanie.Lu@Sun.COM 	case TCAM_CLASS_IP_USER_6:
242611304SJanie.Lu@Sun.COM 	case TCAM_CLASS_IP_USER_7:
242711304SJanie.Lu@Sun.COM 		return (FSPEC_IP_USR);
242811304SJanie.Lu@Sun.COM 	default:
242911304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "nxge_tcam_cls_to_flow"
243011304SJanie.Lu@Sun.COM 		    ": Unknown class code [0x%x]", class_code));
243111304SJanie.Lu@Sun.COM 		break;
243211304SJanie.Lu@Sun.COM 	}
243311304SJanie.Lu@Sun.COM 	return (0);
243411304SJanie.Lu@Sun.COM }
243511304SJanie.Lu@Sun.COM 
243611304SJanie.Lu@Sun.COM void
nxge_get_tcam_entry(p_nxge_t nxgep,flow_resource_t * fs)243711304SJanie.Lu@Sun.COM nxge_get_tcam_entry(p_nxge_t nxgep, flow_resource_t *fs)
243811304SJanie.Lu@Sun.COM {
243911304SJanie.Lu@Sun.COM 	uint16_t 	index;
244011304SJanie.Lu@Sun.COM 	tcam_flow_spec_t *tcam_ep;
244111304SJanie.Lu@Sun.COM 	tcam_entry_t	*tp;
244211304SJanie.Lu@Sun.COM 	flow_spec_t	*fspec;
244311304SJanie.Lu@Sun.COM 	tcpip4_spec_t 	*fspec_key;
244411304SJanie.Lu@Sun.COM 	tcpip4_spec_t 	*fspec_mask;
244511304SJanie.Lu@Sun.COM 
244611304SJanie.Lu@Sun.COM 	index = nxge_tcam_get_index(nxgep, (uint16_t)fs->location);
244711304SJanie.Lu@Sun.COM 	tcam_ep = &nxgep->classifier.tcam_entries[index];
244811304SJanie.Lu@Sun.COM 	if (tcam_ep->valid != 1) {
244911304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry: :"
245011304SJanie.Lu@Sun.COM 		    "Entry [%d] invalid for index [%d]", fs->location, index));
245111304SJanie.Lu@Sun.COM 		return;
245211304SJanie.Lu@Sun.COM 	}
245311304SJanie.Lu@Sun.COM 
245411304SJanie.Lu@Sun.COM 	/* Fill the flow spec entry */
245511304SJanie.Lu@Sun.COM 	tp = &tcam_ep->tce;
245611304SJanie.Lu@Sun.COM 	fspec = &fs->flow_spec;
245711304SJanie.Lu@Sun.COM 	fspec->flow_type = nxge_tcam_cls_to_flow(tp->ip4_class_key);
245811304SJanie.Lu@Sun.COM 
245911304SJanie.Lu@Sun.COM 	/* TODO - look at proto field to differentiate between AH and ESP */
246011304SJanie.Lu@Sun.COM 	if (fspec->flow_type == FSPEC_AHIP4) {
246111304SJanie.Lu@Sun.COM 		if (tp->ip4_proto_key == IPPROTO_ESP)
246211304SJanie.Lu@Sun.COM 			fspec->flow_type = FSPEC_ESPIP4;
246311304SJanie.Lu@Sun.COM 	}
246411304SJanie.Lu@Sun.COM 
246511304SJanie.Lu@Sun.COM 	switch (tp->ip4_class_key) {
246611304SJanie.Lu@Sun.COM 	case TCAM_CLASS_TCP_IPV4:
246711304SJanie.Lu@Sun.COM 	case TCAM_CLASS_UDP_IPV4:
246811304SJanie.Lu@Sun.COM 	case TCAM_CLASS_AH_ESP_IPV4:
246911304SJanie.Lu@Sun.COM 	case TCAM_CLASS_SCTP_IPV4:
247011304SJanie.Lu@Sun.COM 		fspec_key = (tcpip4_spec_t *)&fspec->uh.tcpip4spec;
247111304SJanie.Lu@Sun.COM 		fspec_mask = (tcpip4_spec_t *)&fspec->um.tcpip4spec;
247211304SJanie.Lu@Sun.COM 		FSPEC_IPV4_ADDR(fspec_key->ip4dst, tp->ip4_dest_key);
247311304SJanie.Lu@Sun.COM 		FSPEC_IPV4_ADDR(fspec_mask->ip4dst, tp->ip4_dest_mask);
247411304SJanie.Lu@Sun.COM 		FSPEC_IPV4_ADDR(fspec_key->ip4src, tp->ip4_src_key);
247511304SJanie.Lu@Sun.COM 		FSPEC_IPV4_ADDR(fspec_mask->ip4src, tp->ip4_src_mask);
247611304SJanie.Lu@Sun.COM 		fspec_key->tos = tp->ip4_tos_key;
247711304SJanie.Lu@Sun.COM 		fspec_mask->tos = tp->ip4_tos_mask;
247811304SJanie.Lu@Sun.COM 		break;
247911304SJanie.Lu@Sun.COM 	default:
248011304SJanie.Lu@Sun.COM 		break;
248111304SJanie.Lu@Sun.COM 	}
248211304SJanie.Lu@Sun.COM 
248311304SJanie.Lu@Sun.COM 	switch (tp->ip4_class_key) {
248411304SJanie.Lu@Sun.COM 	case TCAM_CLASS_TCP_IPV4:
248511304SJanie.Lu@Sun.COM 	case TCAM_CLASS_UDP_IPV4:
248611304SJanie.Lu@Sun.COM 	case TCAM_CLASS_SCTP_IPV4:
248711304SJanie.Lu@Sun.COM 		FSPEC_IP_PORTS(fspec_key->pdst, fspec_key->psrc,
248811304SJanie.Lu@Sun.COM 		    tp->ip4_port_key);
248911304SJanie.Lu@Sun.COM 		FSPEC_IP_PORTS(fspec_mask->pdst, fspec_mask->psrc,
249011304SJanie.Lu@Sun.COM 		    tp->ip4_port_mask);
249111304SJanie.Lu@Sun.COM 		break;
249211304SJanie.Lu@Sun.COM 	case TCAM_CLASS_AH_ESP_IPV4:
249311304SJanie.Lu@Sun.COM 		fspec->uh.ahip4spec.spi = tp->ip4_port_key;
249411304SJanie.Lu@Sun.COM 		fspec->um.ahip4spec.spi = tp->ip4_port_mask;
249511304SJanie.Lu@Sun.COM 		break;
249611304SJanie.Lu@Sun.COM 	case TCAM_CLASS_IP_USER_4:
249711304SJanie.Lu@Sun.COM 	case TCAM_CLASS_IP_USER_5:
249811304SJanie.Lu@Sun.COM 	case TCAM_CLASS_IP_USER_6:
249911304SJanie.Lu@Sun.COM 	case TCAM_CLASS_IP_USER_7:
250011304SJanie.Lu@Sun.COM 		fspec->uh.ip_usr_spec.l4_4_bytes = tp->ip4_port_key;
250111304SJanie.Lu@Sun.COM 		fspec->um.ip_usr_spec.l4_4_bytes = tp->ip4_port_mask;
250211304SJanie.Lu@Sun.COM 		fspec->uh.ip_usr_spec.ip_ver = FSPEC_IP4;
250311304SJanie.Lu@Sun.COM 		fspec->uh.ip_usr_spec.proto = tp->ip4_proto_key;
250411304SJanie.Lu@Sun.COM 		fspec->um.ip_usr_spec.proto = tp->ip4_proto_mask;
250511304SJanie.Lu@Sun.COM 		break;
250611304SJanie.Lu@Sun.COM 	default:
250711304SJanie.Lu@Sun.COM 		break;
250811304SJanie.Lu@Sun.COM 	}
250911304SJanie.Lu@Sun.COM 
251011304SJanie.Lu@Sun.COM 	if (tp->match_action.bits.ldw.disc == 1) {
251111304SJanie.Lu@Sun.COM 		fs->channel_cookie = NXGE_PKT_DISCARD;
251211304SJanie.Lu@Sun.COM 	} else {
251311304SJanie.Lu@Sun.COM 		fs->channel_cookie = tp->match_action.bits.ldw.offset;
251411304SJanie.Lu@Sun.COM 	}
251511304SJanie.Lu@Sun.COM }
251611304SJanie.Lu@Sun.COM 
251711304SJanie.Lu@Sun.COM void
nxge_del_tcam_entry(p_nxge_t nxgep,uint32_t location)251811304SJanie.Lu@Sun.COM nxge_del_tcam_entry(p_nxge_t nxgep, uint32_t location)
251911304SJanie.Lu@Sun.COM {
252011304SJanie.Lu@Sun.COM 	npi_status_t rs = NPI_SUCCESS;
252111304SJanie.Lu@Sun.COM 	uint16_t 	index;
252211304SJanie.Lu@Sun.COM 	tcam_flow_spec_t *tcam_ep;
252311304SJanie.Lu@Sun.COM 	tcam_entry_t	*tp;
252411304SJanie.Lu@Sun.COM 	tcam_class_t	class;
252511304SJanie.Lu@Sun.COM 
252611304SJanie.Lu@Sun.COM 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
252711304SJanie.Lu@Sun.COM 	index = nxge_tcam_get_index(nxgep, (uint16_t)location);
252811304SJanie.Lu@Sun.COM 	tcam_ep = &nxgep->classifier.tcam_entries[index];
252911304SJanie.Lu@Sun.COM 	if (tcam_ep->valid != 1) {
253011304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_tcam_entry: :"
253111304SJanie.Lu@Sun.COM 		    "Entry [%d] invalid for index [%d]", location, index));
253211304SJanie.Lu@Sun.COM 		goto fail;
253311304SJanie.Lu@Sun.COM 	}
253411304SJanie.Lu@Sun.COM 
253511304SJanie.Lu@Sun.COM 	/* Fill the flow spec entry */
253611304SJanie.Lu@Sun.COM 	tp = &tcam_ep->tce;
253711304SJanie.Lu@Sun.COM 	class = tp->ip4_class_key;
253811304SJanie.Lu@Sun.COM 	if (class >= TCAM_CLASS_IP_USER_4 && class <= TCAM_CLASS_IP_USER_7) {
253911304SJanie.Lu@Sun.COM 		int i;
254011304SJanie.Lu@Sun.COM 		nxge_usr_l3_cls_t *l3_ucls_p;
254111304SJanie.Lu@Sun.COM 		p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
254211304SJanie.Lu@Sun.COM 
254311304SJanie.Lu@Sun.COM 		for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
254411304SJanie.Lu@Sun.COM 			l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
254511304SJanie.Lu@Sun.COM 			if (l3_ucls_p->valid) {
254611304SJanie.Lu@Sun.COM 				if (l3_ucls_p->cls == class &&
254711304SJanie.Lu@Sun.COM 				    l3_ucls_p->tcam_ref_cnt) {
254811304SJanie.Lu@Sun.COM 					l3_ucls_p->tcam_ref_cnt--;
254911304SJanie.Lu@Sun.COM 					if (l3_ucls_p->tcam_ref_cnt > 0)
255011304SJanie.Lu@Sun.COM 						continue;
255111304SJanie.Lu@Sun.COM 					/* disable class */
255211304SJanie.Lu@Sun.COM 					rs = npi_fflp_cfg_ip_usr_cls_disable(
255311304SJanie.Lu@Sun.COM 					    nxgep->npi_reg_handle,
255411304SJanie.Lu@Sun.COM 					    (tcam_class_t)class);
255511304SJanie.Lu@Sun.COM 					if (rs != NPI_SUCCESS)
255611304SJanie.Lu@Sun.COM 						goto fail;
255711304SJanie.Lu@Sun.COM 					l3_ucls_p->cls = 0;
255811304SJanie.Lu@Sun.COM 					l3_ucls_p->pid = 0;
255911304SJanie.Lu@Sun.COM 					l3_ucls_p->valid = 0;
256011304SJanie.Lu@Sun.COM 					break;
256111304SJanie.Lu@Sun.COM 				}
256211304SJanie.Lu@Sun.COM 			}
256311304SJanie.Lu@Sun.COM 		}
256411304SJanie.Lu@Sun.COM 		if (i == NXGE_L3_PROG_CLS) {
256511304SJanie.Lu@Sun.COM 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
256611304SJanie.Lu@Sun.COM 			    "nxge_del_tcam_entry: Usr class "
256711304SJanie.Lu@Sun.COM 			    "0x%llx not found", (unsigned long long) class));
256811304SJanie.Lu@Sun.COM 			goto fail;
256911304SJanie.Lu@Sun.COM 		}
257011304SJanie.Lu@Sun.COM 	}
257111304SJanie.Lu@Sun.COM 
257211304SJanie.Lu@Sun.COM 	rs = npi_fflp_tcam_entry_invalidate(nxgep->npi_reg_handle, index);
257311304SJanie.Lu@Sun.COM 	if (rs != NPI_SUCCESS) {
257411304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
257511304SJanie.Lu@Sun.COM 		    "nxge_del_tcam_entry: TCAM invalidate failed "
257611304SJanie.Lu@Sun.COM 		    "at loc %d ", location));
257711304SJanie.Lu@Sun.COM 		goto fail;
257811304SJanie.Lu@Sun.COM 	}
257911304SJanie.Lu@Sun.COM 
258011304SJanie.Lu@Sun.COM 	nxgep->classifier.tcam_entries[index].valid = 0;
258111304SJanie.Lu@Sun.COM 	nxgep->classifier.tcam_entry_cnt--;
258211304SJanie.Lu@Sun.COM 
258311304SJanie.Lu@Sun.COM 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
258411304SJanie.Lu@Sun.COM 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_del_tcam_entry"));
258511304SJanie.Lu@Sun.COM 	return;
258611304SJanie.Lu@Sun.COM fail:
258711304SJanie.Lu@Sun.COM 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
258811304SJanie.Lu@Sun.COM 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
258911304SJanie.Lu@Sun.COM 	    "<== nxge_del_tcam_entry FAILED"));
259011304SJanie.Lu@Sun.COM }
259111304SJanie.Lu@Sun.COM 
259211304SJanie.Lu@Sun.COM static uint8_t
nxge_iptun_pkt_type_to_pid(uint8_t pkt_type)259311304SJanie.Lu@Sun.COM nxge_iptun_pkt_type_to_pid(uint8_t pkt_type)
259411304SJanie.Lu@Sun.COM {
259511304SJanie.Lu@Sun.COM 	uint8_t pid = 0;
259611304SJanie.Lu@Sun.COM 
259711304SJanie.Lu@Sun.COM 	switch (pkt_type) {
259811304SJanie.Lu@Sun.COM 	case IPTUN_PKT_IPV4:
259911304SJanie.Lu@Sun.COM 		pid = 4;
260011304SJanie.Lu@Sun.COM 		break;
260111304SJanie.Lu@Sun.COM 	case IPTUN_PKT_IPV6:
260211304SJanie.Lu@Sun.COM 		pid = 41;
260311304SJanie.Lu@Sun.COM 		break;
260411304SJanie.Lu@Sun.COM 	case IPTUN_PKT_GRE:
260511304SJanie.Lu@Sun.COM 		pid = 47;
260611304SJanie.Lu@Sun.COM 		break;
260711304SJanie.Lu@Sun.COM 	case IPTUN_PKT_GTP:
260811304SJanie.Lu@Sun.COM 		pid = 17;
260911304SJanie.Lu@Sun.COM 		break;
261011304SJanie.Lu@Sun.COM 	default:
261111304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
261211304SJanie.Lu@Sun.COM 		    "nxge_iptun_pkt_type_to_pid: Unknown pkt type 0x%x",
261311304SJanie.Lu@Sun.COM 		    pkt_type));
261411304SJanie.Lu@Sun.COM 		break;
261511304SJanie.Lu@Sun.COM 	}
261611304SJanie.Lu@Sun.COM 
261711304SJanie.Lu@Sun.COM 	return (pid);
261811304SJanie.Lu@Sun.COM }
261911304SJanie.Lu@Sun.COM 
262011304SJanie.Lu@Sun.COM static npi_status_t
nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep,uint64_t class,iptun_cfg_t * iptunp)262111304SJanie.Lu@Sun.COM nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep, uint64_t class,
262211304SJanie.Lu@Sun.COM 		iptun_cfg_t *iptunp)
262311304SJanie.Lu@Sun.COM {
262411304SJanie.Lu@Sun.COM 	npi_handle_t handle = nxgep->npi_reg_handle;
262511304SJanie.Lu@Sun.COM 	npi_status_t rs = NPI_SUCCESS;
262611304SJanie.Lu@Sun.COM 
262711304SJanie.Lu@Sun.COM 	switch (iptunp->in_pkt_type) {
262811304SJanie.Lu@Sun.COM 	case IPTUN_PKT_IPV4:
262911304SJanie.Lu@Sun.COM 	case IPTUN_PKT_IPV6:
263011304SJanie.Lu@Sun.COM 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
263111304SJanie.Lu@Sun.COM 		    (tcam_class_t)class, 0, 0, 0, 0);
263211304SJanie.Lu@Sun.COM 		break;
263311304SJanie.Lu@Sun.COM 	case IPTUN_PKT_GRE:
263411304SJanie.Lu@Sun.COM 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
263511304SJanie.Lu@Sun.COM 		    (tcam_class_t)class, iptunp->l4b0_val,
263611304SJanie.Lu@Sun.COM 		    iptunp->l4b0_mask, 0, 0);
263711304SJanie.Lu@Sun.COM 		break;
263811304SJanie.Lu@Sun.COM 	case IPTUN_PKT_GTP:
263911304SJanie.Lu@Sun.COM 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
264011304SJanie.Lu@Sun.COM 		    (tcam_class_t)class, 0, 0, iptunp->l4b23_val,
264111304SJanie.Lu@Sun.COM 		    (iptunp->l4b23_sel & 0x01));
264211304SJanie.Lu@Sun.COM 		break;
264311304SJanie.Lu@Sun.COM 	default:
264411304SJanie.Lu@Sun.COM 		rs = NPI_FFLP_TCAM_CLASS_INVALID;
264511304SJanie.Lu@Sun.COM 		break;
264611304SJanie.Lu@Sun.COM 	}
264711304SJanie.Lu@Sun.COM 	return (rs);
264811304SJanie.Lu@Sun.COM }
264911304SJanie.Lu@Sun.COM 
265011304SJanie.Lu@Sun.COM void
nxge_add_iptun_class(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t * cls_idp)265111304SJanie.Lu@Sun.COM nxge_add_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp,
265211304SJanie.Lu@Sun.COM 		uint8_t *cls_idp)
265311304SJanie.Lu@Sun.COM {
265411304SJanie.Lu@Sun.COM 	int i, add_cls;
265511304SJanie.Lu@Sun.COM 	uint8_t pid;
265611304SJanie.Lu@Sun.COM 	uint64_t class;
265711304SJanie.Lu@Sun.COM 	p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
265811304SJanie.Lu@Sun.COM 	npi_handle_t handle = nxgep->npi_reg_handle;
265911304SJanie.Lu@Sun.COM 	npi_status_t rs = NPI_SUCCESS;
266011304SJanie.Lu@Sun.COM 
266111304SJanie.Lu@Sun.COM 	pid = nxge_iptun_pkt_type_to_pid(iptunp->in_pkt_type);
266211304SJanie.Lu@Sun.COM 	if (pid == 0)
266311304SJanie.Lu@Sun.COM 		return;
266411304SJanie.Lu@Sun.COM 
266511304SJanie.Lu@Sun.COM 	add_cls = 0;
266611304SJanie.Lu@Sun.COM 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
266711304SJanie.Lu@Sun.COM 
266811304SJanie.Lu@Sun.COM 	/* Get an user programmable class ID */
266911304SJanie.Lu@Sun.COM 	for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
267011304SJanie.Lu@Sun.COM 		if (hw_p->tcam_l3_prog_cls[i].valid == 0) {
267111304SJanie.Lu@Sun.COM 			/* todo add new usr class reg */
267211304SJanie.Lu@Sun.COM 			switch (i) {
267311304SJanie.Lu@Sun.COM 			case 0:
267411304SJanie.Lu@Sun.COM 				class = TCAM_CLASS_IP_USER_4;
267511304SJanie.Lu@Sun.COM 				break;
267611304SJanie.Lu@Sun.COM 			case 1:
267711304SJanie.Lu@Sun.COM 				class = TCAM_CLASS_IP_USER_5;
267811304SJanie.Lu@Sun.COM 				break;
267911304SJanie.Lu@Sun.COM 			case 2:
268011304SJanie.Lu@Sun.COM 				class = TCAM_CLASS_IP_USER_6;
268111304SJanie.Lu@Sun.COM 				break;
268211304SJanie.Lu@Sun.COM 			case 3:
268311304SJanie.Lu@Sun.COM 				class = TCAM_CLASS_IP_USER_7;
268411304SJanie.Lu@Sun.COM 				break;
268511304SJanie.Lu@Sun.COM 			default:
268611304SJanie.Lu@Sun.COM 				break;
268711304SJanie.Lu@Sun.COM 			}
268811304SJanie.Lu@Sun.COM 			rs = npi_fflp_cfg_ip_usr_cls_set(handle,
268911304SJanie.Lu@Sun.COM 			    (tcam_class_t)class, 0, 0, pid, 0);
269011304SJanie.Lu@Sun.COM 			if (rs != NPI_SUCCESS)
269111304SJanie.Lu@Sun.COM 				goto fail;
269211304SJanie.Lu@Sun.COM 
269311304SJanie.Lu@Sun.COM 			rs = nxge_set_iptun_usr_cls_reg(nxgep, class, iptunp);
269411304SJanie.Lu@Sun.COM 
269511304SJanie.Lu@Sun.COM 			if (rs != NPI_SUCCESS)
269611304SJanie.Lu@Sun.COM 				goto fail;
269711304SJanie.Lu@Sun.COM 
269811304SJanie.Lu@Sun.COM 			rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
269911304SJanie.Lu@Sun.COM 			    (tcam_class_t)class);
270011304SJanie.Lu@Sun.COM 			if (rs != NPI_SUCCESS)
270111304SJanie.Lu@Sun.COM 				goto fail;
270211304SJanie.Lu@Sun.COM 
270311304SJanie.Lu@Sun.COM 			hw_p->tcam_l3_prog_cls[i].cls = class;
270411304SJanie.Lu@Sun.COM 			hw_p->tcam_l3_prog_cls[i].pid = pid;
270511304SJanie.Lu@Sun.COM 			hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
270611304SJanie.Lu@Sun.COM 			    iptunp->in_pkt_type;
270711304SJanie.Lu@Sun.COM 			hw_p->tcam_l3_prog_cls[i].valid = 1;
270811304SJanie.Lu@Sun.COM 			*cls_idp = (uint8_t)class;
270911304SJanie.Lu@Sun.COM 			add_cls = 1;
271011304SJanie.Lu@Sun.COM 			break;
271111304SJanie.Lu@Sun.COM 		} else if (hw_p->tcam_l3_prog_cls[i].pid == pid) {
271211304SJanie.Lu@Sun.COM 			if (hw_p->tcam_l3_prog_cls[i].flow_pkt_type == 0) {
271311304SJanie.Lu@Sun.COM 				/* there is no flow key */
271411304SJanie.Lu@Sun.COM 				/* todo program the existing usr class reg */
271511304SJanie.Lu@Sun.COM 
271611304SJanie.Lu@Sun.COM 				rs = nxge_set_iptun_usr_cls_reg(nxgep, class,
271711304SJanie.Lu@Sun.COM 				    iptunp);
271811304SJanie.Lu@Sun.COM 				if (rs != NPI_SUCCESS)
271911304SJanie.Lu@Sun.COM 					goto fail;
272011304SJanie.Lu@Sun.COM 
272111304SJanie.Lu@Sun.COM 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
272211304SJanie.Lu@Sun.COM 				    (tcam_class_t)class);
272311304SJanie.Lu@Sun.COM 				if (rs != NPI_SUCCESS)
272411304SJanie.Lu@Sun.COM 					goto fail;
272511304SJanie.Lu@Sun.COM 
272611304SJanie.Lu@Sun.COM 				hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
272711304SJanie.Lu@Sun.COM 				    iptunp->in_pkt_type;
272811304SJanie.Lu@Sun.COM 				*cls_idp = (uint8_t)class;
272911304SJanie.Lu@Sun.COM 				add_cls = 1;
273011304SJanie.Lu@Sun.COM 			} else {
273111304SJanie.Lu@Sun.COM 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
273211304SJanie.Lu@Sun.COM 				    "nxge_add_iptun_class: L3 usr "
273311304SJanie.Lu@Sun.COM 				    "programmable class with pid %d "
273411304SJanie.Lu@Sun.COM 				    "already exists", pid));
273511304SJanie.Lu@Sun.COM 			}
273611304SJanie.Lu@Sun.COM 			break;
273711304SJanie.Lu@Sun.COM 		}
273811304SJanie.Lu@Sun.COM 	}
273911304SJanie.Lu@Sun.COM 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
274011304SJanie.Lu@Sun.COM 
274111304SJanie.Lu@Sun.COM 	if (add_cls != 1) {
274211304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
274311304SJanie.Lu@Sun.COM 		    "nxge_add_iptun_class: Could not add IP tunneling class"));
274411304SJanie.Lu@Sun.COM 	}
274511304SJanie.Lu@Sun.COM 	return;
274611304SJanie.Lu@Sun.COM fail:
274711304SJanie.Lu@Sun.COM 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
274811304SJanie.Lu@Sun.COM 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_iptun_class: FAILED"));
274911304SJanie.Lu@Sun.COM }
275011304SJanie.Lu@Sun.COM 
275111304SJanie.Lu@Sun.COM static boolean_t
nxge_is_iptun_cls_present(p_nxge_t nxgep,uint8_t cls_id,int * idx)275211304SJanie.Lu@Sun.COM nxge_is_iptun_cls_present(p_nxge_t nxgep, uint8_t cls_id, int *idx)
275311304SJanie.Lu@Sun.COM {
275411304SJanie.Lu@Sun.COM 	int i;
275511304SJanie.Lu@Sun.COM 	p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
275611304SJanie.Lu@Sun.COM 
275711304SJanie.Lu@Sun.COM 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
275811304SJanie.Lu@Sun.COM 	for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
275911304SJanie.Lu@Sun.COM 		if (hw_p->tcam_l3_prog_cls[i].valid &&
276011304SJanie.Lu@Sun.COM 		    hw_p->tcam_l3_prog_cls[i].flow_pkt_type != 0) {
276111304SJanie.Lu@Sun.COM 			if (hw_p->tcam_l3_prog_cls[i].cls == cls_id)
276211304SJanie.Lu@Sun.COM 				break;
276311304SJanie.Lu@Sun.COM 		}
276411304SJanie.Lu@Sun.COM 	}
276511304SJanie.Lu@Sun.COM 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
276611304SJanie.Lu@Sun.COM 
276711304SJanie.Lu@Sun.COM 	if (i == NXGE_L3_PROG_CLS) {
276811304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
276911304SJanie.Lu@Sun.COM 		    "nxge_is_iptun_cls_present: Invalid class %d", cls_id));
277011304SJanie.Lu@Sun.COM 		return (B_FALSE);
277111304SJanie.Lu@Sun.COM 	} else {
277211304SJanie.Lu@Sun.COM 		*idx = i;
277311304SJanie.Lu@Sun.COM 		return (B_TRUE);
277411304SJanie.Lu@Sun.COM 	}
277511304SJanie.Lu@Sun.COM }
277611304SJanie.Lu@Sun.COM 
277711304SJanie.Lu@Sun.COM void
nxge_cfg_iptun_hash(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t cls_id)277811304SJanie.Lu@Sun.COM nxge_cfg_iptun_hash(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
277911304SJanie.Lu@Sun.COM {
278011304SJanie.Lu@Sun.COM 	int idx;
278111304SJanie.Lu@Sun.COM 	npi_handle_t handle = nxgep->npi_reg_handle;
278211304SJanie.Lu@Sun.COM 	flow_key_cfg_t cfg;
278311304SJanie.Lu@Sun.COM 
278411304SJanie.Lu@Sun.COM 	/* check to see that this is a valid class ID */
278511304SJanie.Lu@Sun.COM 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &idx)) {
278611304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
278711304SJanie.Lu@Sun.COM 		    "nxge_cfg_iptun_hash: nxge_is_iptun_cls_present "
278811304SJanie.Lu@Sun.COM 		    "failed for cls_id %d", cls_id));
278911304SJanie.Lu@Sun.COM 		return;
279011304SJanie.Lu@Sun.COM 	}
279111304SJanie.Lu@Sun.COM 
279211304SJanie.Lu@Sun.COM 	bzero((void *)&cfg, sizeof (flow_key_cfg_t));
279311304SJanie.Lu@Sun.COM 
279411304SJanie.Lu@Sun.COM 	/*
279511304SJanie.Lu@Sun.COM 	 * This ensures that all 4 bytes of the XOR value are loaded to the
279611304SJanie.Lu@Sun.COM 	 * hash key.
279711304SJanie.Lu@Sun.COM 	 */
279811304SJanie.Lu@Sun.COM 	cfg.use_dport = cfg.use_sport = cfg.ip_opts_exist = 1;
279911304SJanie.Lu@Sun.COM 
280011304SJanie.Lu@Sun.COM 	cfg.l4_xor_sel = (iptunp->l4xor_sel & FL_KEY_USR_L4XOR_MSK);
280111304SJanie.Lu@Sun.COM 	cfg.use_l4_md = 1;
280211304SJanie.Lu@Sun.COM 
280311304SJanie.Lu@Sun.COM 	if (iptunp->hash_flags & HASH_L3PROTO)
280411304SJanie.Lu@Sun.COM 		cfg.use_proto = 1;
280511304SJanie.Lu@Sun.COM 	else if (iptunp->hash_flags & HASH_IPDA)
280611304SJanie.Lu@Sun.COM 		cfg.use_daddr = 1;
280711304SJanie.Lu@Sun.COM 	else if (iptunp->hash_flags & HASH_IPSA)
280811304SJanie.Lu@Sun.COM 		cfg.use_saddr = 1;
280911304SJanie.Lu@Sun.COM 	else if (iptunp->hash_flags & HASH_VLAN)
281011304SJanie.Lu@Sun.COM 		cfg.use_vlan = 1;
281111304SJanie.Lu@Sun.COM 	else if (iptunp->hash_flags & HASH_L2DA)
281211304SJanie.Lu@Sun.COM 		cfg.use_l2da = 1;
281311304SJanie.Lu@Sun.COM 	else if (iptunp->hash_flags & HASH_IFPORT)
281411304SJanie.Lu@Sun.COM 		cfg.use_portnum = 1;
281511304SJanie.Lu@Sun.COM 
281611304SJanie.Lu@Sun.COM 	(void) npi_fflp_cfg_ip_cls_flow_key_rfnl(handle, (tcam_class_t)cls_id,
281711304SJanie.Lu@Sun.COM 	    &cfg);
281811304SJanie.Lu@Sun.COM }
281911304SJanie.Lu@Sun.COM 
282011304SJanie.Lu@Sun.COM void
nxge_del_iptun_class(p_nxge_t nxgep,uint8_t cls_id)282111304SJanie.Lu@Sun.COM nxge_del_iptun_class(p_nxge_t nxgep, uint8_t cls_id)
282211304SJanie.Lu@Sun.COM {
282311304SJanie.Lu@Sun.COM 	int i;
282411304SJanie.Lu@Sun.COM 	npi_handle_t handle = nxgep->npi_reg_handle;
282511304SJanie.Lu@Sun.COM 	npi_status_t rs = NPI_SUCCESS;
282611304SJanie.Lu@Sun.COM 
282711304SJanie.Lu@Sun.COM 
282811304SJanie.Lu@Sun.COM 	/* check to see that this is a valid class ID */
282911304SJanie.Lu@Sun.COM 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) {
283011304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
283111304SJanie.Lu@Sun.COM 		    "nxge_del_iptun_class: Invalid class ID 0x%x", cls_id));
283211304SJanie.Lu@Sun.COM 		return;
283311304SJanie.Lu@Sun.COM 	}
283411304SJanie.Lu@Sun.COM 
283511304SJanie.Lu@Sun.COM 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
283611304SJanie.Lu@Sun.COM 	rs = npi_fflp_cfg_ip_usr_cls_disable(handle, (tcam_class_t)cls_id);
283711304SJanie.Lu@Sun.COM 	if (rs != NPI_SUCCESS)
283811304SJanie.Lu@Sun.COM 		goto fail;
283911304SJanie.Lu@Sun.COM 	nxgep->nxge_hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 0;
284011304SJanie.Lu@Sun.COM 	if (nxgep->nxge_hw_p->tcam_l3_prog_cls[i].tcam_ref_cnt == 0)
284111304SJanie.Lu@Sun.COM 		nxgep->nxge_hw_p->tcam_l3_prog_cls[i].valid = 0;
284211304SJanie.Lu@Sun.COM 
284311304SJanie.Lu@Sun.COM 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
284411304SJanie.Lu@Sun.COM 	return;
284511304SJanie.Lu@Sun.COM fail:
284611304SJanie.Lu@Sun.COM 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
284711304SJanie.Lu@Sun.COM 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_iptun_class: FAILED"));
284811304SJanie.Lu@Sun.COM }
284911304SJanie.Lu@Sun.COM 
285011304SJanie.Lu@Sun.COM void
nxge_get_iptun_class(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t cls_id)285111304SJanie.Lu@Sun.COM nxge_get_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
285211304SJanie.Lu@Sun.COM {
285311304SJanie.Lu@Sun.COM 	int i;
285411304SJanie.Lu@Sun.COM 	uint8_t pid;
285511304SJanie.Lu@Sun.COM 	npi_handle_t handle = nxgep->npi_reg_handle;
285611304SJanie.Lu@Sun.COM 	npi_status_t rs = NPI_SUCCESS;
285711304SJanie.Lu@Sun.COM 	flow_key_cfg_t cfg;
285811304SJanie.Lu@Sun.COM 
285911304SJanie.Lu@Sun.COM 
286011304SJanie.Lu@Sun.COM 	/* check to see that this is a valid class ID */
286111304SJanie.Lu@Sun.COM 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i))
286211304SJanie.Lu@Sun.COM 		return;
286311304SJanie.Lu@Sun.COM 
286411304SJanie.Lu@Sun.COM 	bzero((void *)iptunp, sizeof (iptun_cfg_t));
286511304SJanie.Lu@Sun.COM 
286611304SJanie.Lu@Sun.COM 	pid = nxgep->nxge_hw_p->tcam_l3_prog_cls[i].pid;
286711304SJanie.Lu@Sun.COM 
286811304SJanie.Lu@Sun.COM 	rs = npi_fflp_cfg_ip_usr_cls_get_iptun(handle, (tcam_class_t)cls_id,
286911304SJanie.Lu@Sun.COM 	    &iptunp->l4b0_val, &iptunp->l4b0_mask, &iptunp->l4b23_val,
287011304SJanie.Lu@Sun.COM 	    &iptunp->l4b23_sel);
287111304SJanie.Lu@Sun.COM 	if (rs != NPI_SUCCESS)
287211304SJanie.Lu@Sun.COM 		goto fail;
287311304SJanie.Lu@Sun.COM 
287411304SJanie.Lu@Sun.COM 	rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
287511304SJanie.Lu@Sun.COM 	    (tcam_class_t)cls_id, &cfg);
287611304SJanie.Lu@Sun.COM 	if (rs != NPI_SUCCESS)
287711304SJanie.Lu@Sun.COM 		goto fail;
287811304SJanie.Lu@Sun.COM 
287911304SJanie.Lu@Sun.COM 	iptunp->l4xor_sel = cfg.l4_xor_sel;
288011304SJanie.Lu@Sun.COM 	if (cfg.use_proto)
288111304SJanie.Lu@Sun.COM 		iptunp->hash_flags |= HASH_L3PROTO;
288211304SJanie.Lu@Sun.COM 	else if (cfg.use_daddr)
288311304SJanie.Lu@Sun.COM 		iptunp->hash_flags |= HASH_IPDA;
288411304SJanie.Lu@Sun.COM 	else if (cfg.use_saddr)
288511304SJanie.Lu@Sun.COM 		iptunp->hash_flags |= HASH_IPSA;
288611304SJanie.Lu@Sun.COM 	else if (cfg.use_vlan)
288711304SJanie.Lu@Sun.COM 		iptunp->hash_flags |= HASH_VLAN;
288811304SJanie.Lu@Sun.COM 	else if (cfg.use_l2da)
288911304SJanie.Lu@Sun.COM 		iptunp->hash_flags |= HASH_L2DA;
289011304SJanie.Lu@Sun.COM 	else if (cfg.use_portnum)
289111304SJanie.Lu@Sun.COM 		iptunp->hash_flags |= HASH_IFPORT;
289211304SJanie.Lu@Sun.COM 
289311304SJanie.Lu@Sun.COM 	switch (pid) {
289411304SJanie.Lu@Sun.COM 	case 4:
289511304SJanie.Lu@Sun.COM 		iptunp->in_pkt_type = IPTUN_PKT_IPV4;
289611304SJanie.Lu@Sun.COM 		break;
289711304SJanie.Lu@Sun.COM 	case 41:
289811304SJanie.Lu@Sun.COM 		iptunp->in_pkt_type = IPTUN_PKT_IPV6;
289911304SJanie.Lu@Sun.COM 		break;
290011304SJanie.Lu@Sun.COM 	case 47:
290111304SJanie.Lu@Sun.COM 		iptunp->in_pkt_type = IPTUN_PKT_GRE;
290211304SJanie.Lu@Sun.COM 		break;
290311304SJanie.Lu@Sun.COM 	case 17:
290411304SJanie.Lu@Sun.COM 		iptunp->in_pkt_type = IPTUN_PKT_GTP;
290511304SJanie.Lu@Sun.COM 		break;
290611304SJanie.Lu@Sun.COM 	default:
290711304SJanie.Lu@Sun.COM 		iptunp->in_pkt_type = 0;
290811304SJanie.Lu@Sun.COM 		break;
290911304SJanie.Lu@Sun.COM 	}
291011304SJanie.Lu@Sun.COM 
291111304SJanie.Lu@Sun.COM 	return;
291211304SJanie.Lu@Sun.COM fail:
291311304SJanie.Lu@Sun.COM 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_iptun_class: FAILED"));
291411304SJanie.Lu@Sun.COM }
291511304SJanie.Lu@Sun.COM 
291611304SJanie.Lu@Sun.COM void
nxge_set_ip_cls_sym(p_nxge_t nxgep,uint8_t cls_id,uint8_t sym)291711304SJanie.Lu@Sun.COM nxge_set_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t sym)
291811304SJanie.Lu@Sun.COM {
291911304SJanie.Lu@Sun.COM 	npi_handle_t handle = nxgep->npi_reg_handle;
292011304SJanie.Lu@Sun.COM 	npi_status_t rs = NPI_SUCCESS;
292111304SJanie.Lu@Sun.COM 	boolean_t sym_en = (sym == 1) ? B_TRUE : B_FALSE;
292211304SJanie.Lu@Sun.COM 
292311304SJanie.Lu@Sun.COM 	rs = npi_fflp_cfg_sym_ip_cls_flow_key(handle, (tcam_class_t)cls_id,
292411304SJanie.Lu@Sun.COM 	    sym_en);
292511304SJanie.Lu@Sun.COM 	if (rs != NPI_SUCCESS)
292611304SJanie.Lu@Sun.COM 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
292711304SJanie.Lu@Sun.COM 		    "nxge_set_ip_cls_sym: FAILED"));
292811304SJanie.Lu@Sun.COM }
292911304SJanie.Lu@Sun.COM 
293011304SJanie.Lu@Sun.COM void
nxge_get_ip_cls_sym(p_nxge_t nxgep,uint8_t cls_id,uint8_t * sym)293111304SJanie.Lu@Sun.COM nxge_get_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t *sym)
293211304SJanie.Lu@Sun.COM {
293311304SJanie.Lu@Sun.COM 	npi_handle_t handle = nxgep->npi_reg_handle;
293411304SJanie.Lu@Sun.COM 	npi_status_t rs = NPI_SUCCESS;
293511304SJanie.Lu@Sun.COM 	flow_key_cfg_t cfg;
293611304SJanie.Lu@Sun.COM 
293711304SJanie.Lu@Sun.COM 	rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
293811304SJanie.Lu@Sun.COM 	    (tcam_class_t)cls_id, &cfg);
293911304SJanie.Lu@Sun.COM 	if (rs != NPI_SUCCESS)
294011304SJanie.Lu@Sun.COM 		goto fail;
294111304SJanie.Lu@Sun.COM 
294211304SJanie.Lu@Sun.COM 	if (cfg.use_sym)
294311304SJanie.Lu@Sun.COM 		*sym = 1;
294411304SJanie.Lu@Sun.COM 	else
294511304SJanie.Lu@Sun.COM 		*sym = 0;
294611304SJanie.Lu@Sun.COM 	return;
294711304SJanie.Lu@Sun.COM fail:
294811304SJanie.Lu@Sun.COM 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_ip_cls_sym: FAILED"));
294911304SJanie.Lu@Sun.COM }
2950