xref: /titanic_44/usr/src/uts/common/io/nxge/nxge_fflp.c (revision 0dc2366f7b9f9f36e10909b1e95edbf2a261c2ac)
16f45ec7bSml29623 /*
26f45ec7bSml29623  * CDDL HEADER START
36f45ec7bSml29623  *
46f45ec7bSml29623  * The contents of this file are subject to the terms of the
56f45ec7bSml29623  * Common Development and Distribution License (the "License").
66f45ec7bSml29623  * You may not use this file except in compliance with the License.
76f45ec7bSml29623  *
86f45ec7bSml29623  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96f45ec7bSml29623  * or http://www.opensolaris.org/os/licensing.
106f45ec7bSml29623  * See the License for the specific language governing permissions
116f45ec7bSml29623  * and limitations under the License.
126f45ec7bSml29623  *
136f45ec7bSml29623  * When distributing Covered Code, include this CDDL HEADER in each
146f45ec7bSml29623  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156f45ec7bSml29623  * If applicable, add the following below this CDDL HEADER, with the
166f45ec7bSml29623  * fields enclosed by brackets "[]" replaced with your own identifying
176f45ec7bSml29623  * information: Portions Copyright [yyyy] [name of copyright owner]
186f45ec7bSml29623  *
196f45ec7bSml29623  * CDDL HEADER END
206f45ec7bSml29623  */
21*0dc2366fSVenugopal Iyer 
226f45ec7bSml29623 /*
23*0dc2366fSVenugopal Iyer  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
246f45ec7bSml29623  * Use is subject to license terms.
256f45ec7bSml29623  */
266f45ec7bSml29623 
276f45ec7bSml29623 #include <npi_fflp.h>
286f45ec7bSml29623 #include <npi_mac.h>
296f45ec7bSml29623 #include <nxge_defs.h>
306f45ec7bSml29623 #include <nxge_flow.h>
316f45ec7bSml29623 #include <nxge_fflp.h>
326f45ec7bSml29623 #include <nxge_impl.h>
336f45ec7bSml29623 #include <nxge_fflp_hash.h>
346f45ec7bSml29623 #include <nxge_common.h>
356f45ec7bSml29623 
366f45ec7bSml29623 
376f45ec7bSml29623 /*
386f45ec7bSml29623  * Function prototypes
396f45ec7bSml29623  */
406f45ec7bSml29623 static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t);
416f45ec7bSml29623 static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t);
426f45ec7bSml29623 static nxge_status_t nxge_fflp_tcam_init(p_nxge_t);
436f45ec7bSml29623 static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t);
446f45ec7bSml29623 static nxge_status_t nxge_fflp_fcram_init(p_nxge_t);
456f45ec7bSml29623 static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *);
466f45ec7bSml29623 static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
476f45ec7bSml29623 static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
486f45ec7bSml29623 static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
496f45ec7bSml29623 static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *,
506f45ec7bSml29623 	tcam_entry_t *);
516f45ec7bSml29623 static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *,
526f45ec7bSml29623 	tcam_entry_t *);
536f45ec7bSml29623 static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *,
546f45ec7bSml29623 	tcam_entry_t *);
554df55fdeSJanie Lu static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t);
564df55fdeSJanie Lu static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t);
574df55fdeSJanie Lu static uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t);
584df55fdeSJanie Lu static uint32_t nxge_tcam_cls_to_flow(uint32_t);
594df55fdeSJanie Lu static uint8_t nxge_iptun_pkt_type_to_pid(uint8_t);
604df55fdeSJanie Lu static npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t,
614df55fdeSJanie Lu 					iptun_cfg_t *);
624df55fdeSJanie Lu static boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *);
636f45ec7bSml29623 
646f45ec7bSml29623 /*
656f45ec7bSml29623  * functions used outside this file
666f45ec7bSml29623  */
676f45ec7bSml29623 nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t);
686f45ec7bSml29623 nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t);
696f45ec7bSml29623 nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *);
706f45ec7bSml29623 static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t);
716f45ec7bSml29623 nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *);
726f45ec7bSml29623 nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *);
736f45ec7bSml29623 nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *,
746f45ec7bSml29623 	uint32_t *, uint16_t *);
754df55fdeSJanie Lu int nxge_get_valid_tcam_cnt(p_nxge_t);
764df55fdeSJanie Lu void nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *);
774df55fdeSJanie Lu void nxge_get_tcam_entry(p_nxge_t, flow_resource_t *);
784df55fdeSJanie Lu void nxge_del_tcam_entry(p_nxge_t, uint32_t);
794df55fdeSJanie Lu void nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *);
804df55fdeSJanie Lu void nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t);
814df55fdeSJanie Lu void nxge_del_iptun_class(p_nxge_t, uint8_t);
824df55fdeSJanie Lu void nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t);
834df55fdeSJanie Lu void nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t);
844df55fdeSJanie Lu void nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *);
854df55fdeSJanie Lu 
866f45ec7bSml29623 
876f45ec7bSml29623 nxge_status_t
nxge_tcam_dump_entry(p_nxge_t nxgep,uint32_t location)886f45ec7bSml29623 nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location)
896f45ec7bSml29623 {
906f45ec7bSml29623 	tcam_entry_t tcam_rdptr;
916f45ec7bSml29623 	uint64_t asc_ram = 0;
926f45ec7bSml29623 	npi_handle_t handle;
936f45ec7bSml29623 	npi_status_t status;
946f45ec7bSml29623 
956f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
966f45ec7bSml29623 
976f45ec7bSml29623 	bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry));
986f45ec7bSml29623 	status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location,
996f45ec7bSml29623 	    (struct tcam_entry *)&tcam_rdptr);
1006f45ec7bSml29623 	if (status & NPI_FAILURE) {
1016f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1026f45ec7bSml29623 		    " nxge_tcam_dump_entry:"
1036f45ec7bSml29623 		    "  tcam read failed at location %d ", location));
1046f45ec7bSml29623 		return (NXGE_ERROR);
1056f45ec7bSml29623 	}
1066f45ec7bSml29623 	status = npi_fflp_tcam_asc_ram_entry_read(handle,
1076f45ec7bSml29623 	    (tcam_location_t)location, &asc_ram);
1086f45ec7bSml29623 
1096f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n"
1106f45ec7bSml29623 	    " key:  %llx %llx %llx %llx \n"
1116f45ec7bSml29623 	    " mask: %llx %llx %llx %llx \n"
1126f45ec7bSml29623 	    " ASC RAM %llx \n", location,
1136f45ec7bSml29623 	    tcam_rdptr.key0, tcam_rdptr.key1,
1146f45ec7bSml29623 	    tcam_rdptr.key2, tcam_rdptr.key3,
1156f45ec7bSml29623 	    tcam_rdptr.mask0, tcam_rdptr.mask1,
1166f45ec7bSml29623 	    tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram));
1176f45ec7bSml29623 	return (NXGE_OK);
1186f45ec7bSml29623 }
1196f45ec7bSml29623 
1206f45ec7bSml29623 void
nxge_get_tcam(p_nxge_t nxgep,p_mblk_t mp)1216f45ec7bSml29623 nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp)
1226f45ec7bSml29623 {
1236f45ec7bSml29623 	uint32_t tcam_loc;
1246f45ec7bSml29623 	int *lptr;
1256f45ec7bSml29623 	int location;
1266f45ec7bSml29623 
1276f45ec7bSml29623 	uint32_t start_location = 0;
1286f45ec7bSml29623 	uint32_t stop_location = nxgep->classifier.tcam_size;
1296f45ec7bSml29623 	lptr = (int *)mp->b_rptr;
1306f45ec7bSml29623 	location = *lptr;
1316f45ec7bSml29623 
1326f45ec7bSml29623 	if ((location >= nxgep->classifier.tcam_size) || (location < -1)) {
1336f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1346f45ec7bSml29623 		    "nxge_tcam_dump: Invalid location %d \n", location));
1356f45ec7bSml29623 		return;
1366f45ec7bSml29623 	}
1376f45ec7bSml29623 	if (location == -1) {
1386f45ec7bSml29623 		start_location = 0;
1396f45ec7bSml29623 		stop_location = nxgep->classifier.tcam_size;
1406f45ec7bSml29623 	} else {
1416f45ec7bSml29623 		start_location = location;
1426f45ec7bSml29623 		stop_location = location + 1;
1436f45ec7bSml29623 	}
1446f45ec7bSml29623 	for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++)
1456f45ec7bSml29623 		(void) nxge_tcam_dump_entry(nxgep, tcam_loc);
1466f45ec7bSml29623 }
1476f45ec7bSml29623 
1486f45ec7bSml29623 /*
1496f45ec7bSml29623  * nxge_fflp_vlan_table_invalidate_all
1506f45ec7bSml29623  * invalidates the vlan RDC table entries.
1516f45ec7bSml29623  * INPUT
1526f45ec7bSml29623  * nxge    soft state data structure
1536f45ec7bSml29623  * Return
1546f45ec7bSml29623  *      NXGE_OK
1556f45ec7bSml29623  *      NXGE_ERROR
1566f45ec7bSml29623  *
1576f45ec7bSml29623  */
1586f45ec7bSml29623 
1596f45ec7bSml29623 static nxge_status_t
nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)1606f45ec7bSml29623 nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)
1616f45ec7bSml29623 {
1626f45ec7bSml29623 	vlan_id_t vlan_id;
1636f45ec7bSml29623 	npi_handle_t handle;
1646f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
1656f45ec7bSml29623 	vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
1666f45ec7bSml29623 
1676f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all "));
1686f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
1696f45ec7bSml29623 	for (vlan_id = start; vlan_id < stop; vlan_id++) {
1706f45ec7bSml29623 		rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id);
1716f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
1726f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1736f45ec7bSml29623 			    "VLAN Table invalidate failed for vlan id %d ",
1746f45ec7bSml29623 			    vlan_id));
1756f45ec7bSml29623 			return (NXGE_ERROR | rs);
1766f45ec7bSml29623 		}
1776f45ec7bSml29623 	}
1786f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all "));
1796f45ec7bSml29623 	return (NXGE_OK);
1806f45ec7bSml29623 }
1816f45ec7bSml29623 
1826f45ec7bSml29623 /*
1836f45ec7bSml29623  * The following functions are used by other modules to init
1846f45ec7bSml29623  * the fflp module.
1856f45ec7bSml29623  * these functions are the basic API used to init
1866f45ec7bSml29623  * the fflp modules (tcam, fcram etc ......)
1876f45ec7bSml29623  *
1886f45ec7bSml29623  * The TCAM search future would be disabled  by default.
1896f45ec7bSml29623  */
1906f45ec7bSml29623 
1916f45ec7bSml29623 static nxge_status_t
nxge_fflp_tcam_init(p_nxge_t nxgep)1926f45ec7bSml29623 nxge_fflp_tcam_init(p_nxge_t nxgep)
1936f45ec7bSml29623 {
1946f45ec7bSml29623 	uint8_t access_ratio;
1956f45ec7bSml29623 	tcam_class_t class;
1966f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
1976f45ec7bSml29623 	npi_handle_t handle;
1986f45ec7bSml29623 
1996f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init"));
2006f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
2016f45ec7bSml29623 
2026f45ec7bSml29623 	rs = npi_fflp_cfg_tcam_disable(handle);
2036f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
2046f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n"));
2056f45ec7bSml29623 		return (NXGE_ERROR | rs);
2066f45ec7bSml29623 	}
2076f45ec7bSml29623 
2086f45ec7bSml29623 	access_ratio = nxgep->param_arr[param_tcam_access_ratio].value;
2096f45ec7bSml29623 	rs = npi_fflp_cfg_tcam_access(handle, access_ratio);
2106f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
2116f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2126f45ec7bSml29623 		    "failed TCAM Access cfg\n"));
2136f45ec7bSml29623 		return (NXGE_ERROR | rs);
2146f45ec7bSml29623 	}
2156f45ec7bSml29623 
2166f45ec7bSml29623 	/* disable configurable classes */
2176f45ec7bSml29623 	/* disable the configurable ethernet classes; */
2186f45ec7bSml29623 	for (class = TCAM_CLASS_ETYPE_1;
2196f45ec7bSml29623 	    class <= TCAM_CLASS_ETYPE_2; class++) {
2206f45ec7bSml29623 		rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class);
2216f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
2226f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2236f45ec7bSml29623 			    "TCAM USR Ether Class config failed."));
2246f45ec7bSml29623 			return (NXGE_ERROR | rs);
2256f45ec7bSml29623 		}
2266f45ec7bSml29623 	}
2276f45ec7bSml29623 
2286f45ec7bSml29623 	/* disable the configurable ip classes; */
2296f45ec7bSml29623 	for (class = TCAM_CLASS_IP_USER_4;
2306f45ec7bSml29623 	    class <= TCAM_CLASS_IP_USER_7; class++) {
2316f45ec7bSml29623 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
2326f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
2336f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2346f45ec7bSml29623 			    "TCAM USR IP Class cnfg failed."));
2356f45ec7bSml29623 			return (NXGE_ERROR | rs);
2366f45ec7bSml29623 		}
2376f45ec7bSml29623 	}
2386f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init"));
2396f45ec7bSml29623 	return (NXGE_OK);
2406f45ec7bSml29623 }
2416f45ec7bSml29623 
2426f45ec7bSml29623 /*
2436f45ec7bSml29623  * nxge_fflp_tcam_invalidate_all
2446f45ec7bSml29623  * invalidates all the tcam entries.
2456f45ec7bSml29623  * INPUT
2466f45ec7bSml29623  * nxge    soft state data structure
2476f45ec7bSml29623  * Return
2486f45ec7bSml29623  *      NXGE_OK
2496f45ec7bSml29623  *      NXGE_ERROR
2506f45ec7bSml29623  *
2516f45ec7bSml29623  */
2526f45ec7bSml29623 
2536f45ec7bSml29623 
2546f45ec7bSml29623 static nxge_status_t
nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)2556f45ec7bSml29623 nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)
2566f45ec7bSml29623 {
2576f45ec7bSml29623 	uint16_t location;
2586f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
2596f45ec7bSml29623 	npi_handle_t handle;
2606f45ec7bSml29623 	uint16_t start = 0, stop = nxgep->classifier.tcam_size;
2616f45ec7bSml29623 	p_nxge_hw_list_t hw_p;
2626f45ec7bSml29623 
2636f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
2646f45ec7bSml29623 	    "==> nxge_fflp_tcam_invalidate_all"));
2656f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
2666f45ec7bSml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
2676f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2686f45ec7bSml29623 		    " nxge_fflp_tcam_invalidate_all:"
2696f45ec7bSml29623 		    " common hardware not set", nxgep->niu_type));
2706f45ec7bSml29623 		return (NXGE_ERROR);
2716f45ec7bSml29623 	}
2726f45ec7bSml29623 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
2736f45ec7bSml29623 	for (location = start; location < stop; location++) {
2746f45ec7bSml29623 		rs = npi_fflp_tcam_entry_invalidate(handle, location);
2756f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
2766f45ec7bSml29623 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2776f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2786f45ec7bSml29623 			    "TCAM invalidate failed at loc %d ", location));
2796f45ec7bSml29623 			return (NXGE_ERROR | rs);
2806f45ec7bSml29623 		}
2816f45ec7bSml29623 	}
2826f45ec7bSml29623 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2836f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
2846f45ec7bSml29623 	    "<== nxge_fflp_tcam_invalidate_all"));
2856f45ec7bSml29623 	return (NXGE_OK);
2866f45ec7bSml29623 }
2876f45ec7bSml29623 
2886f45ec7bSml29623 /*
2896f45ec7bSml29623  * nxge_fflp_fcram_entry_invalidate_all
2906f45ec7bSml29623  * invalidates all the FCRAM entries.
2916f45ec7bSml29623  * INPUT
2926f45ec7bSml29623  * nxge    soft state data structure
2936f45ec7bSml29623  * Return
2946f45ec7bSml29623  *      NXGE_OK
2956f45ec7bSml29623  *      NXGE_ERROR
2966f45ec7bSml29623  *
2976f45ec7bSml29623  */
2986f45ec7bSml29623 
2996f45ec7bSml29623 static nxge_status_t
nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)3006f45ec7bSml29623 nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)
3016f45ec7bSml29623 {
3026f45ec7bSml29623 	npi_handle_t handle;
3036f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
3046f45ec7bSml29623 	part_id_t pid = 0;
3056f45ec7bSml29623 	uint8_t base_mask, base_reloc;
3066f45ec7bSml29623 	fcram_entry_t fc;
3076f45ec7bSml29623 	uint32_t location;
3086f45ec7bSml29623 	uint32_t increment, last_location;
3096f45ec7bSml29623 
3106f45ec7bSml29623 	/*
3116f45ec7bSml29623 	 * (1) configure and enable partition 0 with no relocation
3126f45ec7bSml29623 	 * (2) Assume the FCRAM is used as IPv4 exact match entry cells
3136f45ec7bSml29623 	 * (3) Invalidate these cells by clearing the valid bit in
3146f45ec7bSml29623 	 * the subareas 0 and 4
3156f45ec7bSml29623 	 * (4) disable the partition
3166f45ec7bSml29623 	 *
3176f45ec7bSml29623 	 */
3186f45ec7bSml29623 
3196f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all"));
3206f45ec7bSml29623 
3216f45ec7bSml29623 	base_mask = base_reloc = 0x0;
3226f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
3236f45ec7bSml29623 	rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc);
3246f45ec7bSml29623 
3256f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
3266f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n"));
3276f45ec7bSml29623 		return (NXGE_ERROR | rs);
3286f45ec7bSml29623 	}
3296f45ec7bSml29623 	rs = npi_fflp_cfg_fcram_partition_disable(handle, pid);
3306f45ec7bSml29623 
3316f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
3326f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3336f45ec7bSml29623 		    "failed partition enable\n"));
3346f45ec7bSml29623 		return (NXGE_ERROR | rs);
3356f45ec7bSml29623 	}
3366f45ec7bSml29623 	fc.dreg[0].value = 0;
3376f45ec7bSml29623 	fc.hash_hdr_valid = 0;
3386f45ec7bSml29623 	fc.hash_hdr_ext = 1;	/* specify as IPV4 exact match entry */
3396f45ec7bSml29623 	increment = sizeof (hash_ipv4_t);
3406f45ec7bSml29623 	last_location = FCRAM_SIZE * 0x40;
3416f45ec7bSml29623 
3426f45ec7bSml29623 	for (location = 0; location < last_location; location += increment) {
3436f45ec7bSml29623 		rs = npi_fflp_fcram_subarea_write(handle, pid,
34452ccf843Smisaki 		    location, fc.value[0]);
3456f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
3466f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
34752ccf843Smisaki 			    "failed write at location %x ", location));
3486f45ec7bSml29623 			return (NXGE_ERROR | rs);
3496f45ec7bSml29623 		}
3506f45ec7bSml29623 	}
3516f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all"));
3526f45ec7bSml29623 	return (NXGE_OK);
3536f45ec7bSml29623 }
3546f45ec7bSml29623 
3556f45ec7bSml29623 static nxge_status_t
nxge_fflp_fcram_init(p_nxge_t nxgep)3566f45ec7bSml29623 nxge_fflp_fcram_init(p_nxge_t nxgep)
3576f45ec7bSml29623 {
3586f45ec7bSml29623 	fflp_fcram_output_drive_t strength;
3596f45ec7bSml29623 	fflp_fcram_qs_t qs;
3606f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
3616f45ec7bSml29623 	uint8_t access_ratio;
3626f45ec7bSml29623 	int partition;
3636f45ec7bSml29623 	npi_handle_t handle;
3646f45ec7bSml29623 	uint32_t min_time, max_time, sys_time;
3656f45ec7bSml29623 
3666f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init"));
3676f45ec7bSml29623 
3686f45ec7bSml29623 	/*
3696f45ec7bSml29623 	 * Recommended values are needed.
3706f45ec7bSml29623 	 */
3716f45ec7bSml29623 	min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME;
3726f45ec7bSml29623 	max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME;
3736f45ec7bSml29623 	sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME;
3746f45ec7bSml29623 
3756f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
3766f45ec7bSml29623 	strength = FCRAM_OUTDR_NORMAL;
3776f45ec7bSml29623 	qs = FCRAM_QS_MODE_QS;
3786f45ec7bSml29623 	rs = npi_fflp_cfg_fcram_reset(handle, strength, qs);
3796f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
3806f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. "));
3816f45ec7bSml29623 		return (NXGE_ERROR | rs);
3826f45ec7bSml29623 	}
3836f45ec7bSml29623 
3846f45ec7bSml29623 	access_ratio = nxgep->param_arr[param_fcram_access_ratio].value;
3856f45ec7bSml29623 	rs = npi_fflp_cfg_fcram_access(handle, access_ratio);
3866f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
3876f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio"
3886f45ec7bSml29623 		    "configuration \n"));
3896f45ec7bSml29623 		return (NXGE_ERROR | rs);
3906f45ec7bSml29623 	}
3916f45ec7bSml29623 	rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time,
3926f45ec7bSml29623 	    max_time, sys_time);
3936f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
3946f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3956f45ec7bSml29623 		    "failed FCRAM refresh cfg"));
3966f45ec7bSml29623 		return (NXGE_ERROR);
3976f45ec7bSml29623 	}
3986f45ec7bSml29623 
3996f45ec7bSml29623 	/* disable all the partitions until explicitly enabled */
4006f45ec7bSml29623 	for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) {
4016f45ec7bSml29623 		rs = npi_fflp_cfg_fcram_partition_disable(handle, partition);
4026f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
4036f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4046f45ec7bSml29623 			    "failed FCRAM partition"
4056f45ec7bSml29623 			    " enable for partition %d ", partition));
4066f45ec7bSml29623 			return (NXGE_ERROR | rs);
4076f45ec7bSml29623 		}
4086f45ec7bSml29623 	}
4096f45ec7bSml29623 
4106f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init"));
4116f45ec7bSml29623 	return (NXGE_OK);
4126f45ec7bSml29623 }
4136f45ec7bSml29623 
4146f45ec7bSml29623 nxge_status_t
nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep,uint8_t alt_mac)4156f45ec7bSml29623 nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac)
4166f45ec7bSml29623 {
4176f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
4186f45ec7bSml29623 	hostinfo_t mac_rdc;
4196f45ec7bSml29623 	npi_handle_t handle;
4206f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
4216f45ec7bSml29623 
4226f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
4236f45ec7bSml29623 	if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) {
4246f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4256f45ec7bSml29623 		    " nxge_logical_mac_assign_rdc_table"
4266f45ec7bSml29623 		    " unconfigured alt MAC addr %d ", alt_mac));
4276f45ec7bSml29623 		return (NXGE_ERROR);
4286f45ec7bSml29623 	}
4296f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
4306f45ec7bSml29623 	mac_rdc.value = 0;
4316f45ec7bSml29623 	mac_rdc.bits.w0.rdc_tbl_num =
4326f45ec7bSml29623 	    p_class_cfgp->mac_host_info[alt_mac].rdctbl;
4336f45ec7bSml29623 	mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr;
4346f45ec7bSml29623 
4356f45ec7bSml29623 	rs = npi_mac_hostinfo_entry(handle, OP_SET,
4366f45ec7bSml29623 	    nxgep->function_num, alt_mac, &mac_rdc);
4376f45ec7bSml29623 
4386f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
4396f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4406f45ec7bSml29623 		    "failed Assign RDC table"));
4416f45ec7bSml29623 		return (NXGE_ERROR | rs);
4426f45ec7bSml29623 	}
4436f45ec7bSml29623 	return (NXGE_OK);
4446f45ec7bSml29623 }
4456f45ec7bSml29623 
4466f45ec7bSml29623 nxge_status_t
nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)4476f45ec7bSml29623 nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)
4486f45ec7bSml29623 {
4496f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
4506f45ec7bSml29623 	hostinfo_t mac_rdc;
4516f45ec7bSml29623 	npi_handle_t handle;
452*0dc2366fSVenugopal Iyer 	int i;
4536f45ec7bSml29623 
4546f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
4556f45ec7bSml29623 	mac_rdc.value = 0;
4566f45ec7bSml29623 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp;
4576f45ec7bSml29623 	mac_rdc.bits.w0.mac_pref = 1;
4586f45ec7bSml29623 	switch (nxgep->function_num) {
4596f45ec7bSml29623 	case 0:
4606f45ec7bSml29623 	case 1:
461*0dc2366fSVenugopal Iyer 		/*
462*0dc2366fSVenugopal Iyer 		 * Tests indicate that it is OK not to re-initialize the
463*0dc2366fSVenugopal Iyer 		 * hostinfo registers for the XMAC's alternate MAC
464*0dc2366fSVenugopal Iyer 		 * addresses. But that is necessary for BMAC (case 2
465*0dc2366fSVenugopal Iyer 		 * and case 3 below)
466*0dc2366fSVenugopal Iyer 		 */
4676f45ec7bSml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
46852ccf843Smisaki 		    nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
4696f45ec7bSml29623 		break;
4706f45ec7bSml29623 	case 2:
4716f45ec7bSml29623 	case 3:
4726f45ec7bSml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
47352ccf843Smisaki 		    nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
474*0dc2366fSVenugopal Iyer 		for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
475*0dc2366fSVenugopal Iyer 			rs |= npi_mac_hostinfo_entry(handle, OP_SET,
476*0dc2366fSVenugopal Iyer 			    nxgep->function_num, i, &mac_rdc);
4776f45ec7bSml29623 		break;
4786f45ec7bSml29623 	default:
4796f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4806f45ec7bSml29623 		    "failed Assign RDC table (invalid function #)"));
4816f45ec7bSml29623 		return (NXGE_ERROR);
4826f45ec7bSml29623 	}
4836f45ec7bSml29623 
4846f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
4856f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4866f45ec7bSml29623 		    "failed Assign RDC table"));
4876f45ec7bSml29623 		return (NXGE_ERROR | rs);
4886f45ec7bSml29623 	}
4896f45ec7bSml29623 	return (NXGE_OK);
4906f45ec7bSml29623 }
4916f45ec7bSml29623 
4926f45ec7bSml29623 /*
4936f45ec7bSml29623  * Initialize hostinfo registers for alternate MAC addresses and
4946f45ec7bSml29623  * multicast MAC address.
4956f45ec7bSml29623  */
4966f45ec7bSml29623 nxge_status_t
nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)4976f45ec7bSml29623 nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)
4986f45ec7bSml29623 {
4996f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
5006f45ec7bSml29623 	hostinfo_t mac_rdc;
5016f45ec7bSml29623 	npi_handle_t handle;
5026f45ec7bSml29623 
5036f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
5046f45ec7bSml29623 	mac_rdc.value = 0;
5056f45ec7bSml29623 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp;
5066f45ec7bSml29623 	mac_rdc.bits.w0.mac_pref = 1;
5076f45ec7bSml29623 	switch (nxgep->function_num) {
5086f45ec7bSml29623 	case 0:
5096f45ec7bSml29623 	case 1:
5106f45ec7bSml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
511*0dc2366fSVenugopal Iyer 		    nxgep->function_num, XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
5126f45ec7bSml29623 		break;
5136f45ec7bSml29623 	case 2:
5146f45ec7bSml29623 	case 3:
515*0dc2366fSVenugopal Iyer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
516*0dc2366fSVenugopal Iyer 		    nxgep->function_num, BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
5176f45ec7bSml29623 		break;
5186f45ec7bSml29623 	default:
5196f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
520f6485eecSyc148097 		    "failed Assign RDC table (invalid function #)"));
5216f45ec7bSml29623 		return (NXGE_ERROR);
5226f45ec7bSml29623 	}
5236f45ec7bSml29623 
5246f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
5256f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5266f45ec7bSml29623 		    "failed Assign RDC table"));
5276f45ec7bSml29623 		return (NXGE_ERROR | rs);
5286f45ec7bSml29623 	}
5296f45ec7bSml29623 	return (NXGE_OK);
5306f45ec7bSml29623 }
5316f45ec7bSml29623 
5326f45ec7bSml29623 nxge_status_t
nxge_fflp_init_hostinfo(p_nxge_t nxgep)5336f45ec7bSml29623 nxge_fflp_init_hostinfo(p_nxge_t nxgep)
5346f45ec7bSml29623 {
5356f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
5366f45ec7bSml29623 
5376f45ec7bSml29623 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
5386f45ec7bSml29623 	status |= nxge_main_mac_assign_rdc_table(nxgep);
5396f45ec7bSml29623 	return (status);
5406f45ec7bSml29623 }
5416f45ec7bSml29623 
5426f45ec7bSml29623 nxge_status_t
nxge_fflp_hw_reset(p_nxge_t nxgep)5436f45ec7bSml29623 nxge_fflp_hw_reset(p_nxge_t nxgep)
5446f45ec7bSml29623 {
5456f45ec7bSml29623 	npi_handle_t handle;
5466f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
5476f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
5486f45ec7bSml29623 
5496f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
5506f45ec7bSml29623 
5512e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
5526f45ec7bSml29623 		status = nxge_fflp_fcram_init(nxgep);
5536f45ec7bSml29623 		if (status != NXGE_OK) {
5546f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5556f45ec7bSml29623 			    " failed FCRAM init. "));
5566f45ec7bSml29623 			return (status);
5576f45ec7bSml29623 		}
5586f45ec7bSml29623 	}
5596f45ec7bSml29623 
5606f45ec7bSml29623 	status = nxge_fflp_tcam_init(nxgep);
5616f45ec7bSml29623 	if (status != NXGE_OK) {
5626f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5636f45ec7bSml29623 		    "failed TCAM init."));
5646f45ec7bSml29623 		return (status);
5656f45ec7bSml29623 	}
5666f45ec7bSml29623 
5676f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
5686f45ec7bSml29623 	rs = npi_fflp_cfg_llcsnap_enable(handle);
5696f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
5706f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5716f45ec7bSml29623 		    "failed LLCSNAP enable. "));
5726f45ec7bSml29623 		return (NXGE_ERROR | rs);
5736f45ec7bSml29623 	}
5746f45ec7bSml29623 
5756f45ec7bSml29623 	rs = npi_fflp_cfg_cam_errorcheck_disable(handle);
5766f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
5776f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5786f45ec7bSml29623 		    "failed CAM Error Check enable. "));
5796f45ec7bSml29623 		return (NXGE_ERROR | rs);
5806f45ec7bSml29623 	}
5816f45ec7bSml29623 
5826f45ec7bSml29623 	/* init the hash generators */
5836f45ec7bSml29623 	rs = npi_fflp_cfg_hash_h1poly(handle, 0);
5846f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
5856f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5866f45ec7bSml29623 		    "failed H1 Poly Init. "));
5876f45ec7bSml29623 		return (NXGE_ERROR | rs);
5886f45ec7bSml29623 	}
5896f45ec7bSml29623 
5906f45ec7bSml29623 	rs = npi_fflp_cfg_hash_h2poly(handle, 0);
5916f45ec7bSml29623 	if (rs != NPI_SUCCESS) {
5926f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5936f45ec7bSml29623 		    "failed H2 Poly Init. "));
5946f45ec7bSml29623 		return (NXGE_ERROR | rs);
5956f45ec7bSml29623 	}
5966f45ec7bSml29623 
5976f45ec7bSml29623 	/* invalidate TCAM entries */
5986f45ec7bSml29623 	status = nxge_fflp_tcam_invalidate_all(nxgep);
5996f45ec7bSml29623 	if (status != NXGE_OK) {
6006f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6016f45ec7bSml29623 		    "failed TCAM Entry Invalidate. "));
6026f45ec7bSml29623 		return (status);
6036f45ec7bSml29623 	}
6046f45ec7bSml29623 
6056f45ec7bSml29623 	/* invalidate FCRAM entries */
6062e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6076f45ec7bSml29623 		status = nxge_fflp_fcram_invalidate_all(nxgep);
6086f45ec7bSml29623 		if (status != NXGE_OK) {
6096f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6106f45ec7bSml29623 			    "failed FCRAM Entry Invalidate."));
6116f45ec7bSml29623 			return (status);
6126f45ec7bSml29623 		}
6136f45ec7bSml29623 	}
6146f45ec7bSml29623 
6156f45ec7bSml29623 	/* invalidate VLAN RDC tables */
6166f45ec7bSml29623 	status = nxge_fflp_vlan_tbl_clear_all(nxgep);
6176f45ec7bSml29623 	if (status != NXGE_OK) {
6186f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6196f45ec7bSml29623 		    "failed VLAN Table Invalidate. "));
6206f45ec7bSml29623 		return (status);
6216f45ec7bSml29623 	}
6226f45ec7bSml29623 	nxgep->classifier.state |= NXGE_FFLP_HW_RESET;
6236f45ec7bSml29623 
6246f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset"));
6256f45ec7bSml29623 	return (NXGE_OK);
6266f45ec7bSml29623 }
6276f45ec7bSml29623 
6286f45ec7bSml29623 nxge_status_t
nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep,tcam_class_t l3_class,uint32_t class_config)6296f45ec7bSml29623 nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class,
6306f45ec7bSml29623 	uint32_t class_config)
6316f45ec7bSml29623 {
6326f45ec7bSml29623 	flow_key_cfg_t fcfg;
6336f45ec7bSml29623 	npi_handle_t handle;
6346f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
6356f45ec7bSml29623 
6366f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key"));
6376f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
6386f45ec7bSml29623 	bzero(&fcfg, sizeof (flow_key_cfg_t));
6396f45ec7bSml29623 
6406f45ec7bSml29623 	if (class_config & NXGE_CLASS_FLOW_USE_PROTO)
6416f45ec7bSml29623 		fcfg.use_proto = 1;
6426f45ec7bSml29623 	if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT)
6436f45ec7bSml29623 		fcfg.use_dport = 1;
6446f45ec7bSml29623 	if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT)
6456f45ec7bSml29623 		fcfg.use_sport = 1;
6466f45ec7bSml29623 	if (class_config & NXGE_CLASS_FLOW_USE_IPDST)
6476f45ec7bSml29623 		fcfg.use_daddr = 1;
6486f45ec7bSml29623 	if (class_config & NXGE_CLASS_FLOW_USE_IPSRC)
6496f45ec7bSml29623 		fcfg.use_saddr = 1;
6506f45ec7bSml29623 	if (class_config & NXGE_CLASS_FLOW_USE_VLAN)
6516f45ec7bSml29623 		fcfg.use_vlan = 1;
6526f45ec7bSml29623 	if (class_config & NXGE_CLASS_FLOW_USE_L2DA)
6536f45ec7bSml29623 		fcfg.use_l2da = 1;
6546f45ec7bSml29623 	if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM)
6556f45ec7bSml29623 		fcfg.use_portnum = 1;
6566f45ec7bSml29623 	fcfg.ip_opts_exist = 0;
6576f45ec7bSml29623 
6586f45ec7bSml29623 	rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg);
6596f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
6606f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
66152ccf843Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
6626f45ec7bSml29623 		return (NXGE_ERROR | rs);
6636f45ec7bSml29623 	}
6646f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key"));
6656f45ec7bSml29623 	return (NXGE_OK);
6666f45ec7bSml29623 }
6676f45ec7bSml29623 
6686f45ec7bSml29623 nxge_status_t
nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep,tcam_class_t l3_class,uint32_t * class_config)6696f45ec7bSml29623 nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class,
6706f45ec7bSml29623 	uint32_t *class_config)
6716f45ec7bSml29623 {
6726f45ec7bSml29623 	flow_key_cfg_t fcfg;
6736f45ec7bSml29623 	npi_handle_t handle;
6746f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
6756f45ec7bSml29623 	uint32_t ccfg = 0;
6766f45ec7bSml29623 
6776f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get"));
6786f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
6796f45ec7bSml29623 	bzero(&fcfg, sizeof (flow_key_cfg_t));
6806f45ec7bSml29623 
6816f45ec7bSml29623 	rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg);
6826f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
6836f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
68452ccf843Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
6856f45ec7bSml29623 		return (NXGE_ERROR | rs);
6866f45ec7bSml29623 	}
6876f45ec7bSml29623 
6886f45ec7bSml29623 	if (fcfg.use_proto)
6896f45ec7bSml29623 		ccfg |= NXGE_CLASS_FLOW_USE_PROTO;
6906f45ec7bSml29623 	if (fcfg.use_dport)
6916f45ec7bSml29623 		ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT;
6926f45ec7bSml29623 	if (fcfg.use_sport)
6936f45ec7bSml29623 		ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT;
6946f45ec7bSml29623 	if (fcfg.use_daddr)
6956f45ec7bSml29623 		ccfg |= NXGE_CLASS_FLOW_USE_IPDST;
6966f45ec7bSml29623 	if (fcfg.use_saddr)
6976f45ec7bSml29623 		ccfg |= NXGE_CLASS_FLOW_USE_IPSRC;
6986f45ec7bSml29623 	if (fcfg.use_vlan)
6996f45ec7bSml29623 		ccfg |= NXGE_CLASS_FLOW_USE_VLAN;
7006f45ec7bSml29623 	if (fcfg.use_l2da)
7016f45ec7bSml29623 		ccfg |= NXGE_CLASS_FLOW_USE_L2DA;
7026f45ec7bSml29623 	if (fcfg.use_portnum)
7036f45ec7bSml29623 		ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM;
7046f45ec7bSml29623 
7056f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7066f45ec7bSml29623 	    " nxge_cfg_ip_cls_flow_key_get %x", ccfg));
7076f45ec7bSml29623 	*class_config = ccfg;
7086f45ec7bSml29623 
7096f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7106f45ec7bSml29623 	    " <== nxge_cfg_ip_cls_flow_key_get"));
7116f45ec7bSml29623 	return (NXGE_OK);
7126f45ec7bSml29623 }
7136f45ec7bSml29623 
7146f45ec7bSml29623 static nxge_status_t
nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep,tcam_class_t class,uint32_t * class_config)7156f45ec7bSml29623 nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class,
7166f45ec7bSml29623 	uint32_t *class_config)
7176f45ec7bSml29623 {
7186f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
7196f45ec7bSml29623 	tcam_key_cfg_t cfg;
7206f45ec7bSml29623 	npi_handle_t handle;
7216f45ec7bSml29623 	uint32_t ccfg = 0;
7226f45ec7bSml29623 
7236f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
7246f45ec7bSml29623 
7256f45ec7bSml29623 	bzero(&cfg, sizeof (tcam_key_cfg_t));
7266f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
7276f45ec7bSml29623 
7286f45ec7bSml29623 	rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg);
7296f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
7306f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
73152ccf843Smisaki 		    " opt %x for class %d failed ", class_config, class));
7326f45ec7bSml29623 		return (NXGE_ERROR | rs);
7336f45ec7bSml29623 	}
7346f45ec7bSml29623 	if (cfg.discard)
7356f45ec7bSml29623 		ccfg |= NXGE_CLASS_DISCARD;
7366f45ec7bSml29623 	if (cfg.lookup_enable)
7376f45ec7bSml29623 		ccfg |= NXGE_CLASS_TCAM_LOOKUP;
7386f45ec7bSml29623 	if (cfg.use_ip_daddr)
7396f45ec7bSml29623 		ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR;
7406f45ec7bSml29623 	*class_config = ccfg;
7416f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7426f45ec7bSml29623 	    " ==> nxge_cfg_tcam_ip_class %x", ccfg));
7436f45ec7bSml29623 	return (NXGE_OK);
7446f45ec7bSml29623 }
7456f45ec7bSml29623 
7466f45ec7bSml29623 static nxge_status_t
nxge_cfg_tcam_ip_class(p_nxge_t nxgep,tcam_class_t class,uint32_t class_config)7476f45ec7bSml29623 nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class,
7486f45ec7bSml29623 	uint32_t class_config)
7496f45ec7bSml29623 {
7506f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
7516f45ec7bSml29623 	tcam_key_cfg_t cfg;
7526f45ec7bSml29623 	npi_handle_t handle;
7536f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
7546f45ec7bSml29623 
7556f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
7566f45ec7bSml29623 
7576f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7586f45ec7bSml29623 	p_class_cfgp->class_cfg[class] = class_config;
7596f45ec7bSml29623 
7606f45ec7bSml29623 	bzero(&cfg, sizeof (tcam_key_cfg_t));
7616f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
7626f45ec7bSml29623 	cfg.discard = 0;
7636f45ec7bSml29623 	cfg.lookup_enable = 0;
7646f45ec7bSml29623 	cfg.use_ip_daddr = 0;
7656f45ec7bSml29623 	if (class_config & NXGE_CLASS_DISCARD)
7666f45ec7bSml29623 		cfg.discard = 1;
7676f45ec7bSml29623 	if (class_config & NXGE_CLASS_TCAM_LOOKUP)
7686f45ec7bSml29623 		cfg.lookup_enable = 1;
7696f45ec7bSml29623 	if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR)
7706f45ec7bSml29623 		cfg.use_ip_daddr = 1;
7716f45ec7bSml29623 
7726f45ec7bSml29623 	rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg);
7736f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
7746f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
77552ccf843Smisaki 		    " opt %x for class %d failed ", class_config, class));
7766f45ec7bSml29623 		return (NXGE_ERROR | rs);
7776f45ec7bSml29623 	}
7786f45ec7bSml29623 	return (NXGE_OK);
7796f45ec7bSml29623 }
7806f45ec7bSml29623 
7816f45ec7bSml29623 nxge_status_t
nxge_fflp_set_hash1(p_nxge_t nxgep,uint32_t h1)7826f45ec7bSml29623 nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1)
7836f45ec7bSml29623 {
7846f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
7856f45ec7bSml29623 	npi_handle_t handle;
7866f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
7876f45ec7bSml29623 
7886f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1"));
7896f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7906f45ec7bSml29623 	p_class_cfgp->init_h1 = h1;
7916f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
7926f45ec7bSml29623 	rs = npi_fflp_cfg_hash_h1poly(handle, h1);
7936f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
7946f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
7956f45ec7bSml29623 		    " nxge_fflp_init_h1 %x failed ", h1));
7966f45ec7bSml29623 		return (NXGE_ERROR | rs);
7976f45ec7bSml29623 	}
7986f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1"));
7996f45ec7bSml29623 	return (NXGE_OK);
8006f45ec7bSml29623 }
8016f45ec7bSml29623 
8026f45ec7bSml29623 nxge_status_t
nxge_fflp_set_hash2(p_nxge_t nxgep,uint16_t h2)8036f45ec7bSml29623 nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2)
8046f45ec7bSml29623 {
8056f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
8066f45ec7bSml29623 	npi_handle_t handle;
8076f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
8086f45ec7bSml29623 
8096f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2"));
8106f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
8116f45ec7bSml29623 	p_class_cfgp->init_h2 = h2;
8126f45ec7bSml29623 
8136f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
8146f45ec7bSml29623 	rs = npi_fflp_cfg_hash_h2poly(handle, h2);
8156f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
8166f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8176f45ec7bSml29623 		    " nxge_fflp_init_h2 %x failed ", h2));
8186f45ec7bSml29623 		return (NXGE_ERROR | rs);
8196f45ec7bSml29623 	}
8206f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2"));
8216f45ec7bSml29623 	return (NXGE_OK);
8226f45ec7bSml29623 }
8236f45ec7bSml29623 
8246f45ec7bSml29623 nxge_status_t
nxge_classify_init_sw(p_nxge_t nxgep)8256f45ec7bSml29623 nxge_classify_init_sw(p_nxge_t nxgep)
8266f45ec7bSml29623 {
8276f45ec7bSml29623 	nxge_classify_t *classify_ptr;
8286f45ec7bSml29623 
8296f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw"));
8306f45ec7bSml29623 	classify_ptr = &nxgep->classifier;
8316f45ec7bSml29623 
8326f45ec7bSml29623 	if (classify_ptr->state & NXGE_FFLP_SW_INIT) {
8336f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
8346f45ec7bSml29623 		    "nxge_classify_init_sw already init"));
8356f45ec7bSml29623 		return (NXGE_OK);
8366f45ec7bSml29623 	}
8376f45ec7bSml29623 
8384df55fdeSJanie Lu 	classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports;
8394df55fdeSJanie Lu 	classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam;
8404df55fdeSJanie Lu 	classify_ptr->tcam_top = nxgep->function_num;
8416f45ec7bSml29623 
8426f45ec7bSml29623 	/* Init defaults */
8436f45ec7bSml29623 	/*
8446f45ec7bSml29623 	 * add hacks required for HW shortcomings for example, code to handle
8456f45ec7bSml29623 	 * fragmented packets
8466f45ec7bSml29623 	 */
8476f45ec7bSml29623 	nxge_init_h1_table();
8486f45ec7bSml29623 	nxge_crc_ccitt_init();
8496f45ec7bSml29623 	nxgep->classifier.tcam_location = nxgep->function_num;
8506f45ec7bSml29623 	nxgep->classifier.fragment_bug = 1;
8516f45ec7bSml29623 	classify_ptr->state |= NXGE_FFLP_SW_INIT;
8526f45ec7bSml29623 
8536f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw"));
8546f45ec7bSml29623 	return (NXGE_OK);
8556f45ec7bSml29623 }
8566f45ec7bSml29623 
8576f45ec7bSml29623 nxge_status_t
nxge_classify_exit_sw(p_nxge_t nxgep)8586f45ec7bSml29623 nxge_classify_exit_sw(p_nxge_t nxgep)
8596f45ec7bSml29623 {
8606f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw"));
8616f45ec7bSml29623 	nxgep->classifier.state = NULL;
8626f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw"));
8636f45ec7bSml29623 	return (NXGE_OK);
8646f45ec7bSml29623 }
8656f45ec7bSml29623 
8666f45ec7bSml29623 /*
8676f45ec7bSml29623  * Figures out the RDC Group for the entry
8686f45ec7bSml29623  *
8696f45ec7bSml29623  * The current implementation is just a place holder and it
8706f45ec7bSml29623  * returns 0.
8716f45ec7bSml29623  * The real location determining algorithm would consider
8726f45ec7bSml29623  * the partition etc ... before deciding w
8736f45ec7bSml29623  *
8746f45ec7bSml29623  */
8756f45ec7bSml29623 
8766f45ec7bSml29623 /* ARGSUSED */
8776f45ec7bSml29623 static uint8_t
nxge_get_rdc_group(p_nxge_t nxgep,uint8_t class,uint64_t cookie)8784df55fdeSJanie Lu nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
8796f45ec7bSml29623 {
8806f45ec7bSml29623 	int use_port_rdc_grp = 0;
8816f45ec7bSml29623 	uint8_t rdc_grp = 0;
8826f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
8836f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
8846f45ec7bSml29623 	p_nxge_rdc_grp_t rdc_grp_p;
8856f45ec7bSml29623 
8866f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
8876f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
8886f45ec7bSml29623 	rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp];
889678453a8Sspeer 	rdc_grp = p_cfgp->def_mac_rxdma_grpid;
8906f45ec7bSml29623 
8916f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8926f45ec7bSml29623 	    "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
8936f45ec7bSml29623 	    cookie, rdc_grp, rdc_grp_p));
8946f45ec7bSml29623 	return (rdc_grp);
8956f45ec7bSml29623 }
8966f45ec7bSml29623 
8976f45ec7bSml29623 /* ARGSUSED */
8986f45ec7bSml29623 static uint8_t
nxge_get_rdc_offset(p_nxge_t nxgep,uint8_t class,uint64_t cookie)8994df55fdeSJanie Lu nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
9006f45ec7bSml29623 {
9016f45ec7bSml29623 	return ((uint8_t)cookie);
9026f45ec7bSml29623 }
9036f45ec7bSml29623 
9046f45ec7bSml29623 /* ARGSUSED */
9056f45ec7bSml29623 static void
nxge_fill_tcam_entry_udp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9066f45ec7bSml29623 nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9076f45ec7bSml29623 	tcam_entry_t *tcam_ptr)
9086f45ec7bSml29623 {
9096f45ec7bSml29623 	udpip4_spec_t *fspec_key;
9106f45ec7bSml29623 	udpip4_spec_t *fspec_mask;
9116f45ec7bSml29623 
9126f45ec7bSml29623 	fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec;
9136f45ec7bSml29623 	fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec;
9146f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
9156f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
9166f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
9176f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
9186f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
9196f45ec7bSml29623 	    fspec_key->pdst, fspec_key->psrc);
9206f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
9216f45ec7bSml29623 	    fspec_mask->pdst, fspec_mask->psrc);
9226f45ec7bSml29623 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
9236f45ec7bSml29623 	    tcam_ptr->ip4_class_mask,
9246f45ec7bSml29623 	    TCAM_CLASS_UDP_IPV4);
9256f45ec7bSml29623 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
9266f45ec7bSml29623 	    tcam_ptr->ip4_proto_mask,
9276f45ec7bSml29623 	    IPPROTO_UDP);
9284df55fdeSJanie Lu 	tcam_ptr->ip4_tos_key = fspec_key->tos;
9294df55fdeSJanie Lu 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
9306f45ec7bSml29623 }
9316f45ec7bSml29623 
9326f45ec7bSml29623 static void
nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9336f45ec7bSml29623 nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
9346f45ec7bSml29623 	tcam_entry_t *tcam_ptr)
9356f45ec7bSml29623 {
9366f45ec7bSml29623 	udpip6_spec_t *fspec_key;
9376f45ec7bSml29623 	udpip6_spec_t *fspec_mask;
9386f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
9396f45ec7bSml29623 
9406f45ec7bSml29623 	fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec;
9416f45ec7bSml29623 	fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec;
9426f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
9436f45ec7bSml29623 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
9446f45ec7bSml29623 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
9456f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
9466f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
9476f45ec7bSml29623 	} else {
9486f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
9496f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
9506f45ec7bSml29623 	}
9516f45ec7bSml29623 
9526f45ec7bSml29623 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
9536f45ec7bSml29623 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6);
9546f45ec7bSml29623 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
9556f45ec7bSml29623 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP);
9566f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
9576f45ec7bSml29623 	    fspec_key->pdst, fspec_key->psrc);
9586f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
9596f45ec7bSml29623 	    fspec_mask->pdst, fspec_mask->psrc);
9604df55fdeSJanie Lu 	tcam_ptr->ip6_tos_key = fspec_key->tos;
9614df55fdeSJanie Lu 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
9626f45ec7bSml29623 }
9636f45ec7bSml29623 
9646f45ec7bSml29623 /* ARGSUSED */
9656f45ec7bSml29623 static void
nxge_fill_tcam_entry_tcp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9666f45ec7bSml29623 nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9676f45ec7bSml29623 	tcam_entry_t *tcam_ptr)
9686f45ec7bSml29623 {
9696f45ec7bSml29623 	tcpip4_spec_t *fspec_key;
9706f45ec7bSml29623 	tcpip4_spec_t *fspec_mask;
9716f45ec7bSml29623 
9726f45ec7bSml29623 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
9736f45ec7bSml29623 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
9746f45ec7bSml29623 
9756f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
9766f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
9776f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
9786f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
9796f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
9806f45ec7bSml29623 	    fspec_key->pdst, fspec_key->psrc);
9816f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
9826f45ec7bSml29623 	    fspec_mask->pdst, fspec_mask->psrc);
9836f45ec7bSml29623 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
9846f45ec7bSml29623 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4);
9856f45ec7bSml29623 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
9866f45ec7bSml29623 	    tcam_ptr->ip4_proto_mask, IPPROTO_TCP);
9874df55fdeSJanie Lu 	tcam_ptr->ip4_tos_key = fspec_key->tos;
9884df55fdeSJanie Lu 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
9896f45ec7bSml29623 }
9906f45ec7bSml29623 
9916f45ec7bSml29623 /* ARGSUSED */
9926f45ec7bSml29623 static void
nxge_fill_tcam_entry_sctp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9936f45ec7bSml29623 nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9946f45ec7bSml29623 	tcam_entry_t *tcam_ptr)
9956f45ec7bSml29623 {
9966f45ec7bSml29623 	tcpip4_spec_t *fspec_key;
9976f45ec7bSml29623 	tcpip4_spec_t *fspec_mask;
9986f45ec7bSml29623 
9996f45ec7bSml29623 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
10006f45ec7bSml29623 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
10016f45ec7bSml29623 
10026f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
10036f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
10046f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
10056f45ec7bSml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
10066f45ec7bSml29623 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
10076f45ec7bSml29623 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4);
10086f45ec7bSml29623 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
10096f45ec7bSml29623 	    tcam_ptr->ip4_proto_mask, IPPROTO_SCTP);
10106f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
10116f45ec7bSml29623 	    fspec_key->pdst, fspec_key->psrc);
10126f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
10136f45ec7bSml29623 	    fspec_mask->pdst, fspec_mask->psrc);
10144df55fdeSJanie Lu 	tcam_ptr->ip4_tos_key = fspec_key->tos;
10154df55fdeSJanie Lu 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
10166f45ec7bSml29623 }
10176f45ec7bSml29623 
10186f45ec7bSml29623 static void
nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)10196f45ec7bSml29623 nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
10206f45ec7bSml29623 	tcam_entry_t *tcam_ptr)
10216f45ec7bSml29623 {
10226f45ec7bSml29623 	tcpip6_spec_t *fspec_key;
10236f45ec7bSml29623 	tcpip6_spec_t *fspec_mask;
10246f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
10256f45ec7bSml29623 
10266f45ec7bSml29623 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10276f45ec7bSml29623 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10286f45ec7bSml29623 
10296f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10306f45ec7bSml29623 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
10316f45ec7bSml29623 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
10326f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
10336f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
10346f45ec7bSml29623 	} else {
10356f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
10366f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
10376f45ec7bSml29623 	}
10386f45ec7bSml29623 
10396f45ec7bSml29623 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
10406f45ec7bSml29623 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6);
10416f45ec7bSml29623 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
10426f45ec7bSml29623 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP);
10436f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
10446f45ec7bSml29623 	    fspec_key->pdst, fspec_key->psrc);
10456f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
10466f45ec7bSml29623 	    fspec_mask->pdst, fspec_mask->psrc);
10474df55fdeSJanie Lu 	tcam_ptr->ip6_tos_key = fspec_key->tos;
10484df55fdeSJanie Lu 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
10496f45ec7bSml29623 }
10506f45ec7bSml29623 
10516f45ec7bSml29623 static void
nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)10526f45ec7bSml29623 nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
10536f45ec7bSml29623 	tcam_entry_t *tcam_ptr)
10546f45ec7bSml29623 {
10556f45ec7bSml29623 	tcpip6_spec_t *fspec_key;
10566f45ec7bSml29623 	tcpip6_spec_t *fspec_mask;
10576f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
10586f45ec7bSml29623 
10596f45ec7bSml29623 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10606f45ec7bSml29623 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10616f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10626f45ec7bSml29623 
10636f45ec7bSml29623 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
10646f45ec7bSml29623 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
10656f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
10666f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
10676f45ec7bSml29623 	} else {
10686f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
10696f45ec7bSml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
10706f45ec7bSml29623 	}
10716f45ec7bSml29623 
10726f45ec7bSml29623 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
10736f45ec7bSml29623 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6);
10746f45ec7bSml29623 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
10756f45ec7bSml29623 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP);
10766f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
10776f45ec7bSml29623 	    fspec_key->pdst, fspec_key->psrc);
10786f45ec7bSml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
10796f45ec7bSml29623 	    fspec_mask->pdst, fspec_mask->psrc);
10804df55fdeSJanie Lu 	tcam_ptr->ip6_tos_key = fspec_key->tos;
10814df55fdeSJanie Lu 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
10826f45ec7bSml29623 }
10836f45ec7bSml29623 
10844df55fdeSJanie Lu /* ARGSUSED */
10854df55fdeSJanie Lu static void
nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)10864df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec,
10874df55fdeSJanie Lu 	tcam_entry_t *tcam_ptr)
10884df55fdeSJanie Lu {
10894df55fdeSJanie Lu 	ahip4_spec_t *fspec_key;
10904df55fdeSJanie Lu 	ahip4_spec_t *fspec_mask;
10914df55fdeSJanie Lu 
10924df55fdeSJanie Lu 	fspec_key = (ahip4_spec_t *)&flow_spec->uh.ahip4spec;
10934df55fdeSJanie Lu 	fspec_mask = (ahip4_spec_t *)&flow_spec->um.ahip4spec;
10944df55fdeSJanie Lu 
10954df55fdeSJanie Lu 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
10964df55fdeSJanie Lu 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
10974df55fdeSJanie Lu 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
10984df55fdeSJanie Lu 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
10994df55fdeSJanie Lu 
11004df55fdeSJanie Lu 	tcam_ptr->ip4_port_key = fspec_key->spi;
11014df55fdeSJanie Lu 	tcam_ptr->ip4_port_mask = fspec_mask->spi;
11024df55fdeSJanie Lu 
11034df55fdeSJanie Lu 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
11044df55fdeSJanie Lu 	    tcam_ptr->ip4_class_mask,
11054df55fdeSJanie Lu 	    TCAM_CLASS_AH_ESP_IPV4);
11064df55fdeSJanie Lu 
11074df55fdeSJanie Lu 	if (flow_spec->flow_type == FSPEC_AHIP4) {
11084df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
11094df55fdeSJanie Lu 		    tcam_ptr->ip4_proto_mask, IPPROTO_AH);
11104df55fdeSJanie Lu 	} else {
11114df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
11124df55fdeSJanie Lu 		    tcam_ptr->ip4_proto_mask, IPPROTO_ESP);
11134df55fdeSJanie Lu 	}
11144df55fdeSJanie Lu 	tcam_ptr->ip4_tos_key = fspec_key->tos;
11154df55fdeSJanie Lu 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
11164df55fdeSJanie Lu }
11174df55fdeSJanie Lu 
11184df55fdeSJanie Lu static void
nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)11194df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
11204df55fdeSJanie Lu 	tcam_entry_t *tcam_ptr)
11214df55fdeSJanie Lu {
11224df55fdeSJanie Lu 	ahip6_spec_t *fspec_key;
11234df55fdeSJanie Lu 	ahip6_spec_t *fspec_mask;
11244df55fdeSJanie Lu 	p_nxge_class_pt_cfg_t p_class_cfgp;
11254df55fdeSJanie Lu 
11264df55fdeSJanie Lu 	fspec_key = (ahip6_spec_t *)&flow_spec->uh.ahip6spec;
11274df55fdeSJanie Lu 	fspec_mask = (ahip6_spec_t *)&flow_spec->um.ahip6spec;
11284df55fdeSJanie Lu 
11294df55fdeSJanie Lu 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
11304df55fdeSJanie Lu 	if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] &
11314df55fdeSJanie Lu 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
11324df55fdeSJanie Lu 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
11334df55fdeSJanie Lu 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
11344df55fdeSJanie Lu 	} else {
11354df55fdeSJanie Lu 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
11364df55fdeSJanie Lu 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
11374df55fdeSJanie Lu 	}
11384df55fdeSJanie Lu 
11394df55fdeSJanie Lu 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
11404df55fdeSJanie Lu 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6);
11414df55fdeSJanie Lu 
11424df55fdeSJanie Lu 	if (flow_spec->flow_type == FSPEC_AHIP6) {
11434df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
11444df55fdeSJanie Lu 		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH);
11454df55fdeSJanie Lu 	} else {
11464df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
11474df55fdeSJanie Lu 		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP);
11484df55fdeSJanie Lu 	}
11494df55fdeSJanie Lu 	tcam_ptr->ip6_port_key = fspec_key->spi;
11504df55fdeSJanie Lu 	tcam_ptr->ip6_port_mask = fspec_mask->spi;
11514df55fdeSJanie Lu 	tcam_ptr->ip6_tos_key = fspec_key->tos;
11524df55fdeSJanie Lu 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
11534df55fdeSJanie Lu }
11544df55fdeSJanie Lu 
11554df55fdeSJanie Lu /* ARGSUSED */
11564df55fdeSJanie Lu 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)11574df55fdeSJanie Lu nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec,
11584df55fdeSJanie Lu 	tcam_entry_t *tcam_ptr, tcam_class_t class)
11594df55fdeSJanie Lu {
11604df55fdeSJanie Lu 	ip_user_spec_t *fspec_key;
11614df55fdeSJanie Lu 	ip_user_spec_t *fspec_mask;
11624df55fdeSJanie Lu 
11634df55fdeSJanie Lu 	fspec_key = (ip_user_spec_t *)&flow_spec->uh.ip_usr_spec;
11644df55fdeSJanie Lu 	fspec_mask = (ip_user_spec_t *)&flow_spec->um.ip_usr_spec;
11654df55fdeSJanie Lu 
11664df55fdeSJanie Lu 	if (fspec_key->ip_ver == FSPEC_IP4) {
11674df55fdeSJanie Lu 		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
11684df55fdeSJanie Lu 		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
11694df55fdeSJanie Lu 		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
11704df55fdeSJanie Lu 		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
11714df55fdeSJanie Lu 
11724df55fdeSJanie Lu 		tcam_ptr->ip4_port_key = fspec_key->l4_4_bytes;
11734df55fdeSJanie Lu 		tcam_ptr->ip4_port_mask = fspec_mask->l4_4_bytes;
11744df55fdeSJanie Lu 
11754df55fdeSJanie Lu 		TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
11764df55fdeSJanie Lu 		    tcam_ptr->ip4_class_mask, class);
11774df55fdeSJanie Lu 
11784df55fdeSJanie Lu 		tcam_ptr->ip4_proto_key = fspec_key->proto;
11794df55fdeSJanie Lu 		tcam_ptr->ip4_proto_mask = fspec_mask->proto;
11804df55fdeSJanie Lu 
11814df55fdeSJanie Lu 		tcam_ptr->ip4_tos_key = fspec_key->tos;
11824df55fdeSJanie Lu 		tcam_ptr->ip4_tos_mask = fspec_mask->tos;
11834df55fdeSJanie Lu 	}
11844df55fdeSJanie Lu }
11854df55fdeSJanie Lu 
11864df55fdeSJanie Lu 
11876f45ec7bSml29623 nxge_status_t
nxge_flow_get_hash(p_nxge_t nxgep,flow_resource_t * flow_res,uint32_t * H1,uint16_t * H2)11886f45ec7bSml29623 nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res,
11896f45ec7bSml29623 	uint32_t *H1, uint16_t *H2)
11906f45ec7bSml29623 {
11916f45ec7bSml29623 	flow_spec_t *flow_spec;
11926f45ec7bSml29623 	uint32_t class_cfg;
11936f45ec7bSml29623 	flow_template_t ft;
11946f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
11956f45ec7bSml29623 
11966f45ec7bSml29623 	int ft_size = sizeof (flow_template_t);
11976f45ec7bSml29623 
11986f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash"));
11996f45ec7bSml29623 
12006f45ec7bSml29623 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
12016f45ec7bSml29623 	bzero((char *)&ft, ft_size);
12026f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
12036f45ec7bSml29623 
12046f45ec7bSml29623 	switch (flow_spec->flow_type) {
12056f45ec7bSml29623 	case FSPEC_TCPIP4:
12066f45ec7bSml29623 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4];
12076f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
12086f45ec7bSml29623 			ft.ip_proto = IPPROTO_TCP;
12096f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
12106f45ec7bSml29623 			ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src;
12116f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
12126f45ec7bSml29623 			ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst;
12136f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
12146f45ec7bSml29623 			ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc;
12156f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
12166f45ec7bSml29623 			ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst;
12176f45ec7bSml29623 		break;
12186f45ec7bSml29623 
12196f45ec7bSml29623 	case FSPEC_UDPIP4:
12206f45ec7bSml29623 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4];
12216f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
12226f45ec7bSml29623 			ft.ip_proto = IPPROTO_UDP;
12236f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
12246f45ec7bSml29623 			ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src;
12256f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
12266f45ec7bSml29623 			ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst;
12276f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
12286f45ec7bSml29623 			ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc;
12296f45ec7bSml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
12306f45ec7bSml29623 			ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst;
12316f45ec7bSml29623 		break;
12326f45ec7bSml29623 
12336f45ec7bSml29623 	default:
12346f45ec7bSml29623 		return (NXGE_ERROR);
12356f45ec7bSml29623 	}
12366f45ec7bSml29623 
12376f45ec7bSml29623 	*H1 = nxge_compute_h1(p_class_cfgp->init_h1,
12386f45ec7bSml29623 	    (uint32_t *)&ft, ft_size) & 0xfffff;
12396f45ec7bSml29623 	*H2 = nxge_compute_h2(p_class_cfgp->init_h2,
12406f45ec7bSml29623 	    (uint8_t *)&ft, ft_size);
12416f45ec7bSml29623 
12426f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash"));
12436f45ec7bSml29623 	return (NXGE_OK);
12446f45ec7bSml29623 }
12456f45ec7bSml29623 
12466f45ec7bSml29623 nxge_status_t
nxge_add_fcram_entry(p_nxge_t nxgep,flow_resource_t * flow_res)12476f45ec7bSml29623 nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
12486f45ec7bSml29623 {
12496f45ec7bSml29623 	uint32_t H1;
12506f45ec7bSml29623 	uint16_t H2;
12516f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
12526f45ec7bSml29623 
12536f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry"));
12546f45ec7bSml29623 	status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2);
12556f45ec7bSml29623 	if (status != NXGE_OK) {
12566f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
12576f45ec7bSml29623 		    " nxge_add_fcram_entry failed "));
12586f45ec7bSml29623 		return (status);
12596f45ec7bSml29623 	}
12606f45ec7bSml29623 
12616f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry"));
12626f45ec7bSml29623 	return (NXGE_OK);
12636f45ec7bSml29623 }
12646f45ec7bSml29623 
12656f45ec7bSml29623 /*
12666f45ec7bSml29623  * Already decided this flow goes into the tcam
12676f45ec7bSml29623  */
12686f45ec7bSml29623 
12696f45ec7bSml29623 nxge_status_t
nxge_add_tcam_entry(p_nxge_t nxgep,flow_resource_t * flow_res)12706f45ec7bSml29623 nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
12716f45ec7bSml29623 {
12726f45ec7bSml29623 	npi_handle_t handle;
12734df55fdeSJanie Lu 	uint64_t channel_cookie;
12744df55fdeSJanie Lu 	uint64_t flow_cookie;
12756f45ec7bSml29623 	flow_spec_t *flow_spec;
12766f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
12776f45ec7bSml29623 	tcam_entry_t tcam_ptr;
12784df55fdeSJanie Lu 	tcam_location_t location;
12796f45ec7bSml29623 	uint8_t offset, rdc_grp;
12806f45ec7bSml29623 	p_nxge_hw_list_t hw_p;
12814df55fdeSJanie Lu 	uint64_t class;
12826f45ec7bSml29623 
12836f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry"));
12846f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
12856f45ec7bSml29623 
12866f45ec7bSml29623 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
12876f45ec7bSml29623 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
12886f45ec7bSml29623 	flow_cookie = flow_res->flow_cookie;
12896f45ec7bSml29623 	channel_cookie = flow_res->channel_cookie;
12904df55fdeSJanie Lu 	location = (tcam_location_t)nxge_tcam_get_index(nxgep,
12914df55fdeSJanie Lu 	    (uint16_t)flow_res->location);
12924df55fdeSJanie Lu 
12934df55fdeSJanie Lu 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
12944df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
12954df55fdeSJanie Lu 		    " nxge_add_tcam_entry: common hardware not set",
12964df55fdeSJanie Lu 		    nxgep->niu_type));
12974df55fdeSJanie Lu 		return (NXGE_ERROR);
12984df55fdeSJanie Lu 	}
12994df55fdeSJanie Lu 
13004df55fdeSJanie Lu 	if (flow_spec->flow_type == FSPEC_IP_USR) {
13014df55fdeSJanie Lu 		int i;
13024df55fdeSJanie Lu 		int add_usr_cls = 0;
13034df55fdeSJanie Lu 		int ipv6 = 0;
13044df55fdeSJanie Lu 		ip_user_spec_t *uspec = &flow_spec->uh.ip_usr_spec;
13054df55fdeSJanie Lu 		ip_user_spec_t *umask = &flow_spec->um.ip_usr_spec;
13064df55fdeSJanie Lu 		nxge_usr_l3_cls_t *l3_ucls_p;
13074df55fdeSJanie Lu 
13084df55fdeSJanie Lu 		MUTEX_ENTER(&hw_p->nxge_tcam_lock);
13094df55fdeSJanie Lu 
13104df55fdeSJanie Lu 		for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
13114df55fdeSJanie Lu 			l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
13124df55fdeSJanie Lu 			if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) {
13134df55fdeSJanie Lu 				if (uspec->proto == l3_ucls_p->pid) {
13144df55fdeSJanie Lu 					class = l3_ucls_p->cls;
13154df55fdeSJanie Lu 					l3_ucls_p->tcam_ref_cnt++;
13164df55fdeSJanie Lu 					add_usr_cls = 1;
13174df55fdeSJanie Lu 					break;
13184df55fdeSJanie Lu 				}
13194df55fdeSJanie Lu 			} else if (l3_ucls_p->valid == 0) {
13204df55fdeSJanie Lu 				/* Program new user IP class */
13214df55fdeSJanie Lu 				switch (i) {
13224df55fdeSJanie Lu 				case 0:
13234df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_4;
13244df55fdeSJanie Lu 					break;
13254df55fdeSJanie Lu 				case 1:
13264df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_5;
13274df55fdeSJanie Lu 					break;
13284df55fdeSJanie Lu 				case 2:
13294df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_6;
13304df55fdeSJanie Lu 					break;
13314df55fdeSJanie Lu 				case 3:
13324df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_7;
13334df55fdeSJanie Lu 					break;
13344df55fdeSJanie Lu 				default:
13354df55fdeSJanie Lu 					break;
13364df55fdeSJanie Lu 				}
13374df55fdeSJanie Lu 				if (uspec->ip_ver == FSPEC_IP6)
13384df55fdeSJanie Lu 					ipv6 = 1;
13394df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
13404df55fdeSJanie Lu 				    (tcam_class_t)class, uspec->tos,
13414df55fdeSJanie Lu 				    umask->tos, uspec->proto, ipv6);
13424df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
13434df55fdeSJanie Lu 					goto fail;
13444df55fdeSJanie Lu 
13454df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
13464df55fdeSJanie Lu 				    (tcam_class_t)class);
13474df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
13484df55fdeSJanie Lu 					goto fail;
13494df55fdeSJanie Lu 
13504df55fdeSJanie Lu 				l3_ucls_p->cls = class;
13514df55fdeSJanie Lu 				l3_ucls_p->pid = uspec->proto;
13524df55fdeSJanie Lu 				l3_ucls_p->tcam_ref_cnt++;
13534df55fdeSJanie Lu 				l3_ucls_p->valid = 1;
13544df55fdeSJanie Lu 				add_usr_cls = 1;
13554df55fdeSJanie Lu 				break;
13564df55fdeSJanie Lu 			} else if (l3_ucls_p->tcam_ref_cnt == 0 &&
13574df55fdeSJanie Lu 			    uspec->proto == l3_ucls_p->pid) {
13584df55fdeSJanie Lu 				/*
13594df55fdeSJanie Lu 				 * The class has already been programmed,
13604df55fdeSJanie Lu 				 * probably for flow hash
13614df55fdeSJanie Lu 				 */
13624df55fdeSJanie Lu 				class = l3_ucls_p->cls;
13634df55fdeSJanie Lu 				if (uspec->ip_ver == FSPEC_IP6)
13644df55fdeSJanie Lu 					ipv6 = 1;
13654df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
13664df55fdeSJanie Lu 				    (tcam_class_t)class, uspec->tos,
13674df55fdeSJanie Lu 				    umask->tos, uspec->proto, ipv6);
13684df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
13694df55fdeSJanie Lu 					goto fail;
13704df55fdeSJanie Lu 
13714df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
13724df55fdeSJanie Lu 				    (tcam_class_t)class);
13734df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
13744df55fdeSJanie Lu 					goto fail;
13754df55fdeSJanie Lu 
13764df55fdeSJanie Lu 				l3_ucls_p->pid = uspec->proto;
13774df55fdeSJanie Lu 				l3_ucls_p->tcam_ref_cnt++;
13784df55fdeSJanie Lu 				add_usr_cls = 1;
13794df55fdeSJanie Lu 				break;
13804df55fdeSJanie Lu 			}
13814df55fdeSJanie Lu 		}
13824df55fdeSJanie Lu 		if (!add_usr_cls) {
13834df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13844df55fdeSJanie Lu 			    "nxge_add_tcam_entry: Could not find/insert class"
13854df55fdeSJanie Lu 			    "for pid %d", uspec->proto));
13864df55fdeSJanie Lu 			goto fail;
13874df55fdeSJanie Lu 		}
13884df55fdeSJanie Lu 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
13894df55fdeSJanie Lu 	}
13906f45ec7bSml29623 
13916f45ec7bSml29623 	switch (flow_spec->flow_type) {
13926f45ec7bSml29623 	case FSPEC_TCPIP4:
13936f45ec7bSml29623 		nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr);
13946f45ec7bSml29623 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4,
13956f45ec7bSml29623 		    flow_cookie);
13966f45ec7bSml29623 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4,
13976f45ec7bSml29623 		    channel_cookie);
13986f45ec7bSml29623 		break;
13996f45ec7bSml29623 
14006f45ec7bSml29623 	case FSPEC_UDPIP4:
14016f45ec7bSml29623 		nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr);
14026f45ec7bSml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
14036f45ec7bSml29623 		    TCAM_CLASS_UDP_IPV4,
14046f45ec7bSml29623 		    flow_cookie);
14056f45ec7bSml29623 		offset = nxge_get_rdc_offset(nxgep,
14066f45ec7bSml29623 		    TCAM_CLASS_UDP_IPV4,
14076f45ec7bSml29623 		    channel_cookie);
14086f45ec7bSml29623 		break;
14096f45ec7bSml29623 
14106f45ec7bSml29623 	case FSPEC_TCPIP6:
14116f45ec7bSml29623 		nxge_fill_tcam_entry_tcp_ipv6(nxgep,
14126f45ec7bSml29623 		    flow_spec, &tcam_ptr);
14136f45ec7bSml29623 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6,
14146f45ec7bSml29623 		    flow_cookie);
14156f45ec7bSml29623 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6,
14166f45ec7bSml29623 		    channel_cookie);
14176f45ec7bSml29623 		break;
14186f45ec7bSml29623 
14196f45ec7bSml29623 	case FSPEC_UDPIP6:
14206f45ec7bSml29623 		nxge_fill_tcam_entry_udp_ipv6(nxgep,
14216f45ec7bSml29623 		    flow_spec, &tcam_ptr);
14226f45ec7bSml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
14236f45ec7bSml29623 		    TCAM_CLASS_UDP_IPV6,
14244df55fdeSJanie Lu 		    flow_cookie);
14256f45ec7bSml29623 		offset = nxge_get_rdc_offset(nxgep,
14266f45ec7bSml29623 		    TCAM_CLASS_UDP_IPV6,
14274df55fdeSJanie Lu 		    channel_cookie);
14286f45ec7bSml29623 		break;
14296f45ec7bSml29623 
14306f45ec7bSml29623 	case FSPEC_SCTPIP4:
14316f45ec7bSml29623 		nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr);
14326f45ec7bSml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
14336f45ec7bSml29623 		    TCAM_CLASS_SCTP_IPV4,
14344df55fdeSJanie Lu 		    flow_cookie);
14356f45ec7bSml29623 		offset = nxge_get_rdc_offset(nxgep,
14366f45ec7bSml29623 		    TCAM_CLASS_SCTP_IPV4,
14374df55fdeSJanie Lu 		    channel_cookie);
14386f45ec7bSml29623 		break;
14396f45ec7bSml29623 
14406f45ec7bSml29623 	case FSPEC_SCTPIP6:
14416f45ec7bSml29623 		nxge_fill_tcam_entry_sctp_ipv6(nxgep,
14426f45ec7bSml29623 		    flow_spec, &tcam_ptr);
14436f45ec7bSml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
14446f45ec7bSml29623 		    TCAM_CLASS_SCTP_IPV6,
14454df55fdeSJanie Lu 		    flow_cookie);
14466f45ec7bSml29623 		offset = nxge_get_rdc_offset(nxgep,
14476f45ec7bSml29623 		    TCAM_CLASS_SCTP_IPV6,
14484df55fdeSJanie Lu 		    channel_cookie);
14496f45ec7bSml29623 		break;
14506f45ec7bSml29623 
14514df55fdeSJanie Lu 	case FSPEC_AHIP4:
14524df55fdeSJanie Lu 	case FSPEC_ESPIP4:
14534df55fdeSJanie Lu 		nxge_fill_tcam_entry_ah_esp(nxgep, flow_spec, &tcam_ptr);
14544df55fdeSJanie Lu 		rdc_grp = nxge_get_rdc_group(nxgep,
14554df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV4,
14564df55fdeSJanie Lu 		    flow_cookie);
14574df55fdeSJanie Lu 		offset = nxge_get_rdc_offset(nxgep,
14584df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV4,
14594df55fdeSJanie Lu 		    channel_cookie);
14604df55fdeSJanie Lu 		break;
14614df55fdeSJanie Lu 
14624df55fdeSJanie Lu 	case FSPEC_AHIP6:
14634df55fdeSJanie Lu 	case FSPEC_ESPIP6:
14644df55fdeSJanie Lu 		nxge_fill_tcam_entry_ah_esp_ipv6(nxgep,
14654df55fdeSJanie Lu 		    flow_spec, &tcam_ptr);
14664df55fdeSJanie Lu 		rdc_grp = nxge_get_rdc_group(nxgep,
14674df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV6,
14684df55fdeSJanie Lu 		    flow_cookie);
14694df55fdeSJanie Lu 		offset = nxge_get_rdc_offset(nxgep,
14704df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV6,
14714df55fdeSJanie Lu 		    channel_cookie);
14724df55fdeSJanie Lu 		break;
14734df55fdeSJanie Lu 
14744df55fdeSJanie Lu 	case FSPEC_IP_USR:
14754df55fdeSJanie Lu 		nxge_fill_tcam_entry_ip_usr(nxgep, flow_spec, &tcam_ptr,
14764df55fdeSJanie Lu 		    (tcam_class_t)class);
14774df55fdeSJanie Lu 		rdc_grp = nxge_get_rdc_group(nxgep,
14784df55fdeSJanie Lu 		    (tcam_class_t)class, flow_cookie);
14794df55fdeSJanie Lu 		offset = nxge_get_rdc_offset(nxgep,
14804df55fdeSJanie Lu 		    (tcam_class_t)class, channel_cookie);
14814df55fdeSJanie Lu 		break;
14826f45ec7bSml29623 	default:
14834df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14844df55fdeSJanie Lu 		    "nxge_add_tcam_entry: Unknown flow spec 0x%x",
14854df55fdeSJanie Lu 		    flow_spec->flow_type));
14864df55fdeSJanie Lu 		return (NXGE_ERROR);
14876f45ec7bSml29623 	}
14886f45ec7bSml29623 
14896f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
14906f45ec7bSml29623 	    " nxge_add_tcam_entry write"
14916f45ec7bSml29623 	    " for location %d offset %d", location, offset));
14926f45ec7bSml29623 
14936f45ec7bSml29623 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
14946f45ec7bSml29623 	rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr);
14956f45ec7bSml29623 
14966f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
14976f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14986f45ec7bSml29623 		    " nxge_add_tcam_entry write"
14996f45ec7bSml29623 		    " failed for location %d", location));
15004df55fdeSJanie Lu 		goto fail;
15016f45ec7bSml29623 	}
15026f45ec7bSml29623 
15036f45ec7bSml29623 	tcam_ptr.match_action.value = 0;
15046f45ec7bSml29623 	tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp;
15056f45ec7bSml29623 	tcam_ptr.match_action.bits.ldw.offset = offset;
15066f45ec7bSml29623 	tcam_ptr.match_action.bits.ldw.tres =
15076f45ec7bSml29623 	    TRES_TERM_OVRD_L2RDC;
15084df55fdeSJanie Lu 	if (channel_cookie == NXGE_PKT_DISCARD)
15096f45ec7bSml29623 		tcam_ptr.match_action.bits.ldw.disc = 1;
15106f45ec7bSml29623 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
15116f45ec7bSml29623 	    location, tcam_ptr.match_action.value);
15126f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
15136f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15146f45ec7bSml29623 		    " nxge_add_tcam_entry write"
15156f45ec7bSml29623 		    " failed for ASC RAM location %d", location));
15164df55fdeSJanie Lu 		goto fail;
15176f45ec7bSml29623 	}
15186f45ec7bSml29623 	bcopy((void *) &tcam_ptr,
15196f45ec7bSml29623 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
15206f45ec7bSml29623 	    sizeof (tcam_entry_t));
15214df55fdeSJanie Lu 	nxgep->classifier.tcam_entry_cnt++;
15224df55fdeSJanie Lu 	nxgep->classifier.tcam_entries[location].valid = 1;
15236f45ec7bSml29623 
15246f45ec7bSml29623 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15256f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry"));
15266f45ec7bSml29623 	return (NXGE_OK);
15274df55fdeSJanie Lu fail:
15284df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15294df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_tcam_entry FAILED"));
15304df55fdeSJanie Lu 	return (NXGE_ERROR);
15316f45ec7bSml29623 }
15326f45ec7bSml29623 
15336f45ec7bSml29623 static nxge_status_t
nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)15346f45ec7bSml29623 nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)
15356f45ec7bSml29623 {
15366f45ec7bSml29623 	tcam_entry_t tcam_ptr;
15376f45ec7bSml29623 	tcam_location_t location;
15386f45ec7bSml29623 	uint8_t class;
15396f45ec7bSml29623 	uint32_t class_config;
15406f45ec7bSml29623 	npi_handle_t handle;
15416f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
15426f45ec7bSml29623 	p_nxge_hw_list_t hw_p;
15436f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
15446f45ec7bSml29623 
15456f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
15466f45ec7bSml29623 	class = 0;
15476f45ec7bSml29623 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
15486f45ec7bSml29623 	tcam_ptr.ip4_noport_key = 1;
15496f45ec7bSml29623 	tcam_ptr.ip4_noport_mask = 1;
15506f45ec7bSml29623 	location = nxgep->function_num;
15516f45ec7bSml29623 	nxgep->classifier.fragment_bug_location = location;
15526f45ec7bSml29623 
15536f45ec7bSml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
15546f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
155552ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment: common hardware not set",
15566f45ec7bSml29623 		    nxgep->niu_type));
15576f45ec7bSml29623 		return (NXGE_ERROR);
15586f45ec7bSml29623 	}
15596f45ec7bSml29623 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
15606f45ec7bSml29623 	rs = npi_fflp_tcam_entry_write(handle,
15616f45ec7bSml29623 	    location, &tcam_ptr);
15626f45ec7bSml29623 
15636f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
15646f45ec7bSml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15656f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15666f45ec7bSml29623 		    " nxge_tcam_handle_ip_fragment "
15676f45ec7bSml29623 		    " tcam_entry write"
15686f45ec7bSml29623 		    " failed for location %d", location));
15696f45ec7bSml29623 		return (NXGE_ERROR);
15706f45ec7bSml29623 	}
15716f45ec7bSml29623 	tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp;
15726f45ec7bSml29623 	tcam_ptr.match_action.bits.ldw.offset = 0;	/* use the default */
15736f45ec7bSml29623 	tcam_ptr.match_action.bits.ldw.tres =
15746f45ec7bSml29623 	    TRES_TERM_USE_OFFSET;
15756f45ec7bSml29623 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
15766f45ec7bSml29623 	    location, tcam_ptr.match_action.value);
15776f45ec7bSml29623 
15786f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
15796f45ec7bSml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15806f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep,
15816f45ec7bSml29623 		    FFLP_CTL,
15826f45ec7bSml29623 		    " nxge_tcam_handle_ip_fragment "
15836f45ec7bSml29623 		    " tcam_entry write"
15846f45ec7bSml29623 		    " failed for ASC RAM location %d", location));
15856f45ec7bSml29623 		return (NXGE_ERROR);
15866f45ec7bSml29623 	}
15876f45ec7bSml29623 	bcopy((void *) &tcam_ptr,
15886f45ec7bSml29623 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
15896f45ec7bSml29623 	    sizeof (tcam_entry_t));
15904df55fdeSJanie Lu 	nxgep->classifier.tcam_entry_cnt++;
15914df55fdeSJanie Lu 	nxgep->classifier.tcam_entries[location].valid = 1;
15926f45ec7bSml29623 	for (class = TCAM_CLASS_TCP_IPV4;
15936f45ec7bSml29623 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
15946f45ec7bSml29623 		class_config = nxgep->class_config.class_cfg[class];
15956f45ec7bSml29623 		class_config |= NXGE_CLASS_TCAM_LOOKUP;
15966f45ec7bSml29623 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
15976f45ec7bSml29623 
15986f45ec7bSml29623 		if (status & NPI_FFLP_ERROR) {
15996f45ec7bSml29623 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
16006f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16016f45ec7bSml29623 			    "nxge_tcam_handle_ip_fragment "
16026f45ec7bSml29623 			    "nxge_fflp_ip_class_config failed "
16036f45ec7bSml29623 			    " class %d config %x ", class, class_config));
16046f45ec7bSml29623 			return (NXGE_ERROR);
16056f45ec7bSml29623 		}
16066f45ec7bSml29623 	}
16076f45ec7bSml29623 
16086f45ec7bSml29623 	rs = npi_fflp_cfg_tcam_enable(handle);
16096f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
16106f45ec7bSml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
16116f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16126f45ec7bSml29623 		    "nxge_tcam_handle_ip_fragment "
16136f45ec7bSml29623 		    " nxge_fflp_config_tcam_enable failed"));
16146f45ec7bSml29623 		return (NXGE_ERROR);
16156f45ec7bSml29623 	}
16166f45ec7bSml29623 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
16176f45ec7bSml29623 	return (NXGE_OK);
16186f45ec7bSml29623 }
16196f45ec7bSml29623 
16206f45ec7bSml29623 /* ARGSUSED */
16216f45ec7bSml29623 static int
nxge_flow_need_hash_lookup(p_nxge_t nxgep,flow_resource_t * flow_res)16226f45ec7bSml29623 nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res)
16236f45ec7bSml29623 {
16246f45ec7bSml29623 	return (0);
16256f45ec7bSml29623 }
16266f45ec7bSml29623 
16276f45ec7bSml29623 nxge_status_t
nxge_add_flow(p_nxge_t nxgep,flow_resource_t * flow_res)16286f45ec7bSml29623 nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res)
16296f45ec7bSml29623 {
16306f45ec7bSml29623 
16316f45ec7bSml29623 	int insert_hash = 0;
16326f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
16336f45ec7bSml29623 
16342e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
16356f45ec7bSml29623 		/* determine whether to do TCAM or Hash flow */
16366f45ec7bSml29623 		insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res);
16376f45ec7bSml29623 	}
16386f45ec7bSml29623 	if (insert_hash) {
16396f45ec7bSml29623 		status = nxge_add_fcram_entry(nxgep, flow_res);
16406f45ec7bSml29623 	} else {
16416f45ec7bSml29623 		status = nxge_add_tcam_entry(nxgep, flow_res);
16426f45ec7bSml29623 	}
16436f45ec7bSml29623 	return (status);
16446f45ec7bSml29623 }
16456f45ec7bSml29623 
16466f45ec7bSml29623 void
nxge_put_tcam(p_nxge_t nxgep,p_mblk_t mp)16476f45ec7bSml29623 nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp)
16486f45ec7bSml29623 {
16496f45ec7bSml29623 	flow_resource_t *fs;
16506f45ec7bSml29623 
16516f45ec7bSml29623 	fs = (flow_resource_t *)mp->b_rptr;
16526f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16536f45ec7bSml29623 	    "nxge_put_tcam addr fs $%p  type %x offset %x",
16546f45ec7bSml29623 	    fs, fs->flow_spec.flow_type, fs->channel_cookie));
16556f45ec7bSml29623 	(void) nxge_add_tcam_entry(nxgep, fs);
16566f45ec7bSml29623 }
16576f45ec7bSml29623 
16586f45ec7bSml29623 nxge_status_t
nxge_fflp_config_tcam_enable(p_nxge_t nxgep)16596f45ec7bSml29623 nxge_fflp_config_tcam_enable(p_nxge_t nxgep)
16606f45ec7bSml29623 {
16616f45ec7bSml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
16626f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
16636f45ec7bSml29623 
16646f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable"));
16656f45ec7bSml29623 	rs = npi_fflp_cfg_tcam_enable(handle);
16666f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
16676f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16686f45ec7bSml29623 		    " nxge_fflp_config_tcam_enable failed"));
16696f45ec7bSml29623 		return (NXGE_ERROR | rs);
16706f45ec7bSml29623 	}
16716f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable"));
16726f45ec7bSml29623 	return (NXGE_OK);
16736f45ec7bSml29623 }
16746f45ec7bSml29623 
16756f45ec7bSml29623 nxge_status_t
nxge_fflp_config_tcam_disable(p_nxge_t nxgep)16766f45ec7bSml29623 nxge_fflp_config_tcam_disable(p_nxge_t nxgep)
16776f45ec7bSml29623 {
16786f45ec7bSml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
16796f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
16806f45ec7bSml29623 
16816f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
16826f45ec7bSml29623 	    " ==> nxge_fflp_config_tcam_disable"));
16836f45ec7bSml29623 	rs = npi_fflp_cfg_tcam_disable(handle);
16846f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
16856f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16866f45ec7bSml29623 		    " nxge_fflp_config_tcam_disable failed"));
16876f45ec7bSml29623 		return (NXGE_ERROR | rs);
16886f45ec7bSml29623 	}
16896f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
16906f45ec7bSml29623 	    " <== nxge_fflp_config_tcam_disable"));
16916f45ec7bSml29623 	return (NXGE_OK);
16926f45ec7bSml29623 }
16936f45ec7bSml29623 
16946f45ec7bSml29623 nxge_status_t
nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)16956f45ec7bSml29623 nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)
16966f45ec7bSml29623 {
16976f45ec7bSml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
16986f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
16996f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
17006f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
17016f45ec7bSml29623 	uint8_t partition;
17026f45ec7bSml29623 
17036f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17046f45ec7bSml29623 	    " ==> nxge_fflp_config_hash_lookup_enable"));
17056f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
17066f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
17076f45ec7bSml29623 
1708678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1709678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
1710678453a8Sspeer 			rs = npi_fflp_cfg_fcram_partition_enable(
1711678453a8Sspeer 			    handle, partition);
17126f45ec7bSml29623 			if (rs != NPI_SUCCESS) {
17136f45ec7bSml29623 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17146f45ec7bSml29623 				    " nxge_fflp_config_hash_lookup_enable"
17156f45ec7bSml29623 				    "failed FCRAM partition"
17166f45ec7bSml29623 				    " enable for partition %d ", partition));
17176f45ec7bSml29623 				return (NXGE_ERROR | rs);
17186f45ec7bSml29623 			}
17196f45ec7bSml29623 		}
1720678453a8Sspeer 	}
17216f45ec7bSml29623 
17226f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17236f45ec7bSml29623 	    " <== nxge_fflp_config_hash_lookup_enable"));
17246f45ec7bSml29623 	return (NXGE_OK);
17256f45ec7bSml29623 }
17266f45ec7bSml29623 
17276f45ec7bSml29623 nxge_status_t
nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)17286f45ec7bSml29623 nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)
17296f45ec7bSml29623 {
17306f45ec7bSml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
17316f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
17326f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
17336f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
17346f45ec7bSml29623 	uint8_t partition;
17356f45ec7bSml29623 
17366f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17376f45ec7bSml29623 	    " ==> nxge_fflp_config_hash_lookup_disable"));
17386f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
17396f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
17406f45ec7bSml29623 
1741678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1742678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
17436f45ec7bSml29623 			rs = npi_fflp_cfg_fcram_partition_disable(handle,
17446f45ec7bSml29623 			    partition);
17456f45ec7bSml29623 			if (rs != NPI_SUCCESS) {
17466f45ec7bSml29623 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17476f45ec7bSml29623 				    " nxge_fflp_config_hash_lookup_disable"
17486f45ec7bSml29623 				    " failed FCRAM partition"
17496f45ec7bSml29623 				    " disable for partition %d ", partition));
17506f45ec7bSml29623 				return (NXGE_ERROR | rs);
17516f45ec7bSml29623 			}
17526f45ec7bSml29623 		}
1753678453a8Sspeer 	}
17546f45ec7bSml29623 
17556f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17566f45ec7bSml29623 	    " <== nxge_fflp_config_hash_lookup_disable"));
17576f45ec7bSml29623 	return (NXGE_OK);
17586f45ec7bSml29623 }
17596f45ec7bSml29623 
17606f45ec7bSml29623 nxge_status_t
nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)17616f45ec7bSml29623 nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)
17626f45ec7bSml29623 {
17636f45ec7bSml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
17646f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
17656f45ec7bSml29623 
17666f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17676f45ec7bSml29623 	    " ==> nxge_fflp_config_llc_snap_enable"));
17686f45ec7bSml29623 	rs = npi_fflp_cfg_llcsnap_enable(handle);
17696f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
17706f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17716f45ec7bSml29623 		    " nxge_fflp_config_llc_snap_enable failed"));
17726f45ec7bSml29623 		return (NXGE_ERROR | rs);
17736f45ec7bSml29623 	}
17746f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17756f45ec7bSml29623 	    " <== nxge_fflp_config_llc_snap_enable"));
17766f45ec7bSml29623 	return (NXGE_OK);
17776f45ec7bSml29623 }
17786f45ec7bSml29623 
17796f45ec7bSml29623 nxge_status_t
nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)17806f45ec7bSml29623 nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)
17816f45ec7bSml29623 {
17826f45ec7bSml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
17836f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
17846f45ec7bSml29623 
17856f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17866f45ec7bSml29623 	    " ==> nxge_fflp_config_llc_snap_disable"));
17876f45ec7bSml29623 	rs = npi_fflp_cfg_llcsnap_disable(handle);
17886f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
17896f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17906f45ec7bSml29623 		    " nxge_fflp_config_llc_snap_disable failed"));
17916f45ec7bSml29623 		return (NXGE_ERROR | rs);
17926f45ec7bSml29623 	}
17936f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17946f45ec7bSml29623 	    " <== nxge_fflp_config_llc_snap_disable"));
17956f45ec7bSml29623 	return (NXGE_OK);
17966f45ec7bSml29623 }
17976f45ec7bSml29623 
17986f45ec7bSml29623 nxge_status_t
nxge_fflp_ip_usr_class_config(p_nxge_t nxgep,tcam_class_t class,uint32_t config)17996f45ec7bSml29623 nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class,
18006f45ec7bSml29623 	uint32_t config)
18016f45ec7bSml29623 {
18026f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
18036f45ec7bSml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
18046f45ec7bSml29623 	uint8_t tos, tos_mask, proto, ver = 0;
18056f45ec7bSml29623 	uint8_t class_enable = 0;
18066f45ec7bSml29623 
18076f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config"));
18086f45ec7bSml29623 
18096f45ec7bSml29623 	tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >>
18106f45ec7bSml29623 	    NXGE_CLASS_CFG_IP_TOS_SHIFT;
18116f45ec7bSml29623 	tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >>
18126f45ec7bSml29623 	    NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT;
18136f45ec7bSml29623 	proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >>
18146f45ec7bSml29623 	    NXGE_CLASS_CFG_IP_PROTO_SHIFT;
18156f45ec7bSml29623 	if (config & NXGE_CLASS_CFG_IP_IPV6_MASK)
18166f45ec7bSml29623 		ver = 1;
18176f45ec7bSml29623 	if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK)
18186f45ec7bSml29623 		class_enable = 1;
18196f45ec7bSml29623 	rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask,
18206f45ec7bSml29623 	    proto, ver);
18216f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
18226f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18236f45ec7bSml29623 		    " nxge_fflp_ip_usr_class_config"
18246f45ec7bSml29623 		    " for class %d failed ", class));
18256f45ec7bSml29623 		return (NXGE_ERROR | rs);
18266f45ec7bSml29623 	}
18276f45ec7bSml29623 	if (class_enable)
18286f45ec7bSml29623 		rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class);
18296f45ec7bSml29623 	else
18306f45ec7bSml29623 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
18316f45ec7bSml29623 
18326f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
18336f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18346f45ec7bSml29623 		    " nxge_fflp_ip_usr_class_config"
18356f45ec7bSml29623 		    " TCAM enable/disable for class %d failed ", class));
18366f45ec7bSml29623 		return (NXGE_ERROR | rs);
18376f45ec7bSml29623 	}
18386f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config"));
18396f45ec7bSml29623 	return (NXGE_OK);
18406f45ec7bSml29623 }
18416f45ec7bSml29623 
18426f45ec7bSml29623 nxge_status_t
nxge_fflp_ip_class_config(p_nxge_t nxgep,tcam_class_t class,uint32_t config)18436f45ec7bSml29623 nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config)
18446f45ec7bSml29623 {
18456f45ec7bSml29623 	uint32_t class_config;
18466f45ec7bSml29623 	nxge_status_t t_status = NXGE_OK;
18476f45ec7bSml29623 	nxge_status_t f_status = NXGE_OK;
18486f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
18496f45ec7bSml29623 
18506f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
18516f45ec7bSml29623 
18526f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
18536f45ec7bSml29623 	class_config = p_class_cfgp->class_cfg[class];
18546f45ec7bSml29623 
18556f45ec7bSml29623 	if (class_config != config) {
18566f45ec7bSml29623 		p_class_cfgp->class_cfg[class] = config;
18576f45ec7bSml29623 		class_config = config;
18586f45ec7bSml29623 	}
18596f45ec7bSml29623 
18606f45ec7bSml29623 	t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config);
18616f45ec7bSml29623 	f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config);
18626f45ec7bSml29623 
18636f45ec7bSml29623 	if (t_status & NPI_FFLP_ERROR) {
18646f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
18656f45ec7bSml29623 		    " nxge_fflp_ip_class_config %x"
18666f45ec7bSml29623 		    " for class %d tcam failed", config, class));
18676f45ec7bSml29623 		return (t_status);
18686f45ec7bSml29623 	}
18696f45ec7bSml29623 	if (f_status & NPI_FFLP_ERROR) {
18706f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18716f45ec7bSml29623 		    " nxge_fflp_ip_class_config %x"
18726f45ec7bSml29623 		    " for class %d flow key failed", config, class));
18736f45ec7bSml29623 		return (f_status);
18746f45ec7bSml29623 	}
18756f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
18766f45ec7bSml29623 	return (NXGE_OK);
18776f45ec7bSml29623 }
18786f45ec7bSml29623 
18796f45ec7bSml29623 nxge_status_t
nxge_fflp_ip_class_config_get(p_nxge_t nxgep,tcam_class_t class,uint32_t * config)18806f45ec7bSml29623 nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class,
18816f45ec7bSml29623 	uint32_t *config)
18826f45ec7bSml29623 {
18836f45ec7bSml29623 	uint32_t t_class_config, f_class_config;
18846f45ec7bSml29623 	int t_status = NXGE_OK;
18856f45ec7bSml29623 	int f_status = NXGE_OK;
18866f45ec7bSml29623 
18876f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
18886f45ec7bSml29623 
18896f45ec7bSml29623 	t_class_config = f_class_config = 0;
18906f45ec7bSml29623 	t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config);
18916f45ec7bSml29623 	f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config);
18926f45ec7bSml29623 
18936f45ec7bSml29623 	if (t_status & NPI_FFLP_ERROR) {
18946f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18956f45ec7bSml29623 		    " nxge_fflp_ip_class_config_get  "
18966f45ec7bSml29623 		    " for class %d tcam failed", class));
18976f45ec7bSml29623 		return (t_status);
18986f45ec7bSml29623 	}
18996f45ec7bSml29623 
19006f45ec7bSml29623 	if (f_status & NPI_FFLP_ERROR) {
19016f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
19026f45ec7bSml29623 		    " nxge_fflp_ip_class_config_get  "
19036f45ec7bSml29623 		    " for class %d flow key failed", class));
19046f45ec7bSml29623 		return (f_status);
19056f45ec7bSml29623 	}
19066f45ec7bSml29623 
19076f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
19086f45ec7bSml29623 	    " nxge_fflp_ip_class_config tcam %x flow %x",
19096f45ec7bSml29623 	    t_class_config, f_class_config));
19106f45ec7bSml29623 
19116f45ec7bSml29623 	*config = t_class_config | f_class_config;
19126f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get"));
19136f45ec7bSml29623 	return (NXGE_OK);
19146f45ec7bSml29623 }
19156f45ec7bSml29623 
19166f45ec7bSml29623 nxge_status_t
nxge_fflp_ip_class_config_all(p_nxge_t nxgep)19176f45ec7bSml29623 nxge_fflp_ip_class_config_all(p_nxge_t nxgep)
19186f45ec7bSml29623 {
19196f45ec7bSml29623 	uint32_t class_config;
19206f45ec7bSml29623 	tcam_class_t class;
19216f45ec7bSml29623 
19226f45ec7bSml29623 #ifdef	NXGE_DEBUG
19236f45ec7bSml29623 	int status = NXGE_OK;
19246f45ec7bSml29623 #endif
19256f45ec7bSml29623 
19266f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config"));
19276f45ec7bSml29623 	for (class = TCAM_CLASS_TCP_IPV4;
19286f45ec7bSml29623 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
19296f45ec7bSml29623 		class_config = nxgep->class_config.class_cfg[class];
19306f45ec7bSml29623 #ifndef	NXGE_DEBUG
19316f45ec7bSml29623 		(void) nxge_fflp_ip_class_config(nxgep, class, class_config);
19326f45ec7bSml29623 #else
19336f45ec7bSml29623 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
19346f45ec7bSml29623 		if (status & NPI_FFLP_ERROR) {
19356f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19366f45ec7bSml29623 			    "nxge_fflp_ip_class_config failed "
19376f45ec7bSml29623 			    " class %d config %x ",
19386f45ec7bSml29623 			    class, class_config));
19396f45ec7bSml29623 		}
19406f45ec7bSml29623 #endif
19416f45ec7bSml29623 	}
19426f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
19436f45ec7bSml29623 	return (NXGE_OK);
19446f45ec7bSml29623 }
19456f45ec7bSml29623 
19466f45ec7bSml29623 nxge_status_t
nxge_fflp_config_vlan_table(p_nxge_t nxgep,uint16_t vlan_id)19476f45ec7bSml29623 nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id)
19486f45ec7bSml29623 {
19496f45ec7bSml29623 	uint8_t port, rdc_grp;
19506f45ec7bSml29623 	npi_handle_t handle;
19516f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
19526f45ec7bSml29623 	uint8_t priority = 1;
19536f45ec7bSml29623 	p_nxge_mv_cfg_t vlan_table;
19546f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
19556f45ec7bSml29623 	p_nxge_hw_list_t hw_p;
19566f45ec7bSml29623 
19576f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table"));
19586f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
19596f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
19606f45ec7bSml29623 	vlan_table = p_class_cfgp->vlan_tbl;
19616f45ec7bSml29623 	port = nxgep->function_num;
19626f45ec7bSml29623 
19636f45ec7bSml29623 	if (vlan_table[vlan_id].flag == 0) {
19646f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19656f45ec7bSml29623 		    " nxge_fflp_config_vlan_table"
19666f45ec7bSml29623 		    " vlan id is not configured %d", vlan_id));
19676f45ec7bSml29623 		return (NXGE_ERROR);
19686f45ec7bSml29623 	}
19696f45ec7bSml29623 
19706f45ec7bSml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
19716f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19726f45ec7bSml29623 		    " nxge_fflp_config_vlan_table:"
19736f45ec7bSml29623 		    " common hardware not set", nxgep->niu_type));
19746f45ec7bSml29623 		return (NXGE_ERROR);
19756f45ec7bSml29623 	}
19766f45ec7bSml29623 	MUTEX_ENTER(&hw_p->nxge_vlan_lock);
19776f45ec7bSml29623 	rdc_grp = vlan_table[vlan_id].rdctbl;
19786f45ec7bSml29623 	rs = npi_fflp_cfg_enet_vlan_table_assoc(handle,
19796f45ec7bSml29623 	    port, vlan_id,
19806f45ec7bSml29623 	    rdc_grp, priority);
19816f45ec7bSml29623 
19826f45ec7bSml29623 	MUTEX_EXIT(&hw_p->nxge_vlan_lock);
19836f45ec7bSml29623 	if (rs & NPI_FFLP_ERROR) {
19846f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19856f45ec7bSml29623 		    "nxge_fflp_config_vlan_table failed "
19866f45ec7bSml29623 		    " Port %d vlan_id %d rdc_grp %d",
19876f45ec7bSml29623 		    port, vlan_id, rdc_grp));
19886f45ec7bSml29623 		return (NXGE_ERROR | rs);
19896f45ec7bSml29623 	}
19906f45ec7bSml29623 
19916f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table"));
19926f45ec7bSml29623 	return (NXGE_OK);
19936f45ec7bSml29623 }
19946f45ec7bSml29623 
19956f45ec7bSml29623 nxge_status_t
nxge_fflp_update_hw(p_nxge_t nxgep)19966f45ec7bSml29623 nxge_fflp_update_hw(p_nxge_t nxgep)
19976f45ec7bSml29623 {
19986f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
19996f45ec7bSml29623 	p_nxge_param_t pa;
20006f45ec7bSml29623 	uint64_t cfgd_vlans;
20016f45ec7bSml29623 	uint64_t *val_ptr;
20026f45ec7bSml29623 	int i;
20036f45ec7bSml29623 	int num_macs;
20046f45ec7bSml29623 	uint8_t alt_mac;
20056f45ec7bSml29623 	nxge_param_map_t *p_map;
20066f45ec7bSml29623 	p_nxge_mv_cfg_t vlan_table;
20076f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
20086f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_all_cfgp;
20096f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
20106f45ec7bSml29623 
20116f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw"));
20126f45ec7bSml29623 
20136f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
20146f45ec7bSml29623 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
20156f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
20166f45ec7bSml29623 
20176f45ec7bSml29623 	status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1);
20186f45ec7bSml29623 	if (status != NXGE_OK) {
20196f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20206f45ec7bSml29623 		    "nxge_fflp_set_hash1 Failed"));
20216f45ec7bSml29623 		return (NXGE_ERROR);
20226f45ec7bSml29623 	}
20236f45ec7bSml29623 
20246f45ec7bSml29623 	status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2);
20256f45ec7bSml29623 	if (status != NXGE_OK) {
20266f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20276f45ec7bSml29623 		    "nxge_fflp_set_hash2 Failed"));
20286f45ec7bSml29623 		return (NXGE_ERROR);
20296f45ec7bSml29623 	}
20306f45ec7bSml29623 	vlan_table = p_class_cfgp->vlan_tbl;
20316f45ec7bSml29623 
20326f45ec7bSml29623 	/* configure vlan tables */
20336f45ec7bSml29623 	pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp];
2034adfcba55Sjoycey #if defined(__i386)
2035adfcba55Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
2036adfcba55Sjoycey #else
20376f45ec7bSml29623 	val_ptr = (uint64_t *)pa->value;
2038adfcba55Sjoycey #endif
20396f45ec7bSml29623 	cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >>
20406f45ec7bSml29623 	    NXGE_PARAM_ARRAY_CNT_SHIFT);
20416f45ec7bSml29623 
20426f45ec7bSml29623 	for (i = 0; i < cfgd_vlans; i++) {
20436f45ec7bSml29623 		p_map = (nxge_param_map_t *)&val_ptr[i];
20446f45ec7bSml29623 		if (vlan_table[p_map->param_id].flag) {
20456f45ec7bSml29623 			status = nxge_fflp_config_vlan_table(nxgep,
20466f45ec7bSml29623 			    p_map->param_id);
20476f45ec7bSml29623 			if (status != NXGE_OK) {
20486f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20496f45ec7bSml29623 				    "nxge_fflp_config_vlan_table Failed"));
20506f45ec7bSml29623 				return (NXGE_ERROR);
20516f45ec7bSml29623 			}
20526f45ec7bSml29623 		}
20536f45ec7bSml29623 	}
20546f45ec7bSml29623 
20556f45ec7bSml29623 	/* config MAC addresses */
20566f45ec7bSml29623 	num_macs = p_cfgp->max_macs;
20576f45ec7bSml29623 	pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp];
2058adfcba55Sjoycey #if defined(__i386)
2059adfcba55Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
2060adfcba55Sjoycey #else
20616f45ec7bSml29623 	val_ptr = (uint64_t *)pa->value;
2062adfcba55Sjoycey #endif
20636f45ec7bSml29623 
20646f45ec7bSml29623 	for (alt_mac = 0; alt_mac < num_macs; alt_mac++) {
20656f45ec7bSml29623 		if (p_class_cfgp->mac_host_info[alt_mac].flag) {
20666f45ec7bSml29623 			status = nxge_logical_mac_assign_rdc_table(nxgep,
20676f45ec7bSml29623 			    alt_mac);
20686f45ec7bSml29623 			if (status != NXGE_OK) {
20696f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20706f45ec7bSml29623 				    "nxge_logical_mac_assign_rdc_table"
20716f45ec7bSml29623 				    " Failed"));
20726f45ec7bSml29623 				return (NXGE_ERROR);
20736f45ec7bSml29623 			}
20746f45ec7bSml29623 		}
20756f45ec7bSml29623 	}
20766f45ec7bSml29623 
20776f45ec7bSml29623 	/* Config Hash values */
2078f6485eecSyc148097 	/* config classes */
20796f45ec7bSml29623 	status = nxge_fflp_ip_class_config_all(nxgep);
20806f45ec7bSml29623 	if (status != NXGE_OK) {
20816f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
20826f45ec7bSml29623 		    "nxge_fflp_ip_class_config_all Failed"));
20836f45ec7bSml29623 		return (NXGE_ERROR);
20846f45ec7bSml29623 	}
20856f45ec7bSml29623 	return (NXGE_OK);
20866f45ec7bSml29623 }
20876f45ec7bSml29623 
20886f45ec7bSml29623 nxge_status_t
nxge_classify_init_hw(p_nxge_t nxgep)20896f45ec7bSml29623 nxge_classify_init_hw(p_nxge_t nxgep)
20906f45ec7bSml29623 {
20916f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
20926f45ec7bSml29623 
20936f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw"));
20946f45ec7bSml29623 
20956f45ec7bSml29623 	if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) {
20966f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20976f45ec7bSml29623 		    "nxge_classify_init_hw already init"));
20986f45ec7bSml29623 		return (NXGE_OK);
20996f45ec7bSml29623 	}
21006f45ec7bSml29623 
21016f45ec7bSml29623 	/* Now do a real configuration */
21026f45ec7bSml29623 	status = nxge_fflp_update_hw(nxgep);
21036f45ec7bSml29623 	if (status != NXGE_OK) {
21046f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21056f45ec7bSml29623 		    "nxge_fflp_update_hw failed"));
21066f45ec7bSml29623 		return (NXGE_ERROR);
21076f45ec7bSml29623 	}
21086f45ec7bSml29623 
21096f45ec7bSml29623 	/* Init RDC tables? ? who should do that? rxdma or fflp ? */
21106f45ec7bSml29623 	/* attach rdc table to the MAC port. */
21116f45ec7bSml29623 	status = nxge_main_mac_assign_rdc_table(nxgep);
21126f45ec7bSml29623 	if (status != NXGE_OK) {
21136f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21146f45ec7bSml29623 		    "nxge_main_mac_assign_rdc_table failed"));
21156f45ec7bSml29623 		return (NXGE_ERROR);
21166f45ec7bSml29623 	}
21176f45ec7bSml29623 
21186f45ec7bSml29623 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
21196f45ec7bSml29623 	if (status != NXGE_OK) {
21206f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21216f45ec7bSml29623 		    "nxge_multicast_mac_assign_rdc_table failed"));
21226f45ec7bSml29623 		return (NXGE_ERROR);
21236f45ec7bSml29623 	}
21246f45ec7bSml29623 
21254df55fdeSJanie Lu 	if (nxgep->classifier.fragment_bug == 1) {
21266f45ec7bSml29623 		status = nxge_tcam_handle_ip_fragment(nxgep);
21276f45ec7bSml29623 		if (status != NXGE_OK) {
21286f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21296f45ec7bSml29623 			    "nxge_tcam_handle_ip_fragment failed"));
21306f45ec7bSml29623 			return (NXGE_ERROR);
21316f45ec7bSml29623 		}
21324df55fdeSJanie Lu 	}
21336f45ec7bSml29623 
21346f45ec7bSml29623 	nxgep->classifier.state |= NXGE_FFLP_HW_INIT;
21356f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw"));
21366f45ec7bSml29623 	return (NXGE_OK);
21376f45ec7bSml29623 }
21386f45ec7bSml29623 
21396f45ec7bSml29623 nxge_status_t
nxge_fflp_handle_sys_errors(p_nxge_t nxgep)21406f45ec7bSml29623 nxge_fflp_handle_sys_errors(p_nxge_t nxgep)
21416f45ec7bSml29623 {
21426f45ec7bSml29623 	npi_handle_t handle;
21436f45ec7bSml29623 	p_nxge_fflp_stats_t statsp;
21446f45ec7bSml29623 	uint8_t portn, rdc_grp;
21456f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
21466f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
21476f45ec7bSml29623 	vlan_par_err_t vlan_err;
21486f45ec7bSml29623 	tcam_err_t tcam_err;
21496f45ec7bSml29623 	hash_lookup_err_log1_t fcram1_err;
21506f45ec7bSml29623 	hash_lookup_err_log2_t fcram2_err;
21516f45ec7bSml29623 	hash_tbl_data_log_t fcram_err;
21526f45ec7bSml29623 
21536f45ec7bSml29623 	handle = nxgep->npi_handle;
21546f45ec7bSml29623 	statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats;
21556f45ec7bSml29623 	portn = nxgep->mac.portnum;
21566f45ec7bSml29623 
21576f45ec7bSml29623 	/*
21586f45ec7bSml29623 	 * need to read the fflp error registers to figure out what the error
21596f45ec7bSml29623 	 * is
21606f45ec7bSml29623 	 */
21616f45ec7bSml29623 	npi_fflp_vlan_error_get(handle, &vlan_err);
21626f45ec7bSml29623 	npi_fflp_tcam_error_get(handle, &tcam_err);
21636f45ec7bSml29623 
21646f45ec7bSml29623 	if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) {
21656f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21666f45ec7bSml29623 		    " vlan table parity error on port %d"
21676f45ec7bSml29623 		    " addr: 0x%x data: 0x%x",
21686f45ec7bSml29623 		    portn, vlan_err.bits.ldw.addr,
21696f45ec7bSml29623 		    vlan_err.bits.ldw.data));
21706f45ec7bSml29623 		statsp->vlan_parity_err++;
21716f45ec7bSml29623 
21726f45ec7bSml29623 		if (vlan_err.bits.ldw.m_err) {
21736f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21746f45ec7bSml29623 			    " vlan table multiple errors on port %d",
21756f45ec7bSml29623 			    portn));
21766f45ec7bSml29623 		}
21776f45ec7bSml29623 		statsp->errlog.vlan = (uint32_t)vlan_err.value;
21786f45ec7bSml29623 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
21796f45ec7bSml29623 		    NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR);
21806f45ec7bSml29623 		npi_fflp_vlan_error_clear(handle);
21816f45ec7bSml29623 	}
21826f45ec7bSml29623 
21836f45ec7bSml29623 	if (tcam_err.bits.ldw.err) {
21846f45ec7bSml29623 		if (tcam_err.bits.ldw.p_ecc != 0) {
21856f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21866f45ec7bSml29623 			    " TCAM ECC error on port %d"
21876f45ec7bSml29623 			    " TCAM entry: 0x%x syndrome: 0x%x",
21886f45ec7bSml29623 			    portn, tcam_err.bits.ldw.addr,
21896f45ec7bSml29623 			    tcam_err.bits.ldw.syndrome));
21906f45ec7bSml29623 			statsp->tcam_ecc_err++;
21916f45ec7bSml29623 		} else {
21926f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21936f45ec7bSml29623 			    " TCAM Parity error on port %d"
21946f45ec7bSml29623 			    " addr: 0x%x parity value: 0x%x",
21956f45ec7bSml29623 			    portn, tcam_err.bits.ldw.addr,
21966f45ec7bSml29623 			    tcam_err.bits.ldw.syndrome));
21976f45ec7bSml29623 			statsp->tcam_parity_err++;
21986f45ec7bSml29623 		}
21996f45ec7bSml29623 
22006f45ec7bSml29623 		if (tcam_err.bits.ldw.mult) {
22016f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22026f45ec7bSml29623 			    " TCAM Multiple errors on port %d", portn));
22036f45ec7bSml29623 		} else {
22046f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
220552ccf843Smisaki 			    " TCAM PIO error on port %d", portn));
22066f45ec7bSml29623 		}
22076f45ec7bSml29623 
22086f45ec7bSml29623 		statsp->errlog.tcam = (uint32_t)tcam_err.value;
22096f45ec7bSml29623 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
22106f45ec7bSml29623 		    NXGE_FM_EREPORT_FFLP_TCAM_ERR);
22116f45ec7bSml29623 		npi_fflp_tcam_error_clear(handle);
22126f45ec7bSml29623 	}
22136f45ec7bSml29623 
22146f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
22156f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
22166f45ec7bSml29623 
2217678453a8Sspeer 	for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) {
2218678453a8Sspeer 		if (p_cfgp->grpids[rdc_grp]) {
22196f45ec7bSml29623 			npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp);
22206f45ec7bSml29623 			if (fcram_err.bits.ldw.pio_err) {
22216f45ec7bSml29623 				NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22226f45ec7bSml29623 				    " FCRAM PIO ECC error on port %d"
22236f45ec7bSml29623 				    " rdc group: %d Hash Table addr: 0x%x"
22246f45ec7bSml29623 				    " syndrome: 0x%x",
22256f45ec7bSml29623 				    portn, rdc_grp,
22266f45ec7bSml29623 				    fcram_err.bits.ldw.fcram_addr,
22276f45ec7bSml29623 				    fcram_err.bits.ldw.syndrome));
22286f45ec7bSml29623 				statsp->hash_pio_err[rdc_grp]++;
22296f45ec7bSml29623 				statsp->errlog.hash_pio[rdc_grp] =
22306f45ec7bSml29623 				    (uint32_t)fcram_err.value;
22316f45ec7bSml29623 				NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
22326f45ec7bSml29623 				    NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR);
22336f45ec7bSml29623 				npi_fflp_fcram_error_clear(handle, rdc_grp);
22346f45ec7bSml29623 			}
22356f45ec7bSml29623 		}
2236678453a8Sspeer 	}
22376f45ec7bSml29623 
22386f45ec7bSml29623 	npi_fflp_fcram_error_log1_get(handle, &fcram1_err);
22396f45ec7bSml29623 	if (fcram1_err.bits.ldw.ecc_err) {
22406f45ec7bSml29623 		char *multi_str = "";
22416f45ec7bSml29623 		char *multi_bit_str = "";
22426f45ec7bSml29623 
22436f45ec7bSml29623 		npi_fflp_fcram_error_log2_get(handle, &fcram2_err);
22446f45ec7bSml29623 		if (fcram1_err.bits.ldw.mult_lk) {
22456f45ec7bSml29623 			multi_str = "multiple";
22466f45ec7bSml29623 		}
22476f45ec7bSml29623 		if (fcram1_err.bits.ldw.mult_bit) {
22486f45ec7bSml29623 			multi_bit_str = "multiple bits";
22496f45ec7bSml29623 		}
2250f6485eecSyc148097 		statsp->hash_lookup_err++;
22516f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22526f45ec7bSml29623 		    " FCRAM %s lookup %s ECC error on port %d"
22536f45ec7bSml29623 		    " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x",
22546f45ec7bSml29623 		    multi_str, multi_bit_str, portn,
22556f45ec7bSml29623 		    fcram2_err.bits.ldw.h1,
22566f45ec7bSml29623 		    fcram2_err.bits.ldw.subarea,
22576f45ec7bSml29623 		    fcram2_err.bits.ldw.syndrome));
22586f45ec7bSml29623 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
22596f45ec7bSml29623 		    NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR);
22606f45ec7bSml29623 	}
22616f45ec7bSml29623 	statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value;
22626f45ec7bSml29623 	statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value;
22636f45ec7bSml29623 	return (NXGE_OK);
22646f45ec7bSml29623 }
22654df55fdeSJanie Lu 
22664df55fdeSJanie Lu int
nxge_get_valid_tcam_cnt(p_nxge_t nxgep)22674df55fdeSJanie Lu nxge_get_valid_tcam_cnt(p_nxge_t nxgep) {
22684df55fdeSJanie Lu 	return ((nxgep->classifier.fragment_bug == 1) ?
22694df55fdeSJanie Lu 		nxgep->classifier.tcam_entry_cnt - 1 :
22704df55fdeSJanie Lu 		nxgep->classifier.tcam_entry_cnt);
22714df55fdeSJanie Lu }
22724df55fdeSJanie Lu 
22734df55fdeSJanie Lu int
nxge_rxdma_channel_cnt(p_nxge_t nxgep)22744df55fdeSJanie Lu nxge_rxdma_channel_cnt(p_nxge_t nxgep)
22754df55fdeSJanie Lu {
22764df55fdeSJanie Lu 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
22774df55fdeSJanie Lu 	p_nxge_hw_pt_cfg_t p_cfgp;
22784df55fdeSJanie Lu 
22794df55fdeSJanie Lu 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
22804df55fdeSJanie Lu 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
22814df55fdeSJanie Lu 	return (p_cfgp->max_rdcs);
22824df55fdeSJanie Lu }
22834df55fdeSJanie Lu 
22844df55fdeSJanie Lu /* ARGSUSED */
22854df55fdeSJanie Lu int
nxge_rxclass_ioctl(p_nxge_t nxgep,queue_t * wq,mblk_t * mp)22864df55fdeSJanie Lu nxge_rxclass_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
22874df55fdeSJanie Lu {
22884df55fdeSJanie Lu 	uint32_t cmd;
22894df55fdeSJanie Lu 	rx_class_cfg_t *cfg_info = (rx_class_cfg_t *)mp->b_rptr;
22904df55fdeSJanie Lu 
22914df55fdeSJanie Lu 	if (nxgep == NULL) {
22924df55fdeSJanie Lu 		return (-1);
22934df55fdeSJanie Lu 	}
22944df55fdeSJanie Lu 	cmd = cfg_info->cmd;
22954df55fdeSJanie Lu 	switch (cmd) {
22964df55fdeSJanie Lu 	default:
22974df55fdeSJanie Lu 		return (-1);
22984df55fdeSJanie Lu 
22994df55fdeSJanie Lu 	case NXGE_RX_CLASS_GCHAN:
23004df55fdeSJanie Lu 		cfg_info->data = nxge_rxdma_channel_cnt(nxgep);
23014df55fdeSJanie Lu 		break;
23024df55fdeSJanie Lu 	case NXGE_RX_CLASS_GRULE_CNT:
23034df55fdeSJanie Lu 		MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
23044df55fdeSJanie Lu 		cfg_info->rule_cnt = nxge_get_valid_tcam_cnt(nxgep);
23054df55fdeSJanie Lu 		MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
23064df55fdeSJanie Lu 		break;
23074df55fdeSJanie Lu 	case NXGE_RX_CLASS_GRULE:
23084df55fdeSJanie Lu 		nxge_get_tcam_entry(nxgep, &cfg_info->fs);
23094df55fdeSJanie Lu 		break;
23104df55fdeSJanie Lu 	case NXGE_RX_CLASS_GRULE_ALL:
23114df55fdeSJanie Lu 		nxge_get_tcam_entry_all(nxgep, cfg_info);
23124df55fdeSJanie Lu 		break;
23134df55fdeSJanie Lu 	case NXGE_RX_CLASS_RULE_DEL:
23144df55fdeSJanie Lu 		nxge_del_tcam_entry(nxgep, cfg_info->fs.location);
23154df55fdeSJanie Lu 		break;
23164df55fdeSJanie Lu 	case NXGE_RX_CLASS_RULE_INS:
23174df55fdeSJanie Lu 		(void) nxge_add_tcam_entry(nxgep, &cfg_info->fs);
23184df55fdeSJanie Lu 		break;
23194df55fdeSJanie Lu 	}
23204df55fdeSJanie Lu 	return (0);
23214df55fdeSJanie Lu }
23224df55fdeSJanie Lu /* ARGSUSED */
23234df55fdeSJanie Lu int
nxge_rxhash_ioctl(p_nxge_t nxgep,queue_t * wq,mblk_t * mp)23244df55fdeSJanie Lu nxge_rxhash_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
23254df55fdeSJanie Lu {
23264df55fdeSJanie Lu 	uint32_t cmd;
23274df55fdeSJanie Lu 	cfg_cmd_t	*cfg_info = (cfg_cmd_t *)mp->b_rptr;
23284df55fdeSJanie Lu 
23294df55fdeSJanie Lu 	if (nxgep == NULL) {
23304df55fdeSJanie Lu 		return (-1);
23314df55fdeSJanie Lu 	}
23324df55fdeSJanie Lu 	cmd = cfg_info->cmd;
23334df55fdeSJanie Lu 
23344df55fdeSJanie Lu 	switch (cmd) {
23354df55fdeSJanie Lu 	default:
23364df55fdeSJanie Lu 		return (-1);
23374df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_ADD_CLS:
23384df55fdeSJanie Lu 		nxge_add_iptun_class(nxgep, &cfg_info->iptun_cfg,
23394df55fdeSJanie Lu 		    &cfg_info->class_id);
23404df55fdeSJanie Lu 		break;
23414df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_SET_HASH:
23424df55fdeSJanie Lu 		nxge_cfg_iptun_hash(nxgep, &cfg_info->iptun_cfg,
23434df55fdeSJanie Lu 		    cfg_info->class_id);
23444df55fdeSJanie Lu 		break;
23454df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_DEL_CLS:
23464df55fdeSJanie Lu 		nxge_del_iptun_class(nxgep, cfg_info->class_id);
23474df55fdeSJanie Lu 		break;
23484df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_GET_CLS:
23494df55fdeSJanie Lu 		nxge_get_iptun_class(nxgep, &cfg_info->iptun_cfg,
23504df55fdeSJanie Lu 		    cfg_info->class_id);
23514df55fdeSJanie Lu 		break;
23524df55fdeSJanie Lu 	case NXGE_CLS_CFG_SET_SYM:
23534df55fdeSJanie Lu 		nxge_set_ip_cls_sym(nxgep, cfg_info->class_id, cfg_info->sym);
23544df55fdeSJanie Lu 		break;
23554df55fdeSJanie Lu 	case NXGE_CLS_CFG_GET_SYM:
23564df55fdeSJanie Lu 		nxge_get_ip_cls_sym(nxgep, cfg_info->class_id, &cfg_info->sym);
23574df55fdeSJanie Lu 		break;
23584df55fdeSJanie Lu 	}
23594df55fdeSJanie Lu 	return (0);
23604df55fdeSJanie Lu }
23614df55fdeSJanie Lu 
23624df55fdeSJanie Lu void
nxge_get_tcam_entry_all(p_nxge_t nxgep,rx_class_cfg_t * cfgp)23634df55fdeSJanie Lu nxge_get_tcam_entry_all(p_nxge_t nxgep, rx_class_cfg_t *cfgp)
23644df55fdeSJanie Lu {
23654df55fdeSJanie Lu 	nxge_classify_t *clasp = &nxgep->classifier;
23664df55fdeSJanie Lu 	uint16_t	n_entries;
23674df55fdeSJanie Lu 	int		i, j, k;
23684df55fdeSJanie Lu 	tcam_flow_spec_t	*tcam_entryp;
23694df55fdeSJanie Lu 
23704df55fdeSJanie Lu 	cfgp->data = clasp->tcam_size;
23714df55fdeSJanie Lu 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
23724df55fdeSJanie Lu 	n_entries = cfgp->rule_cnt;
23734df55fdeSJanie Lu 
23744df55fdeSJanie Lu 	for (i = 0, j = 0; j < cfgp->data; j++) {
23754df55fdeSJanie Lu 		k = nxge_tcam_get_index(nxgep, j);
23764df55fdeSJanie Lu 		tcam_entryp = &clasp->tcam_entries[k];
23774df55fdeSJanie Lu 		if (tcam_entryp->valid != 1)
23784df55fdeSJanie Lu 			continue;
23794df55fdeSJanie Lu 		cfgp->rule_locs[i] = j;
23804df55fdeSJanie Lu 		i++;
23814df55fdeSJanie Lu 	};
23824df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
23834df55fdeSJanie Lu 
23844df55fdeSJanie Lu 	if (n_entries != i) {
23854df55fdeSJanie Lu 		/* print warning, this should not happen */
23864df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry_all"
23874df55fdeSJanie Lu 		    "n_entries[%d] != i[%d]!!!", n_entries, i));
23884df55fdeSJanie Lu 	}
23894df55fdeSJanie Lu }
23904df55fdeSJanie Lu 
23914df55fdeSJanie Lu 
23924df55fdeSJanie Lu /* Entries for the ports are interleaved in the TCAM */
23934df55fdeSJanie Lu static uint16_t
nxge_tcam_get_index(p_nxge_t nxgep,uint16_t index)23944df55fdeSJanie Lu nxge_tcam_get_index(p_nxge_t nxgep, uint16_t index)
23954df55fdeSJanie Lu {
23964df55fdeSJanie Lu 	/* One entry reserved for IP fragment rule */
23974df55fdeSJanie Lu 	if (index >= (nxgep->classifier.tcam_size - 1))
23984df55fdeSJanie Lu 		index = 0;
23994df55fdeSJanie Lu 	if (nxgep->classifier.fragment_bug == 1)
24004df55fdeSJanie Lu 		index++;
24014df55fdeSJanie Lu 	return (nxgep->classifier.tcam_top + (index * nxgep->nports));
24024df55fdeSJanie Lu }
24034df55fdeSJanie Lu 
24044df55fdeSJanie Lu static uint32_t
nxge_tcam_cls_to_flow(uint32_t class_code)24054df55fdeSJanie Lu nxge_tcam_cls_to_flow(uint32_t class_code) {
24064df55fdeSJanie Lu 	switch (class_code) {
24074df55fdeSJanie Lu 	case TCAM_CLASS_TCP_IPV4:
24084df55fdeSJanie Lu 		return (FSPEC_TCPIP4);
24094df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV4:
24104df55fdeSJanie Lu 		return (FSPEC_UDPIP4);
24114df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV4:
24124df55fdeSJanie Lu 		return (FSPEC_AHIP4);
24134df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV4:
24144df55fdeSJanie Lu 		return (FSPEC_SCTPIP4);
24154df55fdeSJanie Lu 	case  TCAM_CLASS_TCP_IPV6:
24164df55fdeSJanie Lu 		return (FSPEC_TCPIP6);
24174df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV6:
24184df55fdeSJanie Lu 		return (FSPEC_UDPIP6);
24194df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV6:
24204df55fdeSJanie Lu 		return (FSPEC_AHIP6);
24214df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV6:
24224df55fdeSJanie Lu 		return (FSPEC_SCTPIP6);
24234df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_4:
24244df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_5:
24254df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_6:
24264df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_7:
24274df55fdeSJanie Lu 		return (FSPEC_IP_USR);
24284df55fdeSJanie Lu 	default:
24294df55fdeSJanie Lu 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "nxge_tcam_cls_to_flow"
24304df55fdeSJanie Lu 		    ": Unknown class code [0x%x]", class_code));
24314df55fdeSJanie Lu 		break;
24324df55fdeSJanie Lu 	}
24334df55fdeSJanie Lu 	return (0);
24344df55fdeSJanie Lu }
24354df55fdeSJanie Lu 
24364df55fdeSJanie Lu void
nxge_get_tcam_entry(p_nxge_t nxgep,flow_resource_t * fs)24374df55fdeSJanie Lu nxge_get_tcam_entry(p_nxge_t nxgep, flow_resource_t *fs)
24384df55fdeSJanie Lu {
24394df55fdeSJanie Lu 	uint16_t 	index;
24404df55fdeSJanie Lu 	tcam_flow_spec_t *tcam_ep;
24414df55fdeSJanie Lu 	tcam_entry_t	*tp;
24424df55fdeSJanie Lu 	flow_spec_t	*fspec;
24434df55fdeSJanie Lu 	tcpip4_spec_t 	*fspec_key;
24444df55fdeSJanie Lu 	tcpip4_spec_t 	*fspec_mask;
24454df55fdeSJanie Lu 
24464df55fdeSJanie Lu 	index = nxge_tcam_get_index(nxgep, (uint16_t)fs->location);
24474df55fdeSJanie Lu 	tcam_ep = &nxgep->classifier.tcam_entries[index];
24484df55fdeSJanie Lu 	if (tcam_ep->valid != 1) {
24494df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry: :"
24504df55fdeSJanie Lu 		    "Entry [%d] invalid for index [%d]", fs->location, index));
24514df55fdeSJanie Lu 		return;
24524df55fdeSJanie Lu 	}
24534df55fdeSJanie Lu 
24544df55fdeSJanie Lu 	/* Fill the flow spec entry */
24554df55fdeSJanie Lu 	tp = &tcam_ep->tce;
24564df55fdeSJanie Lu 	fspec = &fs->flow_spec;
24574df55fdeSJanie Lu 	fspec->flow_type = nxge_tcam_cls_to_flow(tp->ip4_class_key);
24584df55fdeSJanie Lu 
24594df55fdeSJanie Lu 	/* TODO - look at proto field to differentiate between AH and ESP */
24604df55fdeSJanie Lu 	if (fspec->flow_type == FSPEC_AHIP4) {
24614df55fdeSJanie Lu 		if (tp->ip4_proto_key == IPPROTO_ESP)
24624df55fdeSJanie Lu 			fspec->flow_type = FSPEC_ESPIP4;
24634df55fdeSJanie Lu 	}
24644df55fdeSJanie Lu 
24654df55fdeSJanie Lu 	switch (tp->ip4_class_key) {
24664df55fdeSJanie Lu 	case TCAM_CLASS_TCP_IPV4:
24674df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV4:
24684df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV4:
24694df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV4:
24704df55fdeSJanie Lu 		fspec_key = (tcpip4_spec_t *)&fspec->uh.tcpip4spec;
24714df55fdeSJanie Lu 		fspec_mask = (tcpip4_spec_t *)&fspec->um.tcpip4spec;
24724df55fdeSJanie Lu 		FSPEC_IPV4_ADDR(fspec_key->ip4dst, tp->ip4_dest_key);
24734df55fdeSJanie Lu 		FSPEC_IPV4_ADDR(fspec_mask->ip4dst, tp->ip4_dest_mask);
24744df55fdeSJanie Lu 		FSPEC_IPV4_ADDR(fspec_key->ip4src, tp->ip4_src_key);
24754df55fdeSJanie Lu 		FSPEC_IPV4_ADDR(fspec_mask->ip4src, tp->ip4_src_mask);
24764df55fdeSJanie Lu 		fspec_key->tos = tp->ip4_tos_key;
24774df55fdeSJanie Lu 		fspec_mask->tos = tp->ip4_tos_mask;
24784df55fdeSJanie Lu 		break;
24794df55fdeSJanie Lu 	default:
24804df55fdeSJanie Lu 		break;
24814df55fdeSJanie Lu 	}
24824df55fdeSJanie Lu 
24834df55fdeSJanie Lu 	switch (tp->ip4_class_key) {
24844df55fdeSJanie Lu 	case TCAM_CLASS_TCP_IPV4:
24854df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV4:
24864df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV4:
24874df55fdeSJanie Lu 		FSPEC_IP_PORTS(fspec_key->pdst, fspec_key->psrc,
24884df55fdeSJanie Lu 		    tp->ip4_port_key);
24894df55fdeSJanie Lu 		FSPEC_IP_PORTS(fspec_mask->pdst, fspec_mask->psrc,
24904df55fdeSJanie Lu 		    tp->ip4_port_mask);
24914df55fdeSJanie Lu 		break;
24924df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV4:
24934df55fdeSJanie Lu 		fspec->uh.ahip4spec.spi = tp->ip4_port_key;
24944df55fdeSJanie Lu 		fspec->um.ahip4spec.spi = tp->ip4_port_mask;
24954df55fdeSJanie Lu 		break;
24964df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_4:
24974df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_5:
24984df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_6:
24994df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_7:
25004df55fdeSJanie Lu 		fspec->uh.ip_usr_spec.l4_4_bytes = tp->ip4_port_key;
25014df55fdeSJanie Lu 		fspec->um.ip_usr_spec.l4_4_bytes = tp->ip4_port_mask;
25024df55fdeSJanie Lu 		fspec->uh.ip_usr_spec.ip_ver = FSPEC_IP4;
25034df55fdeSJanie Lu 		fspec->uh.ip_usr_spec.proto = tp->ip4_proto_key;
25044df55fdeSJanie Lu 		fspec->um.ip_usr_spec.proto = tp->ip4_proto_mask;
25054df55fdeSJanie Lu 		break;
25064df55fdeSJanie Lu 	default:
25074df55fdeSJanie Lu 		break;
25084df55fdeSJanie Lu 	}
25094df55fdeSJanie Lu 
25104df55fdeSJanie Lu 	if (tp->match_action.bits.ldw.disc == 1) {
25114df55fdeSJanie Lu 		fs->channel_cookie = NXGE_PKT_DISCARD;
25124df55fdeSJanie Lu 	} else {
25134df55fdeSJanie Lu 		fs->channel_cookie = tp->match_action.bits.ldw.offset;
25144df55fdeSJanie Lu 	}
25154df55fdeSJanie Lu }
25164df55fdeSJanie Lu 
25174df55fdeSJanie Lu void
nxge_del_tcam_entry(p_nxge_t nxgep,uint32_t location)25184df55fdeSJanie Lu nxge_del_tcam_entry(p_nxge_t nxgep, uint32_t location)
25194df55fdeSJanie Lu {
25204df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
25214df55fdeSJanie Lu 	uint16_t 	index;
25224df55fdeSJanie Lu 	tcam_flow_spec_t *tcam_ep;
25234df55fdeSJanie Lu 	tcam_entry_t	*tp;
25244df55fdeSJanie Lu 	tcam_class_t	class;
25254df55fdeSJanie Lu 
25264df55fdeSJanie Lu 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
25274df55fdeSJanie Lu 	index = nxge_tcam_get_index(nxgep, (uint16_t)location);
25284df55fdeSJanie Lu 	tcam_ep = &nxgep->classifier.tcam_entries[index];
25294df55fdeSJanie Lu 	if (tcam_ep->valid != 1) {
25304df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_tcam_entry: :"
25314df55fdeSJanie Lu 		    "Entry [%d] invalid for index [%d]", location, index));
25324df55fdeSJanie Lu 		goto fail;
25334df55fdeSJanie Lu 	}
25344df55fdeSJanie Lu 
25354df55fdeSJanie Lu 	/* Fill the flow spec entry */
25364df55fdeSJanie Lu 	tp = &tcam_ep->tce;
25374df55fdeSJanie Lu 	class = tp->ip4_class_key;
25384df55fdeSJanie Lu 	if (class >= TCAM_CLASS_IP_USER_4 && class <= TCAM_CLASS_IP_USER_7) {
25394df55fdeSJanie Lu 		int i;
25404df55fdeSJanie Lu 		nxge_usr_l3_cls_t *l3_ucls_p;
25414df55fdeSJanie Lu 		p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
25424df55fdeSJanie Lu 
25434df55fdeSJanie Lu 		for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
25444df55fdeSJanie Lu 			l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
25454df55fdeSJanie Lu 			if (l3_ucls_p->valid) {
25464df55fdeSJanie Lu 				if (l3_ucls_p->cls == class &&
25474df55fdeSJanie Lu 				    l3_ucls_p->tcam_ref_cnt) {
25484df55fdeSJanie Lu 					l3_ucls_p->tcam_ref_cnt--;
25494df55fdeSJanie Lu 					if (l3_ucls_p->tcam_ref_cnt > 0)
25504df55fdeSJanie Lu 						continue;
25514df55fdeSJanie Lu 					/* disable class */
25524df55fdeSJanie Lu 					rs = npi_fflp_cfg_ip_usr_cls_disable(
25534df55fdeSJanie Lu 					    nxgep->npi_reg_handle,
25544df55fdeSJanie Lu 					    (tcam_class_t)class);
25554df55fdeSJanie Lu 					if (rs != NPI_SUCCESS)
25564df55fdeSJanie Lu 						goto fail;
25574df55fdeSJanie Lu 					l3_ucls_p->cls = 0;
25584df55fdeSJanie Lu 					l3_ucls_p->pid = 0;
25594df55fdeSJanie Lu 					l3_ucls_p->valid = 0;
25604df55fdeSJanie Lu 					break;
25614df55fdeSJanie Lu 				}
25624df55fdeSJanie Lu 			}
25634df55fdeSJanie Lu 		}
25644df55fdeSJanie Lu 		if (i == NXGE_L3_PROG_CLS) {
25654df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25664df55fdeSJanie Lu 			    "nxge_del_tcam_entry: Usr class "
25674df55fdeSJanie Lu 			    "0x%llx not found", (unsigned long long) class));
25684df55fdeSJanie Lu 			goto fail;
25694df55fdeSJanie Lu 		}
25704df55fdeSJanie Lu 	}
25714df55fdeSJanie Lu 
25724df55fdeSJanie Lu 	rs = npi_fflp_tcam_entry_invalidate(nxgep->npi_reg_handle, index);
25734df55fdeSJanie Lu 	if (rs != NPI_SUCCESS) {
25744df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25754df55fdeSJanie Lu 		    "nxge_del_tcam_entry: TCAM invalidate failed "
25764df55fdeSJanie Lu 		    "at loc %d ", location));
25774df55fdeSJanie Lu 		goto fail;
25784df55fdeSJanie Lu 	}
25794df55fdeSJanie Lu 
25804df55fdeSJanie Lu 	nxgep->classifier.tcam_entries[index].valid = 0;
25814df55fdeSJanie Lu 	nxgep->classifier.tcam_entry_cnt--;
25824df55fdeSJanie Lu 
25834df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
25844df55fdeSJanie Lu 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_del_tcam_entry"));
25854df55fdeSJanie Lu 	return;
25864df55fdeSJanie Lu fail:
25874df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
25884df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25894df55fdeSJanie Lu 	    "<== nxge_del_tcam_entry FAILED"));
25904df55fdeSJanie Lu }
25914df55fdeSJanie Lu 
25924df55fdeSJanie Lu static uint8_t
nxge_iptun_pkt_type_to_pid(uint8_t pkt_type)25934df55fdeSJanie Lu nxge_iptun_pkt_type_to_pid(uint8_t pkt_type)
25944df55fdeSJanie Lu {
25954df55fdeSJanie Lu 	uint8_t pid = 0;
25964df55fdeSJanie Lu 
25974df55fdeSJanie Lu 	switch (pkt_type) {
25984df55fdeSJanie Lu 	case IPTUN_PKT_IPV4:
25994df55fdeSJanie Lu 		pid = 4;
26004df55fdeSJanie Lu 		break;
26014df55fdeSJanie Lu 	case IPTUN_PKT_IPV6:
26024df55fdeSJanie Lu 		pid = 41;
26034df55fdeSJanie Lu 		break;
26044df55fdeSJanie Lu 	case IPTUN_PKT_GRE:
26054df55fdeSJanie Lu 		pid = 47;
26064df55fdeSJanie Lu 		break;
26074df55fdeSJanie Lu 	case IPTUN_PKT_GTP:
26084df55fdeSJanie Lu 		pid = 17;
26094df55fdeSJanie Lu 		break;
26104df55fdeSJanie Lu 	default:
26114df55fdeSJanie Lu 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
26124df55fdeSJanie Lu 		    "nxge_iptun_pkt_type_to_pid: Unknown pkt type 0x%x",
26134df55fdeSJanie Lu 		    pkt_type));
26144df55fdeSJanie Lu 		break;
26154df55fdeSJanie Lu 	}
26164df55fdeSJanie Lu 
26174df55fdeSJanie Lu 	return (pid);
26184df55fdeSJanie Lu }
26194df55fdeSJanie Lu 
26204df55fdeSJanie Lu static npi_status_t
nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep,uint64_t class,iptun_cfg_t * iptunp)26214df55fdeSJanie Lu nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep, uint64_t class,
26224df55fdeSJanie Lu 		iptun_cfg_t *iptunp)
26234df55fdeSJanie Lu {
26244df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
26254df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
26264df55fdeSJanie Lu 
26274df55fdeSJanie Lu 	switch (iptunp->in_pkt_type) {
26284df55fdeSJanie Lu 	case IPTUN_PKT_IPV4:
26294df55fdeSJanie Lu 	case IPTUN_PKT_IPV6:
26304df55fdeSJanie Lu 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
26314df55fdeSJanie Lu 		    (tcam_class_t)class, 0, 0, 0, 0);
26324df55fdeSJanie Lu 		break;
26334df55fdeSJanie Lu 	case IPTUN_PKT_GRE:
26344df55fdeSJanie Lu 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
26354df55fdeSJanie Lu 		    (tcam_class_t)class, iptunp->l4b0_val,
26364df55fdeSJanie Lu 		    iptunp->l4b0_mask, 0, 0);
26374df55fdeSJanie Lu 		break;
26384df55fdeSJanie Lu 	case IPTUN_PKT_GTP:
26394df55fdeSJanie Lu 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
26404df55fdeSJanie Lu 		    (tcam_class_t)class, 0, 0, iptunp->l4b23_val,
26414df55fdeSJanie Lu 		    (iptunp->l4b23_sel & 0x01));
26424df55fdeSJanie Lu 		break;
26434df55fdeSJanie Lu 	default:
26444df55fdeSJanie Lu 		rs = NPI_FFLP_TCAM_CLASS_INVALID;
26454df55fdeSJanie Lu 		break;
26464df55fdeSJanie Lu 	}
26474df55fdeSJanie Lu 	return (rs);
26484df55fdeSJanie Lu }
26494df55fdeSJanie Lu 
26504df55fdeSJanie Lu void
nxge_add_iptun_class(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t * cls_idp)26514df55fdeSJanie Lu nxge_add_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp,
26524df55fdeSJanie Lu 		uint8_t *cls_idp)
26534df55fdeSJanie Lu {
26544df55fdeSJanie Lu 	int i, add_cls;
26554df55fdeSJanie Lu 	uint8_t pid;
26564df55fdeSJanie Lu 	uint64_t class;
26574df55fdeSJanie Lu 	p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
26584df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
26594df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
26604df55fdeSJanie Lu 
26614df55fdeSJanie Lu 	pid = nxge_iptun_pkt_type_to_pid(iptunp->in_pkt_type);
26624df55fdeSJanie Lu 	if (pid == 0)
26634df55fdeSJanie Lu 		return;
26644df55fdeSJanie Lu 
26654df55fdeSJanie Lu 	add_cls = 0;
26664df55fdeSJanie Lu 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
26674df55fdeSJanie Lu 
26684df55fdeSJanie Lu 	/* Get an user programmable class ID */
26694df55fdeSJanie Lu 	for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
26704df55fdeSJanie Lu 		if (hw_p->tcam_l3_prog_cls[i].valid == 0) {
26714df55fdeSJanie Lu 			/* todo add new usr class reg */
26724df55fdeSJanie Lu 			switch (i) {
26734df55fdeSJanie Lu 			case 0:
26744df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_4;
26754df55fdeSJanie Lu 				break;
26764df55fdeSJanie Lu 			case 1:
26774df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_5;
26784df55fdeSJanie Lu 				break;
26794df55fdeSJanie Lu 			case 2:
26804df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_6;
26814df55fdeSJanie Lu 				break;
26824df55fdeSJanie Lu 			case 3:
26834df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_7;
26844df55fdeSJanie Lu 				break;
26854df55fdeSJanie Lu 			default:
26864df55fdeSJanie Lu 				break;
26874df55fdeSJanie Lu 			}
26884df55fdeSJanie Lu 			rs = npi_fflp_cfg_ip_usr_cls_set(handle,
26894df55fdeSJanie Lu 			    (tcam_class_t)class, 0, 0, pid, 0);
26904df55fdeSJanie Lu 			if (rs != NPI_SUCCESS)
26914df55fdeSJanie Lu 				goto fail;
26924df55fdeSJanie Lu 
26934df55fdeSJanie Lu 			rs = nxge_set_iptun_usr_cls_reg(nxgep, class, iptunp);
26944df55fdeSJanie Lu 
26954df55fdeSJanie Lu 			if (rs != NPI_SUCCESS)
26964df55fdeSJanie Lu 				goto fail;
26974df55fdeSJanie Lu 
26984df55fdeSJanie Lu 			rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
26994df55fdeSJanie Lu 			    (tcam_class_t)class);
27004df55fdeSJanie Lu 			if (rs != NPI_SUCCESS)
27014df55fdeSJanie Lu 				goto fail;
27024df55fdeSJanie Lu 
27034df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].cls = class;
27044df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].pid = pid;
27054df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
27064df55fdeSJanie Lu 			    iptunp->in_pkt_type;
27074df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].valid = 1;
27084df55fdeSJanie Lu 			*cls_idp = (uint8_t)class;
27094df55fdeSJanie Lu 			add_cls = 1;
27104df55fdeSJanie Lu 			break;
27114df55fdeSJanie Lu 		} else if (hw_p->tcam_l3_prog_cls[i].pid == pid) {
27124df55fdeSJanie Lu 			if (hw_p->tcam_l3_prog_cls[i].flow_pkt_type == 0) {
27134df55fdeSJanie Lu 				/* there is no flow key */
27144df55fdeSJanie Lu 				/* todo program the existing usr class reg */
27154df55fdeSJanie Lu 
27164df55fdeSJanie Lu 				rs = nxge_set_iptun_usr_cls_reg(nxgep, class,
27174df55fdeSJanie Lu 				    iptunp);
27184df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
27194df55fdeSJanie Lu 					goto fail;
27204df55fdeSJanie Lu 
27214df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
27224df55fdeSJanie Lu 				    (tcam_class_t)class);
27234df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
27244df55fdeSJanie Lu 					goto fail;
27254df55fdeSJanie Lu 
27264df55fdeSJanie Lu 				hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
27274df55fdeSJanie Lu 				    iptunp->in_pkt_type;
27284df55fdeSJanie Lu 				*cls_idp = (uint8_t)class;
27294df55fdeSJanie Lu 				add_cls = 1;
27304df55fdeSJanie Lu 			} else {
27314df55fdeSJanie Lu 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27324df55fdeSJanie Lu 				    "nxge_add_iptun_class: L3 usr "
27334df55fdeSJanie Lu 				    "programmable class with pid %d "
27344df55fdeSJanie Lu 				    "already exists", pid));
27354df55fdeSJanie Lu 			}
27364df55fdeSJanie Lu 			break;
27374df55fdeSJanie Lu 		}
27384df55fdeSJanie Lu 	}
27394df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
27404df55fdeSJanie Lu 
27414df55fdeSJanie Lu 	if (add_cls != 1) {
27424df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27434df55fdeSJanie Lu 		    "nxge_add_iptun_class: Could not add IP tunneling class"));
27444df55fdeSJanie Lu 	}
27454df55fdeSJanie Lu 	return;
27464df55fdeSJanie Lu fail:
27474df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
27484df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_iptun_class: FAILED"));
27494df55fdeSJanie Lu }
27504df55fdeSJanie Lu 
27514df55fdeSJanie Lu static boolean_t
nxge_is_iptun_cls_present(p_nxge_t nxgep,uint8_t cls_id,int * idx)27524df55fdeSJanie Lu nxge_is_iptun_cls_present(p_nxge_t nxgep, uint8_t cls_id, int *idx)
27534df55fdeSJanie Lu {
27544df55fdeSJanie Lu 	int i;
27554df55fdeSJanie Lu 	p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
27564df55fdeSJanie Lu 
27574df55fdeSJanie Lu 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
27584df55fdeSJanie Lu 	for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
27594df55fdeSJanie Lu 		if (hw_p->tcam_l3_prog_cls[i].valid &&
27604df55fdeSJanie Lu 		    hw_p->tcam_l3_prog_cls[i].flow_pkt_type != 0) {
27614df55fdeSJanie Lu 			if (hw_p->tcam_l3_prog_cls[i].cls == cls_id)
27624df55fdeSJanie Lu 				break;
27634df55fdeSJanie Lu 		}
27644df55fdeSJanie Lu 	}
27654df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
27664df55fdeSJanie Lu 
27674df55fdeSJanie Lu 	if (i == NXGE_L3_PROG_CLS) {
27684df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27694df55fdeSJanie Lu 		    "nxge_is_iptun_cls_present: Invalid class %d", cls_id));
27704df55fdeSJanie Lu 		return (B_FALSE);
27714df55fdeSJanie Lu 	} else {
27724df55fdeSJanie Lu 		*idx = i;
27734df55fdeSJanie Lu 		return (B_TRUE);
27744df55fdeSJanie Lu 	}
27754df55fdeSJanie Lu }
27764df55fdeSJanie Lu 
27774df55fdeSJanie Lu void
nxge_cfg_iptun_hash(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t cls_id)27784df55fdeSJanie Lu nxge_cfg_iptun_hash(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
27794df55fdeSJanie Lu {
27804df55fdeSJanie Lu 	int idx;
27814df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
27824df55fdeSJanie Lu 	flow_key_cfg_t cfg;
27834df55fdeSJanie Lu 
27844df55fdeSJanie Lu 	/* check to see that this is a valid class ID */
27854df55fdeSJanie Lu 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &idx)) {
27864df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27874df55fdeSJanie Lu 		    "nxge_cfg_iptun_hash: nxge_is_iptun_cls_present "
27884df55fdeSJanie Lu 		    "failed for cls_id %d", cls_id));
27894df55fdeSJanie Lu 		return;
27904df55fdeSJanie Lu 	}
27914df55fdeSJanie Lu 
27924df55fdeSJanie Lu 	bzero((void *)&cfg, sizeof (flow_key_cfg_t));
27934df55fdeSJanie Lu 
27944df55fdeSJanie Lu 	/*
27954df55fdeSJanie Lu 	 * This ensures that all 4 bytes of the XOR value are loaded to the
27964df55fdeSJanie Lu 	 * hash key.
27974df55fdeSJanie Lu 	 */
27984df55fdeSJanie Lu 	cfg.use_dport = cfg.use_sport = cfg.ip_opts_exist = 1;
27994df55fdeSJanie Lu 
28004df55fdeSJanie Lu 	cfg.l4_xor_sel = (iptunp->l4xor_sel & FL_KEY_USR_L4XOR_MSK);
28014df55fdeSJanie Lu 	cfg.use_l4_md = 1;
28024df55fdeSJanie Lu 
28034df55fdeSJanie Lu 	if (iptunp->hash_flags & HASH_L3PROTO)
28044df55fdeSJanie Lu 		cfg.use_proto = 1;
28054df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_IPDA)
28064df55fdeSJanie Lu 		cfg.use_daddr = 1;
28074df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_IPSA)
28084df55fdeSJanie Lu 		cfg.use_saddr = 1;
28094df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_VLAN)
28104df55fdeSJanie Lu 		cfg.use_vlan = 1;
28114df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_L2DA)
28124df55fdeSJanie Lu 		cfg.use_l2da = 1;
28134df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_IFPORT)
28144df55fdeSJanie Lu 		cfg.use_portnum = 1;
28154df55fdeSJanie Lu 
28164df55fdeSJanie Lu 	(void) npi_fflp_cfg_ip_cls_flow_key_rfnl(handle, (tcam_class_t)cls_id,
28174df55fdeSJanie Lu 	    &cfg);
28184df55fdeSJanie Lu }
28194df55fdeSJanie Lu 
28204df55fdeSJanie Lu void
nxge_del_iptun_class(p_nxge_t nxgep,uint8_t cls_id)28214df55fdeSJanie Lu nxge_del_iptun_class(p_nxge_t nxgep, uint8_t cls_id)
28224df55fdeSJanie Lu {
28234df55fdeSJanie Lu 	int i;
28244df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
28254df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
28264df55fdeSJanie Lu 
28274df55fdeSJanie Lu 
28284df55fdeSJanie Lu 	/* check to see that this is a valid class ID */
28294df55fdeSJanie Lu 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) {
28304df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
28314df55fdeSJanie Lu 		    "nxge_del_iptun_class: Invalid class ID 0x%x", cls_id));
28324df55fdeSJanie Lu 		return;
28334df55fdeSJanie Lu 	}
28344df55fdeSJanie Lu 
28354df55fdeSJanie Lu 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
28364df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_usr_cls_disable(handle, (tcam_class_t)cls_id);
28374df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
28384df55fdeSJanie Lu 		goto fail;
28394df55fdeSJanie Lu 	nxgep->nxge_hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 0;
28404df55fdeSJanie Lu 	if (nxgep->nxge_hw_p->tcam_l3_prog_cls[i].tcam_ref_cnt == 0)
28414df55fdeSJanie Lu 		nxgep->nxge_hw_p->tcam_l3_prog_cls[i].valid = 0;
28424df55fdeSJanie Lu 
28434df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
28444df55fdeSJanie Lu 	return;
28454df55fdeSJanie Lu fail:
28464df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
28474df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_iptun_class: FAILED"));
28484df55fdeSJanie Lu }
28494df55fdeSJanie Lu 
28504df55fdeSJanie Lu void
nxge_get_iptun_class(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t cls_id)28514df55fdeSJanie Lu nxge_get_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
28524df55fdeSJanie Lu {
28534df55fdeSJanie Lu 	int i;
28544df55fdeSJanie Lu 	uint8_t pid;
28554df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
28564df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
28574df55fdeSJanie Lu 	flow_key_cfg_t cfg;
28584df55fdeSJanie Lu 
28594df55fdeSJanie Lu 
28604df55fdeSJanie Lu 	/* check to see that this is a valid class ID */
28614df55fdeSJanie Lu 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i))
28624df55fdeSJanie Lu 		return;
28634df55fdeSJanie Lu 
28644df55fdeSJanie Lu 	bzero((void *)iptunp, sizeof (iptun_cfg_t));
28654df55fdeSJanie Lu 
28664df55fdeSJanie Lu 	pid = nxgep->nxge_hw_p->tcam_l3_prog_cls[i].pid;
28674df55fdeSJanie Lu 
28684df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_usr_cls_get_iptun(handle, (tcam_class_t)cls_id,
28694df55fdeSJanie Lu 	    &iptunp->l4b0_val, &iptunp->l4b0_mask, &iptunp->l4b23_val,
28704df55fdeSJanie Lu 	    &iptunp->l4b23_sel);
28714df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
28724df55fdeSJanie Lu 		goto fail;
28734df55fdeSJanie Lu 
28744df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
28754df55fdeSJanie Lu 	    (tcam_class_t)cls_id, &cfg);
28764df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
28774df55fdeSJanie Lu 		goto fail;
28784df55fdeSJanie Lu 
28794df55fdeSJanie Lu 	iptunp->l4xor_sel = cfg.l4_xor_sel;
28804df55fdeSJanie Lu 	if (cfg.use_proto)
28814df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_L3PROTO;
28824df55fdeSJanie Lu 	else if (cfg.use_daddr)
28834df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_IPDA;
28844df55fdeSJanie Lu 	else if (cfg.use_saddr)
28854df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_IPSA;
28864df55fdeSJanie Lu 	else if (cfg.use_vlan)
28874df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_VLAN;
28884df55fdeSJanie Lu 	else if (cfg.use_l2da)
28894df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_L2DA;
28904df55fdeSJanie Lu 	else if (cfg.use_portnum)
28914df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_IFPORT;
28924df55fdeSJanie Lu 
28934df55fdeSJanie Lu 	switch (pid) {
28944df55fdeSJanie Lu 	case 4:
28954df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_IPV4;
28964df55fdeSJanie Lu 		break;
28974df55fdeSJanie Lu 	case 41:
28984df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_IPV6;
28994df55fdeSJanie Lu 		break;
29004df55fdeSJanie Lu 	case 47:
29014df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_GRE;
29024df55fdeSJanie Lu 		break;
29034df55fdeSJanie Lu 	case 17:
29044df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_GTP;
29054df55fdeSJanie Lu 		break;
29064df55fdeSJanie Lu 	default:
29074df55fdeSJanie Lu 		iptunp->in_pkt_type = 0;
29084df55fdeSJanie Lu 		break;
29094df55fdeSJanie Lu 	}
29104df55fdeSJanie Lu 
29114df55fdeSJanie Lu 	return;
29124df55fdeSJanie Lu fail:
29134df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_iptun_class: FAILED"));
29144df55fdeSJanie Lu }
29154df55fdeSJanie Lu 
29164df55fdeSJanie Lu void
nxge_set_ip_cls_sym(p_nxge_t nxgep,uint8_t cls_id,uint8_t sym)29174df55fdeSJanie Lu nxge_set_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t sym)
29184df55fdeSJanie Lu {
29194df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
29204df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
29214df55fdeSJanie Lu 	boolean_t sym_en = (sym == 1) ? B_TRUE : B_FALSE;
29224df55fdeSJanie Lu 
29234df55fdeSJanie Lu 	rs = npi_fflp_cfg_sym_ip_cls_flow_key(handle, (tcam_class_t)cls_id,
29244df55fdeSJanie Lu 	    sym_en);
29254df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
29264df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
29274df55fdeSJanie Lu 		    "nxge_set_ip_cls_sym: FAILED"));
29284df55fdeSJanie Lu }
29294df55fdeSJanie Lu 
29304df55fdeSJanie Lu void
nxge_get_ip_cls_sym(p_nxge_t nxgep,uint8_t cls_id,uint8_t * sym)29314df55fdeSJanie Lu nxge_get_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t *sym)
29324df55fdeSJanie Lu {
29334df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
29344df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
29354df55fdeSJanie Lu 	flow_key_cfg_t cfg;
29364df55fdeSJanie Lu 
29374df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
29384df55fdeSJanie Lu 	    (tcam_class_t)cls_id, &cfg);
29394df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
29404df55fdeSJanie Lu 		goto fail;
29414df55fdeSJanie Lu 
29424df55fdeSJanie Lu 	if (cfg.use_sym)
29434df55fdeSJanie Lu 		*sym = 1;
29444df55fdeSJanie Lu 	else
29454df55fdeSJanie Lu 		*sym = 0;
29464df55fdeSJanie Lu 	return;
29474df55fdeSJanie Lu fail:
29484df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_ip_cls_sym: FAILED"));
29494df55fdeSJanie Lu }
2950