xref: /onnv-gate/usr/src/uts/common/io/nxge/nxge_fflp.c (revision 4977:6ff1c7caf2c9)
13859Sml29623 /*
23859Sml29623  * CDDL HEADER START
33859Sml29623  *
43859Sml29623  * The contents of this file are subject to the terms of the
53859Sml29623  * Common Development and Distribution License (the "License").
63859Sml29623  * You may not use this file except in compliance with the License.
73859Sml29623  *
83859Sml29623  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93859Sml29623  * or http://www.opensolaris.org/os/licensing.
103859Sml29623  * See the License for the specific language governing permissions
113859Sml29623  * and limitations under the License.
123859Sml29623  *
133859Sml29623  * When distributing Covered Code, include this CDDL HEADER in each
143859Sml29623  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153859Sml29623  * If applicable, add the following below this CDDL HEADER, with the
163859Sml29623  * fields enclosed by brackets "[]" replaced with your own identifying
173859Sml29623  * information: Portions Copyright [yyyy] [name of copyright owner]
183859Sml29623  *
193859Sml29623  * CDDL HEADER END
203859Sml29623  */
213859Sml29623 /*
223859Sml29623  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
233859Sml29623  * Use is subject to license terms.
243859Sml29623  */
253859Sml29623 
263859Sml29623 #pragma ident	"%Z%%M%	%I%	%E% SMI"
273859Sml29623 
283859Sml29623 #include <npi_fflp.h>
293859Sml29623 #include <npi_mac.h>
303859Sml29623 #include <nxge_defs.h>
313859Sml29623 #include <nxge_flow.h>
323859Sml29623 #include <nxge_fflp.h>
333859Sml29623 #include <nxge_impl.h>
343859Sml29623 #include <nxge_fflp_hash.h>
353859Sml29623 #include <nxge_common.h>
363859Sml29623 
373859Sml29623 
383859Sml29623 /*
393859Sml29623  * Function prototypes
403859Sml29623  */
413859Sml29623 static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t);
423859Sml29623 static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t);
433859Sml29623 static nxge_status_t nxge_fflp_tcam_init(p_nxge_t);
443859Sml29623 static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t);
453859Sml29623 static nxge_status_t nxge_fflp_fcram_init(p_nxge_t);
463859Sml29623 static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *);
473859Sml29623 static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
483859Sml29623 static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
493859Sml29623 static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
503859Sml29623 static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *,
513859Sml29623 	tcam_entry_t *);
523859Sml29623 static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *,
533859Sml29623 	tcam_entry_t *);
543859Sml29623 static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *,
553859Sml29623 	tcam_entry_t *);
563859Sml29623 static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, intptr_t);
573859Sml29623 static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, intptr_t);
583859Sml29623 static tcam_location_t nxge_get_tcam_location(p_nxge_t, uint8_t);
593859Sml29623 
603859Sml29623 /*
613859Sml29623  * functions used outside this file
623859Sml29623  */
633859Sml29623 nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t);
643859Sml29623 nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t);
653859Sml29623 nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *);
663859Sml29623 static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t);
673859Sml29623 nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *);
683859Sml29623 nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *);
693859Sml29623 nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *,
703859Sml29623 	uint32_t *, uint16_t *);
713859Sml29623 
723859Sml29623 nxge_status_t
733859Sml29623 nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location)
743859Sml29623 {
753859Sml29623 	tcam_entry_t tcam_rdptr;
763859Sml29623 	uint64_t asc_ram = 0;
773859Sml29623 	npi_handle_t handle;
783859Sml29623 	npi_status_t status;
793859Sml29623 
803859Sml29623 	handle = nxgep->npi_reg_handle;
813859Sml29623 
823859Sml29623 	bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry));
833859Sml29623 	status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location,
843859Sml29623 		(struct tcam_entry *)&tcam_rdptr);
853859Sml29623 	if (status & NPI_FAILURE) {
863859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
873859Sml29623 			" nxge_tcam_dump_entry:"
883859Sml29623 			"  tcam read failed at location %d ", location));
893859Sml29623 		return (NXGE_ERROR);
903859Sml29623 	}
913859Sml29623 	status = npi_fflp_tcam_asc_ram_entry_read(handle,
923859Sml29623 		(tcam_location_t)location, &asc_ram);
933859Sml29623 
943859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n"
953859Sml29623 		" key:  %llx %llx %llx %llx \n"
963859Sml29623 		" mask: %llx %llx %llx %llx \n"
973859Sml29623 		" ASC RAM %llx \n", location,
983859Sml29623 		tcam_rdptr.key0, tcam_rdptr.key1,
993859Sml29623 		tcam_rdptr.key2, tcam_rdptr.key3,
1003859Sml29623 		tcam_rdptr.mask0, tcam_rdptr.mask1,
1013859Sml29623 		tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram));
1023859Sml29623 	return (NXGE_OK);
1033859Sml29623 }
1043859Sml29623 
1053859Sml29623 void
1063859Sml29623 nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp)
1073859Sml29623 {
1083859Sml29623 	uint32_t tcam_loc;
1093859Sml29623 	int *lptr;
1103859Sml29623 	int location;
1113859Sml29623 
1123859Sml29623 	uint32_t start_location = 0;
1133859Sml29623 	uint32_t stop_location = nxgep->classifier.tcam_size;
1143859Sml29623 	lptr = (int *)mp->b_rptr;
1153859Sml29623 	location = *lptr;
1163859Sml29623 
1173859Sml29623 	if ((location >= nxgep->classifier.tcam_size) || (location < -1)) {
1183859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1193859Sml29623 			"nxge_tcam_dump: Invalid location %d \n", location));
1203859Sml29623 		return;
1213859Sml29623 	}
1223859Sml29623 	if (location == -1) {
1233859Sml29623 		start_location = 0;
1243859Sml29623 		stop_location = nxgep->classifier.tcam_size;
1253859Sml29623 	} else {
1263859Sml29623 		start_location = location;
1273859Sml29623 		stop_location = location + 1;
1283859Sml29623 	}
1293859Sml29623 	for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++)
1303859Sml29623 		(void) nxge_tcam_dump_entry(nxgep, tcam_loc);
1313859Sml29623 }
1323859Sml29623 
1333859Sml29623 /*
1343859Sml29623  * nxge_fflp_vlan_table_invalidate_all
1353859Sml29623  * invalidates the vlan RDC table entries.
1363859Sml29623  * INPUT
1373859Sml29623  * nxge    soft state data structure
1383859Sml29623  * Return
1393859Sml29623  *      NXGE_OK
1403859Sml29623  *      NXGE_ERROR
1413859Sml29623  *
1423859Sml29623  */
1433859Sml29623 
1443859Sml29623 static nxge_status_t
1453859Sml29623 nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)
1463859Sml29623 {
1473859Sml29623 	vlan_id_t vlan_id;
1483859Sml29623 	npi_handle_t handle;
1493859Sml29623 	npi_status_t rs = NPI_SUCCESS;
1503859Sml29623 	vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
1513859Sml29623 
1523859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all "));
1533859Sml29623 	handle = nxgep->npi_reg_handle;
1543859Sml29623 	for (vlan_id = start; vlan_id < stop; vlan_id++) {
1553859Sml29623 		rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id);
1563859Sml29623 		if (rs != NPI_SUCCESS) {
1573859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1583859Sml29623 				"VLAN Table invalidate failed for vlan id %d ",
1593859Sml29623 				vlan_id));
1603859Sml29623 			return (NXGE_ERROR | rs);
1613859Sml29623 		}
1623859Sml29623 	}
1633859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all "));
1643859Sml29623 	return (NXGE_OK);
1653859Sml29623 }
1663859Sml29623 
1673859Sml29623 /*
1683859Sml29623  * The following functions are used by other modules to init
1693859Sml29623  * the fflp module.
1703859Sml29623  * these functions are the basic API used to init
1713859Sml29623  * the fflp modules (tcam, fcram etc ......)
1723859Sml29623  *
1733859Sml29623  * The TCAM search future would be disabled  by default.
1743859Sml29623  */
1753859Sml29623 
1763859Sml29623 static nxge_status_t
1773859Sml29623 nxge_fflp_tcam_init(p_nxge_t nxgep)
1783859Sml29623 {
1793859Sml29623 	uint8_t access_ratio;
1803859Sml29623 	tcam_class_t class;
1813859Sml29623 	npi_status_t rs = NPI_SUCCESS;
1823859Sml29623 	npi_handle_t handle;
1833859Sml29623 
1843859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init"));
1853859Sml29623 	handle = nxgep->npi_reg_handle;
1863859Sml29623 
1873859Sml29623 	rs = npi_fflp_cfg_tcam_disable(handle);
1883859Sml29623 	if (rs != NPI_SUCCESS) {
1893859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n"));
1903859Sml29623 		return (NXGE_ERROR | rs);
1913859Sml29623 	}
1923859Sml29623 
1933859Sml29623 	access_ratio = nxgep->param_arr[param_tcam_access_ratio].value;
1943859Sml29623 	rs = npi_fflp_cfg_tcam_access(handle, access_ratio);
1953859Sml29623 	if (rs != NPI_SUCCESS) {
1963859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1973859Sml29623 				"failed TCAM Access cfg\n"));
1983859Sml29623 		return (NXGE_ERROR | rs);
1993859Sml29623 	}
2003859Sml29623 
2013859Sml29623 	/* disable configurable classes */
2023859Sml29623 	/* disable the configurable ethernet classes; */
2033859Sml29623 	for (class = TCAM_CLASS_ETYPE_1;
2043859Sml29623 		class <= TCAM_CLASS_ETYPE_2; class++) {
2053859Sml29623 		rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class);
2063859Sml29623 		if (rs != NPI_SUCCESS) {
2073859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2083859Sml29623 				"TCAM USR Ether Class config failed."));
2093859Sml29623 			return (NXGE_ERROR | rs);
2103859Sml29623 		}
2113859Sml29623 	}
2123859Sml29623 
2133859Sml29623 	/* disable the configurable ip classes; */
2143859Sml29623 	for (class = TCAM_CLASS_IP_USER_4;
2153859Sml29623 		class <= TCAM_CLASS_IP_USER_7; class++) {
2163859Sml29623 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
2173859Sml29623 		if (rs != NPI_SUCCESS) {
2183859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2193859Sml29623 				"TCAM USR IP Class cnfg failed."));
2203859Sml29623 			return (NXGE_ERROR | rs);
2213859Sml29623 		}
2223859Sml29623 	}
2233859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init"));
2243859Sml29623 	return (NXGE_OK);
2253859Sml29623 }
2263859Sml29623 
2273859Sml29623 /*
2283859Sml29623  * nxge_fflp_tcam_invalidate_all
2293859Sml29623  * invalidates all the tcam entries.
2303859Sml29623  * INPUT
2313859Sml29623  * nxge    soft state data structure
2323859Sml29623  * Return
2333859Sml29623  *      NXGE_OK
2343859Sml29623  *      NXGE_ERROR
2353859Sml29623  *
2363859Sml29623  */
2373859Sml29623 
2383859Sml29623 
2393859Sml29623 static nxge_status_t
2403859Sml29623 nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)
2413859Sml29623 {
2423859Sml29623 	uint16_t location;
2433859Sml29623 	npi_status_t rs = NPI_SUCCESS;
2443859Sml29623 	npi_handle_t handle;
2453859Sml29623 	uint16_t start = 0, stop = nxgep->classifier.tcam_size;
2463859Sml29623 	p_nxge_hw_list_t hw_p;
2473859Sml29623 
2483859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
2493859Sml29623 		"==> nxge_fflp_tcam_invalidate_all"));
2503859Sml29623 	handle = nxgep->npi_reg_handle;
2513859Sml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
2523859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2533859Sml29623 			" nxge_fflp_tcam_invalidate_all:"
2543859Sml29623 			" common hardware not set", nxgep->niu_type));
2553859Sml29623 		return (NXGE_ERROR);
2563859Sml29623 	}
2573859Sml29623 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
2583859Sml29623 	for (location = start; location < stop; location++) {
2593859Sml29623 		rs = npi_fflp_tcam_entry_invalidate(handle, location);
2603859Sml29623 		if (rs != NPI_SUCCESS) {
2613859Sml29623 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2623859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2633859Sml29623 				"TCAM invalidate failed at loc %d ", location));
2643859Sml29623 			return (NXGE_ERROR | rs);
2653859Sml29623 		}
2663859Sml29623 	}
2673859Sml29623 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2683859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
2693859Sml29623 			"<== nxge_fflp_tcam_invalidate_all"));
2703859Sml29623 	return (NXGE_OK);
2713859Sml29623 }
2723859Sml29623 
2733859Sml29623 /*
2743859Sml29623  * nxge_fflp_fcram_entry_invalidate_all
2753859Sml29623  * invalidates all the FCRAM entries.
2763859Sml29623  * INPUT
2773859Sml29623  * nxge    soft state data structure
2783859Sml29623  * Return
2793859Sml29623  *      NXGE_OK
2803859Sml29623  *      NXGE_ERROR
2813859Sml29623  *
2823859Sml29623  */
2833859Sml29623 
2843859Sml29623 static nxge_status_t
2853859Sml29623 nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)
2863859Sml29623 {
2873859Sml29623 	npi_handle_t handle;
2883859Sml29623 	npi_status_t rs = NPI_SUCCESS;
2893859Sml29623 	part_id_t pid = 0;
2903859Sml29623 	uint8_t base_mask, base_reloc;
2913859Sml29623 	fcram_entry_t fc;
2923859Sml29623 	uint32_t location;
2933859Sml29623 	uint32_t increment, last_location;
2943859Sml29623 
2953859Sml29623 	/*
2963859Sml29623 	 * (1) configure and enable partition 0 with no relocation
2973859Sml29623 	 * (2) Assume the FCRAM is used as IPv4 exact match entry cells
2983859Sml29623 	 * (3) Invalidate these cells by clearing the valid bit in
2993859Sml29623 	 * the subareas 0 and 4
3003859Sml29623 	 * (4) disable the partition
3013859Sml29623 	 *
3023859Sml29623 	 */
3033859Sml29623 
3043859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all"));
3053859Sml29623 
3063859Sml29623 	base_mask = base_reloc = 0x0;
3073859Sml29623 	handle = nxgep->npi_reg_handle;
3083859Sml29623 	rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc);
3093859Sml29623 
3103859Sml29623 	if (rs != NPI_SUCCESS) {
3113859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n"));
3123859Sml29623 		return (NXGE_ERROR | rs);
3133859Sml29623 	}
3143859Sml29623 	rs = npi_fflp_cfg_fcram_partition_disable(handle, pid);
3153859Sml29623 
3163859Sml29623 	if (rs != NPI_SUCCESS) {
3173859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3183859Sml29623 			"failed partition enable\n"));
3193859Sml29623 		return (NXGE_ERROR | rs);
3203859Sml29623 	}
3213859Sml29623 	fc.dreg[0].value = 0;
3223859Sml29623 	fc.hash_hdr_valid = 0;
3233859Sml29623 	fc.hash_hdr_ext = 1;	/* specify as IPV4 exact match entry */
3243859Sml29623 	increment = sizeof (hash_ipv4_t);
3253859Sml29623 	last_location = FCRAM_SIZE * 0x40;
3263859Sml29623 
3273859Sml29623 	for (location = 0; location < last_location; location += increment) {
3283859Sml29623 		rs = npi_fflp_fcram_subarea_write(handle, pid,
3293859Sml29623 			location,
3303859Sml29623 			fc.value[0]);
3313859Sml29623 		if (rs != NPI_SUCCESS) {
3323859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3333859Sml29623 					"failed write"
3343859Sml29623 					"at location %x ",
3353859Sml29623 					location));
3363859Sml29623 			return (NXGE_ERROR | rs);
3373859Sml29623 		}
3383859Sml29623 	}
3393859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all"));
3403859Sml29623 	return (NXGE_OK);
3413859Sml29623 }
3423859Sml29623 
3433859Sml29623 static nxge_status_t
3443859Sml29623 nxge_fflp_fcram_init(p_nxge_t nxgep)
3453859Sml29623 {
3463859Sml29623 	fflp_fcram_output_drive_t strength;
3473859Sml29623 	fflp_fcram_qs_t qs;
3483859Sml29623 	npi_status_t rs = NPI_SUCCESS;
3493859Sml29623 	uint8_t access_ratio;
3503859Sml29623 	int partition;
3513859Sml29623 	npi_handle_t handle;
3523859Sml29623 	uint32_t min_time, max_time, sys_time;
3533859Sml29623 
3543859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init"));
3553859Sml29623 
3563859Sml29623 	/*
3573859Sml29623 	 * Recommended values are needed.
3583859Sml29623 	 */
3593859Sml29623 	min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME;
3603859Sml29623 	max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME;
3613859Sml29623 	sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME;
3623859Sml29623 
3633859Sml29623 	handle = nxgep->npi_reg_handle;
3643859Sml29623 	strength = FCRAM_OUTDR_NORMAL;
3653859Sml29623 	qs = FCRAM_QS_MODE_QS;
3663859Sml29623 	rs = npi_fflp_cfg_fcram_reset(handle, strength, qs);
3673859Sml29623 	if (rs != NPI_SUCCESS) {
3683859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. "));
3693859Sml29623 		return (NXGE_ERROR | rs);
3703859Sml29623 	}
3713859Sml29623 
3723859Sml29623 	access_ratio = nxgep->param_arr[param_fcram_access_ratio].value;
3733859Sml29623 	rs = npi_fflp_cfg_fcram_access(handle, access_ratio);
3743859Sml29623 	if (rs != NPI_SUCCESS) {
3753859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio"
3763859Sml29623 			"configuration \n"));
3773859Sml29623 		return (NXGE_ERROR | rs);
3783859Sml29623 	}
3793859Sml29623 	rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time,
3803859Sml29623 		max_time, sys_time);
3813859Sml29623 	if (rs != NPI_SUCCESS) {
3823859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3833859Sml29623 			"failed FCRAM refresh cfg"));
3843859Sml29623 		return (NXGE_ERROR);
3853859Sml29623 	}
3863859Sml29623 
3873859Sml29623 	/* disable all the partitions until explicitly enabled */
3883859Sml29623 	for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) {
3893859Sml29623 		rs = npi_fflp_cfg_fcram_partition_disable(handle, partition);
3903859Sml29623 		if (rs != NPI_SUCCESS) {
3913859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3923859Sml29623 				"failed FCRAM partition"
3933859Sml29623 				" enable for partition %d ", partition));
3943859Sml29623 			return (NXGE_ERROR | rs);
3953859Sml29623 		}
3963859Sml29623 	}
3973859Sml29623 
3983859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init"));
3993859Sml29623 	return (NXGE_OK);
4003859Sml29623 }
4013859Sml29623 
4023859Sml29623 nxge_status_t
4033859Sml29623 nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac)
4043859Sml29623 {
4053859Sml29623 	npi_status_t rs = NPI_SUCCESS;
4063859Sml29623 	hostinfo_t mac_rdc;
4073859Sml29623 	npi_handle_t handle;
4083859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
4093859Sml29623 
4103859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
4113859Sml29623 	if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) {
4123859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4133859Sml29623 			" nxge_logical_mac_assign_rdc_table"
4143859Sml29623 			" unconfigured alt MAC addr %d ", alt_mac));
4153859Sml29623 		return (NXGE_ERROR);
4163859Sml29623 	}
4173859Sml29623 	handle = nxgep->npi_reg_handle;
4183859Sml29623 	mac_rdc.value = 0;
4193859Sml29623 	mac_rdc.bits.w0.rdc_tbl_num =
4203859Sml29623 		p_class_cfgp->mac_host_info[alt_mac].rdctbl;
4213859Sml29623 	mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr;
4223859Sml29623 
4233859Sml29623 	rs = npi_mac_hostinfo_entry(handle, OP_SET,
4243859Sml29623 		nxgep->function_num, alt_mac, &mac_rdc);
4253859Sml29623 
4263859Sml29623 	if (rs != NPI_SUCCESS) {
4273859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4283859Sml29623 			"failed Assign RDC table"));
4293859Sml29623 		return (NXGE_ERROR | rs);
4303859Sml29623 	}
4313859Sml29623 	return (NXGE_OK);
4323859Sml29623 }
4333859Sml29623 
4343859Sml29623 nxge_status_t
4353859Sml29623 nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)
4363859Sml29623 {
4373859Sml29623 	npi_status_t rs = NPI_SUCCESS;
4383859Sml29623 	hostinfo_t mac_rdc;
4393859Sml29623 	npi_handle_t handle;
4403859Sml29623 
4413859Sml29623 	handle = nxgep->npi_reg_handle;
4423859Sml29623 	mac_rdc.value = 0;
4433859Sml29623 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp;
4443859Sml29623 	mac_rdc.bits.w0.mac_pref = 1;
4453859Sml29623 	switch (nxgep->function_num) {
4463859Sml29623 	case 0:
4473859Sml29623 	case 1:
4483859Sml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
4493859Sml29623 			nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY,
4503859Sml29623 			&mac_rdc);
4513859Sml29623 		break;
4523859Sml29623 	case 2:
4533859Sml29623 	case 3:
4543859Sml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
4553859Sml29623 			nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY,
4563859Sml29623 			&mac_rdc);
4573859Sml29623 		break;
4583859Sml29623 	default:
4593859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4603859Sml29623 			"failed Assign RDC table (invalid function #)"));
4613859Sml29623 		return (NXGE_ERROR);
4623859Sml29623 	}
4633859Sml29623 
4643859Sml29623 	if (rs != NPI_SUCCESS) {
4653859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4663859Sml29623 				"failed Assign RDC table"));
4673859Sml29623 		return (NXGE_ERROR | rs);
4683859Sml29623 	}
4693859Sml29623 	return (NXGE_OK);
4703859Sml29623 }
4713859Sml29623 
4723859Sml29623 /*
4733859Sml29623  * Initialize hostinfo registers for alternate MAC addresses and
4743859Sml29623  * multicast MAC address.
4753859Sml29623  */
4763859Sml29623 nxge_status_t
4773859Sml29623 nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)
4783859Sml29623 {
4793859Sml29623 	npi_status_t rs = NPI_SUCCESS;
4803859Sml29623 	hostinfo_t mac_rdc;
4813859Sml29623 	npi_handle_t handle;
4823859Sml29623 	int i;
4833859Sml29623 
4843859Sml29623 	handle = nxgep->npi_reg_handle;
4853859Sml29623 	mac_rdc.value = 0;
4863859Sml29623 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp;
4873859Sml29623 	mac_rdc.bits.w0.mac_pref = 1;
4883859Sml29623 	switch (nxgep->function_num) {
4893859Sml29623 	case 0:
4903859Sml29623 	case 1:
4913859Sml29623 		/*
4923859Sml29623 		 * Tests indicate that it is OK not to re-initialize the
4933859Sml29623 		 * hostinfo registers for the XMAC's alternate MAC
4943859Sml29623 		 * addresses. But that is necessary for BMAC (case 2
4953859Sml29623 		 * and case 3 below)
4963859Sml29623 		 */
4973859Sml29623 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
4983859Sml29623 			nxgep->function_num,
4993859Sml29623 			XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
5003859Sml29623 		break;
5013859Sml29623 	case 2:
5023859Sml29623 	case 3:
5033859Sml29623 		for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
5043859Sml29623 			rs |= npi_mac_hostinfo_entry(handle, OP_SET,
5053859Sml29623 			nxgep->function_num, i, &mac_rdc);
5063859Sml29623 
5073859Sml29623 		rs |= npi_mac_hostinfo_entry(handle, OP_SET,
5083859Sml29623 			nxgep->function_num,
5093859Sml29623 			BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
5103859Sml29623 		break;
5113859Sml29623 	default:
5123859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5133859Sml29623 			"failed Assign RDC table (invalid funcion #)"));
5143859Sml29623 		return (NXGE_ERROR);
5153859Sml29623 	}
5163859Sml29623 
5173859Sml29623 	if (rs != NPI_SUCCESS) {
5183859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5193859Sml29623 			"failed Assign RDC table"));
5203859Sml29623 		return (NXGE_ERROR | rs);
5213859Sml29623 	}
5223859Sml29623 	return (NXGE_OK);
5233859Sml29623 }
5243859Sml29623 
5253859Sml29623 nxge_status_t
5263859Sml29623 nxge_fflp_init_hostinfo(p_nxge_t nxgep)
5273859Sml29623 {
5283859Sml29623 	nxge_status_t status = NXGE_OK;
5293859Sml29623 
5303859Sml29623 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
5313859Sml29623 	status |= nxge_main_mac_assign_rdc_table(nxgep);
5323859Sml29623 	return (status);
5333859Sml29623 }
5343859Sml29623 
5353859Sml29623 nxge_status_t
5363859Sml29623 nxge_fflp_hw_reset(p_nxge_t nxgep)
5373859Sml29623 {
5383859Sml29623 	npi_handle_t handle;
5393859Sml29623 	npi_status_t rs = NPI_SUCCESS;
5403859Sml29623 	nxge_status_t status = NXGE_OK;
5413859Sml29623 
5423859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
5433859Sml29623 
544*4977Sraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
5453859Sml29623 		status = nxge_fflp_fcram_init(nxgep);
5463859Sml29623 		if (status != NXGE_OK) {
5473859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5483859Sml29623 				" failed FCRAM init. "));
5493859Sml29623 			return (status);
5503859Sml29623 		}
5513859Sml29623 	}
5523859Sml29623 
5533859Sml29623 	status = nxge_fflp_tcam_init(nxgep);
5543859Sml29623 	if (status != NXGE_OK) {
5553859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5563859Sml29623 			"failed TCAM init."));
5573859Sml29623 		return (status);
5583859Sml29623 	}
5593859Sml29623 
5603859Sml29623 	handle = nxgep->npi_reg_handle;
5613859Sml29623 	rs = npi_fflp_cfg_llcsnap_enable(handle);
5623859Sml29623 	if (rs != NPI_SUCCESS) {
5633859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5643859Sml29623 			"failed LLCSNAP enable. "));
5653859Sml29623 		return (NXGE_ERROR | rs);
5663859Sml29623 	}
5673859Sml29623 
5683859Sml29623 	rs = npi_fflp_cfg_cam_errorcheck_disable(handle);
5693859Sml29623 	if (rs != NPI_SUCCESS) {
5703859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5713859Sml29623 			"failed CAM Error Check enable. "));
5723859Sml29623 		return (NXGE_ERROR | rs);
5733859Sml29623 	}
5743859Sml29623 
5753859Sml29623 	/* init the hash generators */
5763859Sml29623 	rs = npi_fflp_cfg_hash_h1poly(handle, 0);
5773859Sml29623 	if (rs != NPI_SUCCESS) {
5783859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5793859Sml29623 			"failed H1 Poly Init. "));
5803859Sml29623 		return (NXGE_ERROR | rs);
5813859Sml29623 	}
5823859Sml29623 
5833859Sml29623 	rs = npi_fflp_cfg_hash_h2poly(handle, 0);
5843859Sml29623 	if (rs != NPI_SUCCESS) {
5853859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5863859Sml29623 			"failed H2 Poly Init. "));
5873859Sml29623 		return (NXGE_ERROR | rs);
5883859Sml29623 	}
5893859Sml29623 
5903859Sml29623 	/* invalidate TCAM entries */
5913859Sml29623 	status = nxge_fflp_tcam_invalidate_all(nxgep);
5923859Sml29623 	if (status != NXGE_OK) {
5933859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5943859Sml29623 			"failed TCAM Entry Invalidate. "));
5953859Sml29623 		return (status);
5963859Sml29623 	}
5973859Sml29623 
5983859Sml29623 	/* invalidate FCRAM entries */
599*4977Sraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6003859Sml29623 		status = nxge_fflp_fcram_invalidate_all(nxgep);
6013859Sml29623 		if (status != NXGE_OK) {
6023859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6033859Sml29623 					"failed FCRAM Entry Invalidate."));
6043859Sml29623 			return (status);
6053859Sml29623 		}
6063859Sml29623 	}
6073859Sml29623 
6083859Sml29623 	/* invalidate VLAN RDC tables */
6093859Sml29623 	status = nxge_fflp_vlan_tbl_clear_all(nxgep);
6103859Sml29623 	if (status != NXGE_OK) {
6113859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6123859Sml29623 			"failed VLAN Table Invalidate. "));
6133859Sml29623 		return (status);
6143859Sml29623 	}
6153859Sml29623 	nxgep->classifier.state |= NXGE_FFLP_HW_RESET;
6163859Sml29623 
6173859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset"));
6183859Sml29623 	return (NXGE_OK);
6193859Sml29623 }
6203859Sml29623 
6213859Sml29623 nxge_status_t
6223859Sml29623 nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class,
6233859Sml29623 	uint32_t class_config)
6243859Sml29623 {
6253859Sml29623 	flow_key_cfg_t fcfg;
6263859Sml29623 	npi_handle_t handle;
6273859Sml29623 	npi_status_t rs = NPI_SUCCESS;
6283859Sml29623 
6293859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key"));
6303859Sml29623 	handle = nxgep->npi_reg_handle;
6313859Sml29623 	bzero(&fcfg, sizeof (flow_key_cfg_t));
6323859Sml29623 
6333859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_PROTO)
6343859Sml29623 		fcfg.use_proto = 1;
6353859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT)
6363859Sml29623 		fcfg.use_dport = 1;
6373859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT)
6383859Sml29623 		fcfg.use_sport = 1;
6393859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_IPDST)
6403859Sml29623 		fcfg.use_daddr = 1;
6413859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_IPSRC)
6423859Sml29623 		fcfg.use_saddr = 1;
6433859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_VLAN)
6443859Sml29623 		fcfg.use_vlan = 1;
6453859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_L2DA)
6463859Sml29623 		fcfg.use_l2da = 1;
6473859Sml29623 	if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM)
6483859Sml29623 		fcfg.use_portnum = 1;
6493859Sml29623 	fcfg.ip_opts_exist = 0;
6503859Sml29623 
6513859Sml29623 	rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg);
6523859Sml29623 	if (rs & NPI_FFLP_ERROR) {
6533859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
6543859Sml29623 			" opt %x for class %d failed ",
6553859Sml29623 			class_config, l3_class));
6563859Sml29623 		return (NXGE_ERROR | rs);
6573859Sml29623 	}
6583859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key"));
6593859Sml29623 	return (NXGE_OK);
6603859Sml29623 }
6613859Sml29623 
6623859Sml29623 nxge_status_t
6633859Sml29623 nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class,
6643859Sml29623 	uint32_t *class_config)
6653859Sml29623 {
6663859Sml29623 	flow_key_cfg_t fcfg;
6673859Sml29623 	npi_handle_t handle;
6683859Sml29623 	npi_status_t rs = NPI_SUCCESS;
6693859Sml29623 	uint32_t ccfg = 0;
6703859Sml29623 
6713859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get"));
6723859Sml29623 	handle = nxgep->npi_reg_handle;
6733859Sml29623 	bzero(&fcfg, sizeof (flow_key_cfg_t));
6743859Sml29623 
6753859Sml29623 	rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg);
6763859Sml29623 	if (rs & NPI_FFLP_ERROR) {
6773859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
6783859Sml29623 				" opt %x for class %d failed ",
6793859Sml29623 				class_config, l3_class));
6803859Sml29623 		return (NXGE_ERROR | rs);
6813859Sml29623 	}
6823859Sml29623 
6833859Sml29623 	if (fcfg.use_proto)
6843859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_PROTO;
6853859Sml29623 	if (fcfg.use_dport)
6863859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT;
6873859Sml29623 	if (fcfg.use_sport)
6883859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT;
6893859Sml29623 	if (fcfg.use_daddr)
6903859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_IPDST;
6913859Sml29623 	if (fcfg.use_saddr)
6923859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_IPSRC;
6933859Sml29623 	if (fcfg.use_vlan)
6943859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_VLAN;
6953859Sml29623 	if (fcfg.use_l2da)
6963859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_L2DA;
6973859Sml29623 	if (fcfg.use_portnum)
6983859Sml29623 		ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM;
6993859Sml29623 
7003859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7013859Sml29623 		" nxge_cfg_ip_cls_flow_key_get %x", ccfg));
7023859Sml29623 	*class_config = ccfg;
7033859Sml29623 
7043859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7053859Sml29623 		" <== nxge_cfg_ip_cls_flow_key_get"));
7063859Sml29623 	return (NXGE_OK);
7073859Sml29623 }
7083859Sml29623 
7093859Sml29623 static nxge_status_t
7103859Sml29623 nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class,
7113859Sml29623 	uint32_t *class_config)
7123859Sml29623 {
7133859Sml29623 	npi_status_t rs = NPI_SUCCESS;
7143859Sml29623 	tcam_key_cfg_t cfg;
7153859Sml29623 	npi_handle_t handle;
7163859Sml29623 	uint32_t ccfg = 0;
7173859Sml29623 
7183859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
7193859Sml29623 
7203859Sml29623 	bzero(&cfg, sizeof (tcam_key_cfg_t));
7213859Sml29623 	handle = nxgep->npi_reg_handle;
7223859Sml29623 
7233859Sml29623 	rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg);
7243859Sml29623 	if (rs & NPI_FFLP_ERROR) {
7253859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
7263859Sml29623 			" opt %x for class %d failed ",
7273859Sml29623 			class_config, class));
7283859Sml29623 		return (NXGE_ERROR | rs);
7293859Sml29623 	}
7303859Sml29623 	if (cfg.discard)
7313859Sml29623 		ccfg |= NXGE_CLASS_DISCARD;
7323859Sml29623 	if (cfg.lookup_enable)
7333859Sml29623 		ccfg |= NXGE_CLASS_TCAM_LOOKUP;
7343859Sml29623 	if (cfg.use_ip_daddr)
7353859Sml29623 		ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR;
7363859Sml29623 	*class_config = ccfg;
7373859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7383859Sml29623 			" ==> nxge_cfg_tcam_ip_class %x", ccfg));
7393859Sml29623 	return (NXGE_OK);
7403859Sml29623 }
7413859Sml29623 
7423859Sml29623 static nxge_status_t
7433859Sml29623 nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class,
7443859Sml29623 	uint32_t class_config)
7453859Sml29623 {
7463859Sml29623 	npi_status_t rs = NPI_SUCCESS;
7473859Sml29623 	tcam_key_cfg_t cfg;
7483859Sml29623 	npi_handle_t handle;
7493859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
7503859Sml29623 
7513859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
7523859Sml29623 
7533859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7543859Sml29623 	p_class_cfgp->class_cfg[class] = class_config;
7553859Sml29623 
7563859Sml29623 	bzero(&cfg, sizeof (tcam_key_cfg_t));
7573859Sml29623 	handle = nxgep->npi_reg_handle;
7583859Sml29623 	cfg.discard = 0;
7593859Sml29623 	cfg.lookup_enable = 0;
7603859Sml29623 	cfg.use_ip_daddr = 0;
7613859Sml29623 	if (class_config & NXGE_CLASS_DISCARD)
7623859Sml29623 		cfg.discard = 1;
7633859Sml29623 	if (class_config & NXGE_CLASS_TCAM_LOOKUP)
7643859Sml29623 		cfg.lookup_enable = 1;
7653859Sml29623 	if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR)
7663859Sml29623 		cfg.use_ip_daddr = 1;
7673859Sml29623 
7683859Sml29623 	rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg);
7693859Sml29623 	if (rs & NPI_FFLP_ERROR) {
7703859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
7713859Sml29623 			" opt %x for class %d failed ",
7723859Sml29623 			class_config, class));
7733859Sml29623 		return (NXGE_ERROR | rs);
7743859Sml29623 	}
7753859Sml29623 	return (NXGE_OK);
7763859Sml29623 }
7773859Sml29623 
7783859Sml29623 nxge_status_t
7793859Sml29623 nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1)
7803859Sml29623 {
7813859Sml29623 	npi_status_t rs = NPI_SUCCESS;
7823859Sml29623 	npi_handle_t handle;
7833859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
7843859Sml29623 
7853859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1"));
7863859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7873859Sml29623 	p_class_cfgp->init_h1 = h1;
7883859Sml29623 	handle = nxgep->npi_reg_handle;
7893859Sml29623 	rs = npi_fflp_cfg_hash_h1poly(handle, h1);
7903859Sml29623 	if (rs & NPI_FFLP_ERROR) {
7913859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
7923859Sml29623 			" nxge_fflp_init_h1 %x failed ", h1));
7933859Sml29623 		return (NXGE_ERROR | rs);
7943859Sml29623 	}
7953859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1"));
7963859Sml29623 	return (NXGE_OK);
7973859Sml29623 }
7983859Sml29623 
7993859Sml29623 nxge_status_t
8003859Sml29623 nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2)
8013859Sml29623 {
8023859Sml29623 	npi_status_t rs = NPI_SUCCESS;
8033859Sml29623 	npi_handle_t handle;
8043859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
8053859Sml29623 
8063859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2"));
8073859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
8083859Sml29623 	p_class_cfgp->init_h2 = h2;
8093859Sml29623 
8103859Sml29623 	handle = nxgep->npi_reg_handle;
8113859Sml29623 	rs = npi_fflp_cfg_hash_h2poly(handle, h2);
8123859Sml29623 	if (rs & NPI_FFLP_ERROR) {
8133859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8143859Sml29623 			" nxge_fflp_init_h2 %x failed ", h2));
8153859Sml29623 		return (NXGE_ERROR | rs);
8163859Sml29623 	}
8173859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2"));
8183859Sml29623 	return (NXGE_OK);
8193859Sml29623 }
8203859Sml29623 
8213859Sml29623 nxge_status_t
8223859Sml29623 nxge_classify_init_sw(p_nxge_t nxgep)
8233859Sml29623 {
8243859Sml29623 	int alloc_size;
8253859Sml29623 	nxge_classify_t *classify_ptr;
8263859Sml29623 
8273859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw"));
8283859Sml29623 	classify_ptr = &nxgep->classifier;
8293859Sml29623 
8303859Sml29623 	if (classify_ptr->state & NXGE_FFLP_SW_INIT) {
8313859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
8323859Sml29623 			"nxge_classify_init_sw already init"));
8333859Sml29623 		return (NXGE_OK);
8343859Sml29623 	}
8353859Sml29623 	/* Init SW structures */
8363859Sml29623 	classify_ptr->tcam_size = TCAM_NIU_TCAM_MAX_ENTRY;
8373859Sml29623 
8383859Sml29623 	/* init data structures, based on HW type */
839*4977Sraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
8403859Sml29623 		classify_ptr->tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY;
8413859Sml29623 		/*
8423859Sml29623 		 * check if fcram based classification is required and init the
8433859Sml29623 		 * flow storage
8443859Sml29623 		 */
8453859Sml29623 	}
8463859Sml29623 	alloc_size = sizeof (tcam_flow_spec_t) * classify_ptr->tcam_size;
8473859Sml29623 	classify_ptr->tcam_entries = KMEM_ZALLOC(alloc_size, NULL);
8483859Sml29623 
8493859Sml29623 	/* Init defaults */
8503859Sml29623 	/*
8513859Sml29623 	 * add hacks required for HW shortcomings for example, code to handle
8523859Sml29623 	 * fragmented packets
8533859Sml29623 	 */
8543859Sml29623 	nxge_init_h1_table();
8553859Sml29623 	nxge_crc_ccitt_init();
8563859Sml29623 	nxgep->classifier.tcam_location = nxgep->function_num;
8573859Sml29623 	nxgep->classifier.fragment_bug = 1;
8583859Sml29623 	classify_ptr->state |= NXGE_FFLP_SW_INIT;
8593859Sml29623 
8603859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw"));
8613859Sml29623 	return (NXGE_OK);
8623859Sml29623 }
8633859Sml29623 
8643859Sml29623 nxge_status_t
8653859Sml29623 nxge_classify_exit_sw(p_nxge_t nxgep)
8663859Sml29623 {
8673859Sml29623 	int alloc_size;
8683859Sml29623 	nxge_classify_t *classify_ptr;
8693859Sml29623 	int fsize;
8703859Sml29623 
8713859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw"));
8723859Sml29623 	classify_ptr = &nxgep->classifier;
8733859Sml29623 
8743859Sml29623 	fsize = sizeof (tcam_flow_spec_t);
8753859Sml29623 	if (classify_ptr->tcam_entries) {
8763859Sml29623 		alloc_size = fsize * classify_ptr->tcam_size;
8773859Sml29623 		KMEM_FREE((void *) classify_ptr->tcam_entries, alloc_size);
8783859Sml29623 	}
8793859Sml29623 	nxgep->classifier.state = NULL;
8803859Sml29623 
8813859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw"));
8823859Sml29623 	return (NXGE_OK);
8833859Sml29623 }
8843859Sml29623 
8853859Sml29623 /*
8863859Sml29623  * Figures out the location where the TCAM entry is
8873859Sml29623  * to be inserted.
8883859Sml29623  *
8893859Sml29623  * The current implementation is just a place holder and it
8903859Sml29623  * returns the next tcam location.
8913859Sml29623  * The real location determining algorithm would consider
8923859Sml29623  * the priority, partition etc ... before deciding which
8933859Sml29623  * location to insert.
8943859Sml29623  *
8953859Sml29623  */
8963859Sml29623 
8973859Sml29623 /* ARGSUSED */
8983859Sml29623 static tcam_location_t
8993859Sml29623 nxge_get_tcam_location(p_nxge_t nxgep, uint8_t class)
9003859Sml29623 {
9013859Sml29623 	tcam_location_t location;
9023859Sml29623 
9033859Sml29623 	location = nxgep->classifier.tcam_location;
9043859Sml29623 	nxgep->classifier.tcam_location = (location + nxgep->nports) %
9053859Sml29623 		nxgep->classifier.tcam_size;
9063859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
9073859Sml29623 		"nxge_get_tcam_location: location %d next %d \n",
9083859Sml29623 		location, nxgep->classifier.tcam_location));
9093859Sml29623 	return (location);
9103859Sml29623 }
9113859Sml29623 
9123859Sml29623 /*
9133859Sml29623  * Figures out the RDC Group for the entry
9143859Sml29623  *
9153859Sml29623  * The current implementation is just a place holder and it
9163859Sml29623  * returns 0.
9173859Sml29623  * The real location determining algorithm would consider
9183859Sml29623  * the partition etc ... before deciding w
9193859Sml29623  *
9203859Sml29623  */
9213859Sml29623 
9223859Sml29623 /* ARGSUSED */
9233859Sml29623 static uint8_t
9243859Sml29623 nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, intptr_t cookie)
9253859Sml29623 {
9263859Sml29623 	int use_port_rdc_grp = 0;
9273859Sml29623 	uint8_t rdc_grp = 0;
9283859Sml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
9293859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
9303859Sml29623 	p_nxge_rdc_grp_t rdc_grp_p;
9313859Sml29623 
9323859Sml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
9333859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
9343859Sml29623 	rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp];
9353859Sml29623 	rdc_grp = p_cfgp->start_rdc_grpid;
9363859Sml29623 
9373859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
9383859Sml29623 		"nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
9393859Sml29623 		cookie, rdc_grp, rdc_grp_p));
9403859Sml29623 	return (rdc_grp);
9413859Sml29623 }
9423859Sml29623 
9433859Sml29623 /* ARGSUSED */
9443859Sml29623 static uint8_t
9453859Sml29623 nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, intptr_t cookie)
9463859Sml29623 {
9473859Sml29623 	return ((uint8_t)cookie);
9483859Sml29623 }
9493859Sml29623 
9503859Sml29623 /* ARGSUSED */
9513859Sml29623 static void
9523859Sml29623 nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9533859Sml29623 	tcam_entry_t *tcam_ptr)
9543859Sml29623 {
9553859Sml29623 	udpip4_spec_t *fspec_key;
9563859Sml29623 	udpip4_spec_t *fspec_mask;
9573859Sml29623 
9583859Sml29623 	fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec;
9593859Sml29623 	fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec;
9603859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
9613859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
9623859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
9633859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
9643859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
9653859Sml29623 		fspec_key->pdst, fspec_key->psrc);
9663859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
9673859Sml29623 		fspec_mask->pdst, fspec_mask->psrc);
9683859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
9693859Sml29623 		tcam_ptr->ip4_class_mask,
9703859Sml29623 		TCAM_CLASS_UDP_IPV4);
9713859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
9723859Sml29623 		tcam_ptr->ip4_proto_mask,
9733859Sml29623 		IPPROTO_UDP);
9743859Sml29623 }
9753859Sml29623 
9763859Sml29623 static void
9773859Sml29623 nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
9783859Sml29623 	tcam_entry_t *tcam_ptr)
9793859Sml29623 {
9803859Sml29623 	udpip6_spec_t *fspec_key;
9813859Sml29623 	udpip6_spec_t *fspec_mask;
9823859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
9833859Sml29623 
9843859Sml29623 	fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec;
9853859Sml29623 	fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec;
9863859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
9873859Sml29623 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
9883859Sml29623 			NXGE_CLASS_TCAM_USE_SRC_ADDR) {
9893859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
9903859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
9913859Sml29623 	} else {
9923859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
9933859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
9943859Sml29623 	}
9953859Sml29623 
9963859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
9973859Sml29623 		tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6);
9983859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
9993859Sml29623 		tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP);
10003859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
10013859Sml29623 		fspec_key->pdst, fspec_key->psrc);
10023859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
10033859Sml29623 		fspec_mask->pdst, fspec_mask->psrc);
10043859Sml29623 }
10053859Sml29623 
10063859Sml29623 /* ARGSUSED */
10073859Sml29623 static void
10083859Sml29623 nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec,
10093859Sml29623 	tcam_entry_t *tcam_ptr)
10103859Sml29623 {
10113859Sml29623 	tcpip4_spec_t *fspec_key;
10123859Sml29623 	tcpip4_spec_t *fspec_mask;
10133859Sml29623 
10143859Sml29623 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
10153859Sml29623 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
10163859Sml29623 
10173859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
10183859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
10193859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
10203859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
10213859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
10223859Sml29623 		fspec_key->pdst, fspec_key->psrc);
10233859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
10243859Sml29623 		fspec_mask->pdst, fspec_mask->psrc);
10253859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
10263859Sml29623 		tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4);
10273859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
10283859Sml29623 		tcam_ptr->ip4_proto_mask, IPPROTO_TCP);
10293859Sml29623 }
10303859Sml29623 
10313859Sml29623 /* ARGSUSED */
10323859Sml29623 static void
10333859Sml29623 nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec,
10343859Sml29623 	tcam_entry_t *tcam_ptr)
10353859Sml29623 {
10363859Sml29623 	tcpip4_spec_t *fspec_key;
10373859Sml29623 	tcpip4_spec_t *fspec_mask;
10383859Sml29623 
10393859Sml29623 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
10403859Sml29623 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
10413859Sml29623 
10423859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
10433859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
10443859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
10453859Sml29623 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
10463859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
10473859Sml29623 		tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4);
10483859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
10493859Sml29623 		tcam_ptr->ip4_proto_mask, IPPROTO_SCTP);
10503859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
10513859Sml29623 		fspec_key->pdst, fspec_key->psrc);
10523859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
10533859Sml29623 		fspec_mask->pdst, fspec_mask->psrc);
10543859Sml29623 }
10553859Sml29623 
10563859Sml29623 static void
10573859Sml29623 nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
10583859Sml29623 	tcam_entry_t *tcam_ptr)
10593859Sml29623 {
10603859Sml29623 	tcpip6_spec_t *fspec_key;
10613859Sml29623 	tcpip6_spec_t *fspec_mask;
10623859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
10633859Sml29623 
10643859Sml29623 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10653859Sml29623 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10663859Sml29623 
10673859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10683859Sml29623 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
10693859Sml29623 			NXGE_CLASS_TCAM_USE_SRC_ADDR) {
10703859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
10713859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
10723859Sml29623 	} else {
10733859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
10743859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
10753859Sml29623 	}
10763859Sml29623 
10773859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
10783859Sml29623 		tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6);
10793859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
10803859Sml29623 		tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP);
10813859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
10823859Sml29623 		fspec_key->pdst, fspec_key->psrc);
10833859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
10843859Sml29623 		fspec_mask->pdst, fspec_mask->psrc);
10853859Sml29623 }
10863859Sml29623 
10873859Sml29623 static void
10883859Sml29623 nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
10893859Sml29623 	tcam_entry_t *tcam_ptr)
10903859Sml29623 {
10913859Sml29623 	tcpip6_spec_t *fspec_key;
10923859Sml29623 	tcpip6_spec_t *fspec_mask;
10933859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
10943859Sml29623 
10953859Sml29623 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10963859Sml29623 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10973859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10983859Sml29623 
10993859Sml29623 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
11003859Sml29623 			NXGE_CLASS_TCAM_USE_SRC_ADDR) {
11013859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
11023859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
11033859Sml29623 	} else {
11043859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
11053859Sml29623 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
11063859Sml29623 	}
11073859Sml29623 
11083859Sml29623 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
11093859Sml29623 		tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6);
11103859Sml29623 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
11113859Sml29623 		tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP);
11123859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
11133859Sml29623 		fspec_key->pdst, fspec_key->psrc);
11143859Sml29623 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
11153859Sml29623 		fspec_mask->pdst, fspec_mask->psrc);
11163859Sml29623 }
11173859Sml29623 
11183859Sml29623 nxge_status_t
11193859Sml29623 nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res,
11203859Sml29623 	uint32_t *H1, uint16_t *H2)
11213859Sml29623 {
11223859Sml29623 	flow_spec_t *flow_spec;
11233859Sml29623 	uint32_t class_cfg;
11243859Sml29623 	flow_template_t ft;
11253859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
11263859Sml29623 
11273859Sml29623 	int ft_size = sizeof (flow_template_t);
11283859Sml29623 
11293859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash"));
11303859Sml29623 
11313859Sml29623 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
11323859Sml29623 	bzero((char *)&ft, ft_size);
11333859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
11343859Sml29623 
11353859Sml29623 	switch (flow_spec->flow_type) {
11363859Sml29623 	case FSPEC_TCPIP4:
11373859Sml29623 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4];
11383859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
11393859Sml29623 			ft.ip_proto = IPPROTO_TCP;
11403859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
11413859Sml29623 			ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src;
11423859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
11433859Sml29623 			ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst;
11443859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
11453859Sml29623 			ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc;
11463859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
11473859Sml29623 			ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst;
11483859Sml29623 		break;
11493859Sml29623 
11503859Sml29623 	case FSPEC_UDPIP4:
11513859Sml29623 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4];
11523859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
11533859Sml29623 			ft.ip_proto = IPPROTO_UDP;
11543859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
11553859Sml29623 			ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src;
11563859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
11573859Sml29623 			ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst;
11583859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
11593859Sml29623 			ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc;
11603859Sml29623 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
11613859Sml29623 			ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst;
11623859Sml29623 		break;
11633859Sml29623 
11643859Sml29623 	default:
11653859Sml29623 		return (NXGE_ERROR);
11663859Sml29623 	}
11673859Sml29623 
11683859Sml29623 	*H1 = nxge_compute_h1(p_class_cfgp->init_h1,
11693859Sml29623 		(uint32_t *)&ft, ft_size) & 0xfffff;
11703859Sml29623 	*H2 = nxge_compute_h2(p_class_cfgp->init_h2,
11713859Sml29623 		(uint8_t *)&ft, ft_size);
11723859Sml29623 
11733859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash"));
11743859Sml29623 	return (NXGE_OK);
11753859Sml29623 }
11763859Sml29623 
11773859Sml29623 nxge_status_t
11783859Sml29623 nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
11793859Sml29623 {
11803859Sml29623 	uint32_t H1;
11813859Sml29623 	uint16_t H2;
11823859Sml29623 	nxge_status_t status = NXGE_OK;
11833859Sml29623 
11843859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry"));
11853859Sml29623 	status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2);
11863859Sml29623 	if (status != NXGE_OK) {
11873859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
11883859Sml29623 			" nxge_add_fcram_entry failed "));
11893859Sml29623 		return (status);
11903859Sml29623 	}
11913859Sml29623 
11923859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry"));
11933859Sml29623 	return (NXGE_OK);
11943859Sml29623 }
11953859Sml29623 
11963859Sml29623 /*
11973859Sml29623  * Already decided this flow goes into the tcam
11983859Sml29623  */
11993859Sml29623 
12003859Sml29623 nxge_status_t
12013859Sml29623 nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
12023859Sml29623 {
12033859Sml29623 	npi_handle_t handle;
12043859Sml29623 	intptr_t channel_cookie;
12053859Sml29623 	intptr_t flow_cookie;
12063859Sml29623 	flow_spec_t *flow_spec;
12073859Sml29623 	npi_status_t rs = NPI_SUCCESS;
12083859Sml29623 	tcam_entry_t tcam_ptr;
12093859Sml29623 	tcam_location_t location = 0;
12103859Sml29623 	uint8_t offset, rdc_grp;
12113859Sml29623 	p_nxge_hw_list_t hw_p;
12123859Sml29623 
12133859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry"));
12143859Sml29623 	handle = nxgep->npi_reg_handle;
12153859Sml29623 
12163859Sml29623 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
12173859Sml29623 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
12183859Sml29623 	flow_cookie = flow_res->flow_cookie;
12193859Sml29623 	channel_cookie = flow_res->channel_cookie;
12203859Sml29623 
12213859Sml29623 	switch (flow_spec->flow_type) {
12223859Sml29623 	case FSPEC_TCPIP4:
12233859Sml29623 		nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr);
12243859Sml29623 		location = nxge_get_tcam_location(nxgep,
12253859Sml29623 			TCAM_CLASS_TCP_IPV4);
12263859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4,
12273859Sml29623 			flow_cookie);
12283859Sml29623 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4,
12293859Sml29623 			channel_cookie);
12303859Sml29623 		break;
12313859Sml29623 
12323859Sml29623 	case FSPEC_UDPIP4:
12333859Sml29623 		nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr);
12343859Sml29623 		location = nxge_get_tcam_location(nxgep,
12353859Sml29623 			TCAM_CLASS_UDP_IPV4);
12363859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
12373859Sml29623 			TCAM_CLASS_UDP_IPV4,
12383859Sml29623 			flow_cookie);
12393859Sml29623 		offset = nxge_get_rdc_offset(nxgep,
12403859Sml29623 			TCAM_CLASS_UDP_IPV4,
12413859Sml29623 			channel_cookie);
12423859Sml29623 		break;
12433859Sml29623 
12443859Sml29623 	case FSPEC_TCPIP6:
12453859Sml29623 		nxge_fill_tcam_entry_tcp_ipv6(nxgep,
12463859Sml29623 			flow_spec, &tcam_ptr);
12473859Sml29623 		location = nxge_get_tcam_location(nxgep,
12483859Sml29623 			TCAM_CLASS_TCP_IPV6);
12493859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6,
12503859Sml29623 			flow_cookie);
12513859Sml29623 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6,
12523859Sml29623 			channel_cookie);
12533859Sml29623 		break;
12543859Sml29623 
12553859Sml29623 	case FSPEC_UDPIP6:
12563859Sml29623 		nxge_fill_tcam_entry_udp_ipv6(nxgep,
12573859Sml29623 			flow_spec, &tcam_ptr);
12583859Sml29623 		location = nxge_get_tcam_location(nxgep,
12593859Sml29623 			TCAM_CLASS_UDP_IPV6);
12603859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
12613859Sml29623 			TCAM_CLASS_UDP_IPV6,
12623859Sml29623 			channel_cookie);
12633859Sml29623 		offset = nxge_get_rdc_offset(nxgep,
12643859Sml29623 			TCAM_CLASS_UDP_IPV6,
12653859Sml29623 			flow_cookie);
12663859Sml29623 		break;
12673859Sml29623 
12683859Sml29623 	case FSPEC_SCTPIP4:
12693859Sml29623 		nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr);
12703859Sml29623 		location = nxge_get_tcam_location(nxgep,
12713859Sml29623 			TCAM_CLASS_SCTP_IPV4);
12723859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
12733859Sml29623 			TCAM_CLASS_SCTP_IPV4,
12743859Sml29623 			channel_cookie);
12753859Sml29623 		offset = nxge_get_rdc_offset(nxgep,
12763859Sml29623 			TCAM_CLASS_SCTP_IPV4,
12773859Sml29623 			flow_cookie);
12783859Sml29623 		break;
12793859Sml29623 
12803859Sml29623 	case FSPEC_SCTPIP6:
12813859Sml29623 		nxge_fill_tcam_entry_sctp_ipv6(nxgep,
12823859Sml29623 			flow_spec, &tcam_ptr);
12833859Sml29623 		location = nxge_get_tcam_location(nxgep,
12843859Sml29623 			TCAM_CLASS_SCTP_IPV4);
12853859Sml29623 		rdc_grp = nxge_get_rdc_group(nxgep,
12863859Sml29623 			TCAM_CLASS_SCTP_IPV6,
12873859Sml29623 			channel_cookie);
12883859Sml29623 		offset = nxge_get_rdc_offset(nxgep,
12893859Sml29623 			TCAM_CLASS_SCTP_IPV6,
12903859Sml29623 			flow_cookie);
12913859Sml29623 		break;
12923859Sml29623 
12933859Sml29623 	default:
12943859Sml29623 		return (NXGE_OK);
12953859Sml29623 	}
12963859Sml29623 
12973859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
12983859Sml29623 		" nxge_add_tcam_entry write"
12993859Sml29623 		" for location %d offset %d", location, offset));
13003859Sml29623 
13013859Sml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
13023859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13033859Sml29623 			" nxge_add_tcam_entry: common hardware not set",
13043859Sml29623 			nxgep->niu_type));
13053859Sml29623 		return (NXGE_ERROR);
13063859Sml29623 	}
13073859Sml29623 
13083859Sml29623 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
13093859Sml29623 	rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr);
13103859Sml29623 
13113859Sml29623 	if (rs & NPI_FFLP_ERROR) {
13123859Sml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
13133859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13143859Sml29623 			" nxge_add_tcam_entry write"
13153859Sml29623 			" failed for location %d", location));
13163859Sml29623 		return (NXGE_ERROR | rs);
13173859Sml29623 	}
13183859Sml29623 
13193859Sml29623 	tcam_ptr.match_action.value = 0;
13203859Sml29623 	tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp;
13213859Sml29623 	tcam_ptr.match_action.bits.ldw.offset = offset;
13223859Sml29623 	tcam_ptr.match_action.bits.ldw.tres =
13233859Sml29623 		TRES_TERM_OVRD_L2RDC;
13243859Sml29623 	if (channel_cookie == -1)
13253859Sml29623 		tcam_ptr.match_action.bits.ldw.disc = 1;
13263859Sml29623 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
13273859Sml29623 		location, tcam_ptr.match_action.value);
13283859Sml29623 	if (rs & NPI_FFLP_ERROR) {
13293859Sml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
13303859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13313859Sml29623 			" nxge_add_tcam_entry write"
13323859Sml29623 			" failed for ASC RAM location %d", location));
13333859Sml29623 		return (NXGE_ERROR | rs);
13343859Sml29623 	}
13353859Sml29623 	bcopy((void *) &tcam_ptr,
13363859Sml29623 		(void *) &nxgep->classifier.tcam_entries[location].tce,
13373859Sml29623 		sizeof (tcam_entry_t));
13383859Sml29623 
13393859Sml29623 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
13403859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry"));
13413859Sml29623 	return (NXGE_OK);
13423859Sml29623 }
13433859Sml29623 
13443859Sml29623 static nxge_status_t
13453859Sml29623 nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)
13463859Sml29623 {
13473859Sml29623 	tcam_entry_t tcam_ptr;
13483859Sml29623 	tcam_location_t location;
13493859Sml29623 	uint8_t class;
13503859Sml29623 	uint32_t class_config;
13513859Sml29623 	npi_handle_t handle;
13523859Sml29623 	npi_status_t rs = NPI_SUCCESS;
13533859Sml29623 	p_nxge_hw_list_t hw_p;
13543859Sml29623 	nxge_status_t status = NXGE_OK;
13553859Sml29623 
13563859Sml29623 	handle = nxgep->npi_reg_handle;
13573859Sml29623 	class = 0;
13583859Sml29623 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
13593859Sml29623 	tcam_ptr.ip4_noport_key = 1;
13603859Sml29623 	tcam_ptr.ip4_noport_mask = 1;
13613859Sml29623 	location = nxgep->function_num;
13623859Sml29623 	nxgep->classifier.fragment_bug_location = location;
13633859Sml29623 
13643859Sml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
13653859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13663859Sml29623 			" nxge_tcam_handle_ip_fragment:"
13673859Sml29623 			" common hardware not set",
13683859Sml29623 			nxgep->niu_type));
13693859Sml29623 		return (NXGE_ERROR);
13703859Sml29623 	}
13713859Sml29623 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
13723859Sml29623 	rs = npi_fflp_tcam_entry_write(handle,
13733859Sml29623 		location, &tcam_ptr);
13743859Sml29623 
13753859Sml29623 	if (rs & NPI_FFLP_ERROR) {
13763859Sml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
13773859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13783859Sml29623 			" nxge_tcam_handle_ip_fragment "
13793859Sml29623 			" tcam_entry write"
13803859Sml29623 			" failed for location %d", location));
13813859Sml29623 		return (NXGE_ERROR);
13823859Sml29623 	}
13833859Sml29623 	tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp;
13843859Sml29623 	tcam_ptr.match_action.bits.ldw.offset = 0;	/* use the default */
13853859Sml29623 	tcam_ptr.match_action.bits.ldw.tres =
13863859Sml29623 		TRES_TERM_USE_OFFSET;
13873859Sml29623 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
13883859Sml29623 		location, tcam_ptr.match_action.value);
13893859Sml29623 
13903859Sml29623 	if (rs & NPI_FFLP_ERROR) {
13913859Sml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
13923859Sml29623 		NXGE_DEBUG_MSG((nxgep,
13933859Sml29623 			FFLP_CTL,
13943859Sml29623 			" nxge_tcam_handle_ip_fragment "
13953859Sml29623 			" tcam_entry write"
13963859Sml29623 			" failed for ASC RAM location %d", location));
13973859Sml29623 		return (NXGE_ERROR);
13983859Sml29623 	}
13993859Sml29623 	bcopy((void *) &tcam_ptr,
14003859Sml29623 		(void *) &nxgep->classifier.tcam_entries[location].tce,
14013859Sml29623 		sizeof (tcam_entry_t));
14023859Sml29623 	for (class = TCAM_CLASS_TCP_IPV4;
14033859Sml29623 		class <= TCAM_CLASS_SCTP_IPV6; class++) {
14043859Sml29623 		class_config = nxgep->class_config.class_cfg[class];
14053859Sml29623 		class_config |= NXGE_CLASS_TCAM_LOOKUP;
14063859Sml29623 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
14073859Sml29623 
14083859Sml29623 		if (status & NPI_FFLP_ERROR) {
14093859Sml29623 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
14103859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14113859Sml29623 				"nxge_tcam_handle_ip_fragment "
14123859Sml29623 				"nxge_fflp_ip_class_config failed "
14133859Sml29623 				" class %d config %x ", class, class_config));
14143859Sml29623 			return (NXGE_ERROR);
14153859Sml29623 		}
14163859Sml29623 	}
14173859Sml29623 
14183859Sml29623 	rs = npi_fflp_cfg_tcam_enable(handle);
14193859Sml29623 	if (rs & NPI_FFLP_ERROR) {
14203859Sml29623 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
14213859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14223859Sml29623 			"nxge_tcam_handle_ip_fragment "
14233859Sml29623 			" nxge_fflp_config_tcam_enable failed"));
14243859Sml29623 		return (NXGE_ERROR);
14253859Sml29623 	}
14263859Sml29623 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
14273859Sml29623 	return (NXGE_OK);
14283859Sml29623 }
14293859Sml29623 
14303859Sml29623 /* ARGSUSED */
14313859Sml29623 static int
14323859Sml29623 nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res)
14333859Sml29623 {
14343859Sml29623 	return (0);
14353859Sml29623 }
14363859Sml29623 
14373859Sml29623 nxge_status_t
14383859Sml29623 nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res)
14393859Sml29623 {
14403859Sml29623 
14413859Sml29623 	int insert_hash = 0;
14423859Sml29623 	nxge_status_t status = NXGE_OK;
14433859Sml29623 
1444*4977Sraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
14453859Sml29623 		/* determine whether to do TCAM or Hash flow */
14463859Sml29623 		insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res);
14473859Sml29623 	}
14483859Sml29623 	if (insert_hash) {
14493859Sml29623 		status = nxge_add_fcram_entry(nxgep, flow_res);
14503859Sml29623 	} else {
14513859Sml29623 		status = nxge_add_tcam_entry(nxgep, flow_res);
14523859Sml29623 	}
14533859Sml29623 	return (status);
14543859Sml29623 }
14553859Sml29623 
14563859Sml29623 void
14573859Sml29623 nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp)
14583859Sml29623 {
14593859Sml29623 	flow_resource_t *fs;
14603859Sml29623 
14613859Sml29623 	fs = (flow_resource_t *)mp->b_rptr;
14623859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14633859Sml29623 		"nxge_put_tcam addr fs $%p  type %x offset %x",
14643859Sml29623 		fs, fs->flow_spec.flow_type, fs->channel_cookie));
14653859Sml29623 	(void) nxge_add_tcam_entry(nxgep, fs);
14663859Sml29623 }
14673859Sml29623 
14683859Sml29623 nxge_status_t
14693859Sml29623 nxge_fflp_config_tcam_enable(p_nxge_t nxgep)
14703859Sml29623 {
14713859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
14723859Sml29623 	npi_status_t rs = NPI_SUCCESS;
14733859Sml29623 
14743859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable"));
14753859Sml29623 	rs = npi_fflp_cfg_tcam_enable(handle);
14763859Sml29623 	if (rs & NPI_FFLP_ERROR) {
14773859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14783859Sml29623 			" nxge_fflp_config_tcam_enable failed"));
14793859Sml29623 		return (NXGE_ERROR | rs);
14803859Sml29623 	}
14813859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable"));
14823859Sml29623 	return (NXGE_OK);
14833859Sml29623 }
14843859Sml29623 
14853859Sml29623 nxge_status_t
14863859Sml29623 nxge_fflp_config_tcam_disable(p_nxge_t nxgep)
14873859Sml29623 {
14883859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
14893859Sml29623 	npi_status_t rs = NPI_SUCCESS;
14903859Sml29623 
14913859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
14923859Sml29623 		" ==> nxge_fflp_config_tcam_disable"));
14933859Sml29623 	rs = npi_fflp_cfg_tcam_disable(handle);
14943859Sml29623 	if (rs & NPI_FFLP_ERROR) {
14953859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14963859Sml29623 				" nxge_fflp_config_tcam_disable failed"));
14973859Sml29623 		return (NXGE_ERROR | rs);
14983859Sml29623 	}
14993859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
15003859Sml29623 		" <== nxge_fflp_config_tcam_disable"));
15013859Sml29623 	return (NXGE_OK);
15023859Sml29623 }
15033859Sml29623 
15043859Sml29623 nxge_status_t
15053859Sml29623 nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)
15063859Sml29623 {
15073859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
15083859Sml29623 	npi_status_t rs = NPI_SUCCESS;
15093859Sml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
15103859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
15113859Sml29623 	uint8_t partition;
15123859Sml29623 
15133859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
15143859Sml29623 		" ==> nxge_fflp_config_hash_lookup_enable"));
15153859Sml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
15163859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
15173859Sml29623 
15183859Sml29623 	for (partition = p_cfgp->start_rdc_grpid;
15193859Sml29623 		partition < p_cfgp->max_rdc_grpids; partition++) {
15203859Sml29623 		rs = npi_fflp_cfg_fcram_partition_enable(handle, partition);
15213859Sml29623 		if (rs != NPI_SUCCESS) {
15223859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15233859Sml29623 				" nxge_fflp_config_hash_lookup_enable"
15243859Sml29623 				"failed FCRAM partition"
15253859Sml29623 				" enable for partition %d ", partition));
15263859Sml29623 			return (NXGE_ERROR | rs);
15273859Sml29623 		}
15283859Sml29623 	}
15293859Sml29623 
15303859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
15313859Sml29623 		" <== nxge_fflp_config_hash_lookup_enable"));
15323859Sml29623 	return (NXGE_OK);
15333859Sml29623 }
15343859Sml29623 
15353859Sml29623 nxge_status_t
15363859Sml29623 nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)
15373859Sml29623 {
15383859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
15393859Sml29623 	npi_status_t rs = NPI_SUCCESS;
15403859Sml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
15413859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
15423859Sml29623 	uint8_t partition;
15433859Sml29623 
15443859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
15453859Sml29623 		" ==> nxge_fflp_config_hash_lookup_disable"));
15463859Sml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
15473859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
15483859Sml29623 
15493859Sml29623 	for (partition = p_cfgp->start_rdc_grpid;
15503859Sml29623 		partition < p_cfgp->max_rdc_grpids; partition++) {
15513859Sml29623 		rs = npi_fflp_cfg_fcram_partition_disable(handle,
15523859Sml29623 			partition);
15533859Sml29623 		if (rs != NPI_SUCCESS) {
15543859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15553859Sml29623 				" nxge_fflp_config_hash_lookup_disable"
15563859Sml29623 				" failed FCRAM partition"
15573859Sml29623 				" disable for partition %d ", partition));
15583859Sml29623 			return (NXGE_ERROR | rs);
15593859Sml29623 		}
15603859Sml29623 	}
15613859Sml29623 
15623859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
15633859Sml29623 		" <== nxge_fflp_config_hash_lookup_disable"));
15643859Sml29623 	return (NXGE_OK);
15653859Sml29623 }
15663859Sml29623 
15673859Sml29623 nxge_status_t
15683859Sml29623 nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)
15693859Sml29623 {
15703859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
15713859Sml29623 	npi_status_t rs = NPI_SUCCESS;
15723859Sml29623 
15733859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
15743859Sml29623 		" ==> nxge_fflp_config_llc_snap_enable"));
15753859Sml29623 	rs = npi_fflp_cfg_llcsnap_enable(handle);
15763859Sml29623 	if (rs & NPI_FFLP_ERROR) {
15773859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15783859Sml29623 			" nxge_fflp_config_llc_snap_enable failed"));
15793859Sml29623 		return (NXGE_ERROR | rs);
15803859Sml29623 	}
15813859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
15823859Sml29623 		" <== nxge_fflp_config_llc_snap_enable"));
15833859Sml29623 	return (NXGE_OK);
15843859Sml29623 }
15853859Sml29623 
15863859Sml29623 nxge_status_t
15873859Sml29623 nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)
15883859Sml29623 {
15893859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
15903859Sml29623 	npi_status_t rs = NPI_SUCCESS;
15913859Sml29623 
15923859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
15933859Sml29623 		" ==> nxge_fflp_config_llc_snap_disable"));
15943859Sml29623 	rs = npi_fflp_cfg_llcsnap_disable(handle);
15953859Sml29623 	if (rs & NPI_FFLP_ERROR) {
15963859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15973859Sml29623 			" nxge_fflp_config_llc_snap_disable failed"));
15983859Sml29623 		return (NXGE_ERROR | rs);
15993859Sml29623 	}
16003859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
16013859Sml29623 		" <== nxge_fflp_config_llc_snap_disable"));
16023859Sml29623 	return (NXGE_OK);
16033859Sml29623 }
16043859Sml29623 
16053859Sml29623 nxge_status_t
16063859Sml29623 nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class,
16073859Sml29623 	uint32_t config)
16083859Sml29623 {
16093859Sml29623 	npi_status_t rs = NPI_SUCCESS;
16103859Sml29623 	npi_handle_t handle = nxgep->npi_reg_handle;
16113859Sml29623 	uint8_t tos, tos_mask, proto, ver = 0;
16123859Sml29623 	uint8_t class_enable = 0;
16133859Sml29623 
16143859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config"));
16153859Sml29623 
16163859Sml29623 	tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >>
16173859Sml29623 		NXGE_CLASS_CFG_IP_TOS_SHIFT;
16183859Sml29623 	tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >>
16193859Sml29623 		NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT;
16203859Sml29623 	proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >>
16213859Sml29623 		NXGE_CLASS_CFG_IP_PROTO_SHIFT;
16223859Sml29623 	if (config & NXGE_CLASS_CFG_IP_IPV6_MASK)
16233859Sml29623 		ver = 1;
16243859Sml29623 	if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK)
16253859Sml29623 		class_enable = 1;
16263859Sml29623 	rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask,
16273859Sml29623 		proto, ver);
16283859Sml29623 	if (rs & NPI_FFLP_ERROR) {
16293859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16303859Sml29623 			" nxge_fflp_ip_usr_class_config"
16313859Sml29623 			" for class %d failed ", class));
16323859Sml29623 		return (NXGE_ERROR | rs);
16333859Sml29623 	}
16343859Sml29623 	if (class_enable)
16353859Sml29623 		rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class);
16363859Sml29623 	else
16373859Sml29623 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
16383859Sml29623 
16393859Sml29623 	if (rs & NPI_FFLP_ERROR) {
16403859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16413859Sml29623 			" nxge_fflp_ip_usr_class_config"
16423859Sml29623 			" TCAM enable/disable for class %d failed ", class));
16433859Sml29623 		return (NXGE_ERROR | rs);
16443859Sml29623 	}
16453859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config"));
16463859Sml29623 	return (NXGE_OK);
16473859Sml29623 }
16483859Sml29623 
16493859Sml29623 nxge_status_t
16503859Sml29623 nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config)
16513859Sml29623 {
16523859Sml29623 	uint32_t class_config;
16533859Sml29623 	nxge_status_t t_status = NXGE_OK;
16543859Sml29623 	nxge_status_t f_status = NXGE_OK;
16553859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
16563859Sml29623 
16573859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
16583859Sml29623 
16593859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
16603859Sml29623 	class_config = p_class_cfgp->class_cfg[class];
16613859Sml29623 
16623859Sml29623 	if (class_config != config) {
16633859Sml29623 		p_class_cfgp->class_cfg[class] = config;
16643859Sml29623 		class_config = config;
16653859Sml29623 	}
16663859Sml29623 
16673859Sml29623 	t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config);
16683859Sml29623 	f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config);
16693859Sml29623 
16703859Sml29623 	if (t_status & NPI_FFLP_ERROR) {
16713859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
16723859Sml29623 			" nxge_fflp_ip_class_config %x"
16733859Sml29623 			" for class %d tcam failed", config, class));
16743859Sml29623 		return (t_status);
16753859Sml29623 	}
16763859Sml29623 	if (f_status & NPI_FFLP_ERROR) {
16773859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16783859Sml29623 			" nxge_fflp_ip_class_config %x"
16793859Sml29623 			" for class %d flow key failed", config, class));
16803859Sml29623 		return (f_status);
16813859Sml29623 	}
16823859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
16833859Sml29623 	return (NXGE_OK);
16843859Sml29623 }
16853859Sml29623 
16863859Sml29623 nxge_status_t
16873859Sml29623 nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class,
16883859Sml29623 	uint32_t *config)
16893859Sml29623 {
16903859Sml29623 	uint32_t t_class_config, f_class_config;
16913859Sml29623 	int t_status = NXGE_OK;
16923859Sml29623 	int f_status = NXGE_OK;
16933859Sml29623 
16943859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
16953859Sml29623 
16963859Sml29623 	t_class_config = f_class_config = 0;
16973859Sml29623 	t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config);
16983859Sml29623 	f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config);
16993859Sml29623 
17003859Sml29623 	if (t_status & NPI_FFLP_ERROR) {
17013859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17023859Sml29623 			" nxge_fflp_ip_class_config_get  "
17033859Sml29623 			" for class %d tcam failed", class));
17043859Sml29623 		return (t_status);
17053859Sml29623 	}
17063859Sml29623 
17073859Sml29623 	if (f_status & NPI_FFLP_ERROR) {
17083859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17093859Sml29623 			" nxge_fflp_ip_class_config_get  "
17103859Sml29623 			" for class %d flow key failed", class));
17113859Sml29623 		return (f_status);
17123859Sml29623 	}
17133859Sml29623 
17143859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17153859Sml29623 		" nxge_fflp_ip_class_config tcam %x flow %x",
17163859Sml29623 		t_class_config, f_class_config));
17173859Sml29623 
17183859Sml29623 	*config = t_class_config | f_class_config;
17193859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get"));
17203859Sml29623 	return (NXGE_OK);
17213859Sml29623 }
17223859Sml29623 
17233859Sml29623 nxge_status_t
17243859Sml29623 nxge_fflp_ip_class_config_all(p_nxge_t nxgep)
17253859Sml29623 {
17263859Sml29623 	uint32_t class_config;
17273859Sml29623 	tcam_class_t class;
17283859Sml29623 
17293859Sml29623 #ifdef	NXGE_DEBUG
17303859Sml29623 	int status = NXGE_OK;
17313859Sml29623 #endif
17323859Sml29623 
17333859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config"));
17343859Sml29623 	for (class = TCAM_CLASS_TCP_IPV4;
17353859Sml29623 		class <= TCAM_CLASS_SCTP_IPV6; class++) {
17363859Sml29623 		class_config = nxgep->class_config.class_cfg[class];
17373859Sml29623 #ifndef	NXGE_DEBUG
17383859Sml29623 		(void) nxge_fflp_ip_class_config(nxgep, class, class_config);
17393859Sml29623 #else
17403859Sml29623 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
17413859Sml29623 		if (status & NPI_FFLP_ERROR) {
17423859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17433859Sml29623 				"nxge_fflp_ip_class_config failed "
17443859Sml29623 				" class %d config %x ",
17453859Sml29623 				class, class_config));
17463859Sml29623 		}
17473859Sml29623 #endif
17483859Sml29623 	}
17493859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
17503859Sml29623 	return (NXGE_OK);
17513859Sml29623 }
17523859Sml29623 
17533859Sml29623 nxge_status_t
17543859Sml29623 nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id)
17553859Sml29623 {
17563859Sml29623 	uint8_t port, rdc_grp;
17573859Sml29623 	npi_handle_t handle;
17583859Sml29623 	npi_status_t rs = NPI_SUCCESS;
17593859Sml29623 	uint8_t priority = 1;
17603859Sml29623 	p_nxge_mv_cfg_t vlan_table;
17613859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
17623859Sml29623 	p_nxge_hw_list_t hw_p;
17633859Sml29623 
17643859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table"));
17653859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
17663859Sml29623 	handle = nxgep->npi_reg_handle;
17673859Sml29623 	vlan_table = p_class_cfgp->vlan_tbl;
17683859Sml29623 	port = nxgep->function_num;
17693859Sml29623 
17703859Sml29623 	if (vlan_table[vlan_id].flag == 0) {
17713859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17723859Sml29623 			" nxge_fflp_config_vlan_table"
17733859Sml29623 			" vlan id is not configured %d", vlan_id));
17743859Sml29623 		return (NXGE_ERROR);
17753859Sml29623 	}
17763859Sml29623 
17773859Sml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
17783859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17793859Sml29623 			" nxge_fflp_config_vlan_table:"
17803859Sml29623 			" common hardware not set", nxgep->niu_type));
17813859Sml29623 		return (NXGE_ERROR);
17823859Sml29623 	}
17833859Sml29623 	MUTEX_ENTER(&hw_p->nxge_vlan_lock);
17843859Sml29623 	rdc_grp = vlan_table[vlan_id].rdctbl;
17853859Sml29623 	rs = npi_fflp_cfg_enet_vlan_table_assoc(handle,
17863859Sml29623 		port, vlan_id,
17873859Sml29623 		rdc_grp, priority);
17883859Sml29623 
17893859Sml29623 	MUTEX_EXIT(&hw_p->nxge_vlan_lock);
17903859Sml29623 	if (rs & NPI_FFLP_ERROR) {
17913859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17923859Sml29623 			"nxge_fflp_config_vlan_table failed "
17933859Sml29623 			" Port %d vlan_id %d rdc_grp %d",
17943859Sml29623 			port, vlan_id, rdc_grp));
17953859Sml29623 		return (NXGE_ERROR | rs);
17963859Sml29623 	}
17973859Sml29623 
17983859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table"));
17993859Sml29623 	return (NXGE_OK);
18003859Sml29623 }
18013859Sml29623 
18023859Sml29623 nxge_status_t
18033859Sml29623 nxge_fflp_update_hw(p_nxge_t nxgep)
18043859Sml29623 {
18053859Sml29623 	nxge_status_t status = NXGE_OK;
18063859Sml29623 	p_nxge_param_t pa;
18073859Sml29623 	uint64_t cfgd_vlans;
18083859Sml29623 	uint64_t *val_ptr;
18093859Sml29623 	int i;
18103859Sml29623 	int num_macs;
18113859Sml29623 	uint8_t alt_mac;
18123859Sml29623 	nxge_param_map_t *p_map;
18133859Sml29623 	p_nxge_mv_cfg_t vlan_table;
18143859Sml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
18153859Sml29623 	p_nxge_dma_pt_cfg_t p_all_cfgp;
18163859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
18173859Sml29623 
18183859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw"));
18193859Sml29623 
18203859Sml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
18213859Sml29623 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
18223859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
18233859Sml29623 
18243859Sml29623 	status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1);
18253859Sml29623 	if (status != NXGE_OK) {
18263859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
18273859Sml29623 			"nxge_fflp_set_hash1 Failed"));
18283859Sml29623 		return (NXGE_ERROR);
18293859Sml29623 	}
18303859Sml29623 
18313859Sml29623 	status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2);
18323859Sml29623 	if (status != NXGE_OK) {
18333859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
18343859Sml29623 			"nxge_fflp_set_hash2 Failed"));
18353859Sml29623 		return (NXGE_ERROR);
18363859Sml29623 	}
18373859Sml29623 	vlan_table = p_class_cfgp->vlan_tbl;
18383859Sml29623 
18393859Sml29623 	/* configure vlan tables */
18403859Sml29623 	pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp];
18413859Sml29623 	val_ptr = (uint64_t *)pa->value;
18423859Sml29623 	cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >>
18433859Sml29623 		NXGE_PARAM_ARRAY_CNT_SHIFT);
18443859Sml29623 
18453859Sml29623 	for (i = 0; i < cfgd_vlans; i++) {
18463859Sml29623 		p_map = (nxge_param_map_t *)&val_ptr[i];
18473859Sml29623 		if (vlan_table[p_map->param_id].flag) {
18483859Sml29623 			status = nxge_fflp_config_vlan_table(nxgep,
18493859Sml29623 				p_map->param_id);
18503859Sml29623 			if (status != NXGE_OK) {
18513859Sml29623 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
18523859Sml29623 					"nxge_fflp_config_vlan_table Failed"));
18533859Sml29623 				return (NXGE_ERROR);
18543859Sml29623 			}
18553859Sml29623 		}
18563859Sml29623 	}
18573859Sml29623 
18583859Sml29623 	/* config MAC addresses */
18593859Sml29623 	num_macs = p_cfgp->max_macs;
18603859Sml29623 	pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp];
18613859Sml29623 	val_ptr = (uint64_t *)pa->value;
18623859Sml29623 
18633859Sml29623 	for (alt_mac = 0; alt_mac < num_macs; alt_mac++) {
18643859Sml29623 		if (p_class_cfgp->mac_host_info[alt_mac].flag) {
18653859Sml29623 			status = nxge_logical_mac_assign_rdc_table(nxgep,
18663859Sml29623 				alt_mac);
18673859Sml29623 			if (status != NXGE_OK) {
18683859Sml29623 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
18693859Sml29623 					"nxge_logical_mac_assign_rdc_table"
18703859Sml29623 					" Failed"));
18713859Sml29623 				return (NXGE_ERROR);
18723859Sml29623 			}
18733859Sml29623 		}
18743859Sml29623 	}
18753859Sml29623 
18763859Sml29623 	/* Config Hash values */
18773859Sml29623 	/* config classess */
18783859Sml29623 	status = nxge_fflp_ip_class_config_all(nxgep);
18793859Sml29623 	if (status != NXGE_OK) {
18803859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18813859Sml29623 			"nxge_fflp_ip_class_config_all Failed"));
18823859Sml29623 		return (NXGE_ERROR);
18833859Sml29623 	}
18843859Sml29623 	return (NXGE_OK);
18853859Sml29623 }
18863859Sml29623 
18873859Sml29623 nxge_status_t
18883859Sml29623 nxge_classify_init_hw(p_nxge_t nxgep)
18893859Sml29623 {
18903859Sml29623 	nxge_status_t status = NXGE_OK;
18913859Sml29623 
18923859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw"));
18933859Sml29623 
18943859Sml29623 	if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) {
18953859Sml29623 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
18963859Sml29623 			"nxge_classify_init_hw already init"));
18973859Sml29623 		return (NXGE_OK);
18983859Sml29623 	}
18993859Sml29623 
19003859Sml29623 	/* Now do a real configuration */
19013859Sml29623 	status = nxge_fflp_update_hw(nxgep);
19023859Sml29623 	if (status != NXGE_OK) {
19033859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19043859Sml29623 			"nxge_fflp_update_hw failed"));
19053859Sml29623 		return (NXGE_ERROR);
19063859Sml29623 	}
19073859Sml29623 
19083859Sml29623 	/* Init RDC tables? ? who should do that? rxdma or fflp ? */
19093859Sml29623 	/* attach rdc table to the MAC port. */
19103859Sml29623 	status = nxge_main_mac_assign_rdc_table(nxgep);
19113859Sml29623 	if (status != NXGE_OK) {
19123859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19133859Sml29623 				"nxge_main_mac_assign_rdc_table failed"));
19143859Sml29623 		return (NXGE_ERROR);
19153859Sml29623 	}
19163859Sml29623 
19173859Sml29623 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
19183859Sml29623 	if (status != NXGE_OK) {
19193859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19203859Sml29623 			"nxge_multicast_mac_assign_rdc_table failed"));
19213859Sml29623 		return (NXGE_ERROR);
19223859Sml29623 	}
19233859Sml29623 
19243859Sml29623 	status = nxge_tcam_handle_ip_fragment(nxgep);
19253859Sml29623 	if (status != NXGE_OK) {
19263859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19273859Sml29623 			"nxge_tcam_handle_ip_fragment failed"));
19283859Sml29623 		return (NXGE_ERROR);
19293859Sml29623 	}
19303859Sml29623 
19313859Sml29623 	nxgep->classifier.state |= NXGE_FFLP_HW_INIT;
19323859Sml29623 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw"));
19333859Sml29623 	return (NXGE_OK);
19343859Sml29623 }
19353859Sml29623 
19363859Sml29623 nxge_status_t
19373859Sml29623 nxge_fflp_handle_sys_errors(p_nxge_t nxgep)
19383859Sml29623 {
19393859Sml29623 	npi_handle_t handle;
19403859Sml29623 	p_nxge_fflp_stats_t statsp;
19413859Sml29623 	uint8_t portn, rdc_grp;
19423859Sml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
19433859Sml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
19443859Sml29623 	vlan_par_err_t vlan_err;
19453859Sml29623 	tcam_err_t tcam_err;
19463859Sml29623 	hash_lookup_err_log1_t fcram1_err;
19473859Sml29623 	hash_lookup_err_log2_t fcram2_err;
19483859Sml29623 	hash_tbl_data_log_t fcram_err;
19493859Sml29623 
19503859Sml29623 	handle = nxgep->npi_handle;
19513859Sml29623 	statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats;
19523859Sml29623 	portn = nxgep->mac.portnum;
19533859Sml29623 
19543859Sml29623 	/*
19553859Sml29623 	 * need to read the fflp error registers to figure out what the error
19563859Sml29623 	 * is
19573859Sml29623 	 */
19583859Sml29623 	npi_fflp_vlan_error_get(handle, &vlan_err);
19593859Sml29623 	npi_fflp_tcam_error_get(handle, &tcam_err);
19603859Sml29623 
19613859Sml29623 	if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) {
19623859Sml29623 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
19633859Sml29623 			" vlan table parity error on port %d"
19643859Sml29623 			" addr: 0x%x data: 0x%x",
19653859Sml29623 			portn, vlan_err.bits.ldw.addr,
19663859Sml29623 			vlan_err.bits.ldw.data));
19673859Sml29623 		statsp->vlan_parity_err++;
19683859Sml29623 
19693859Sml29623 		if (vlan_err.bits.ldw.m_err) {
19703859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
19713859Sml29623 				" vlan table multiple errors on port %d",
19723859Sml29623 				portn));
19733859Sml29623 		}
19743859Sml29623 		statsp->errlog.vlan = (uint32_t)vlan_err.value;
19753859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
19763859Sml29623 			NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR);
19773859Sml29623 		npi_fflp_vlan_error_clear(handle);
19783859Sml29623 	}
19793859Sml29623 
19803859Sml29623 	if (tcam_err.bits.ldw.err) {
19813859Sml29623 		if (tcam_err.bits.ldw.p_ecc != 0) {
19823859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
19833859Sml29623 				" TCAM ECC error on port %d"
19843859Sml29623 				" TCAM entry: 0x%x syndrome: 0x%x",
19853859Sml29623 				portn, tcam_err.bits.ldw.addr,
19863859Sml29623 				tcam_err.bits.ldw.syndrome));
19873859Sml29623 			statsp->tcam_ecc_err++;
19883859Sml29623 		} else {
19893859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
19903859Sml29623 				" TCAM Parity error on port %d"
19913859Sml29623 				" addr: 0x%x parity value: 0x%x",
19923859Sml29623 				portn, tcam_err.bits.ldw.addr,
19933859Sml29623 				tcam_err.bits.ldw.syndrome));
19943859Sml29623 			statsp->tcam_parity_err++;
19953859Sml29623 		}
19963859Sml29623 
19973859Sml29623 		if (tcam_err.bits.ldw.mult) {
19983859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
19993859Sml29623 				" TCAM Multiple errors on port %d", portn));
20003859Sml29623 		} else {
20013859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
20023859Sml29623 					" TCAM PIO error on port %d",
20033859Sml29623 					portn));
20043859Sml29623 		}
20053859Sml29623 
20063859Sml29623 		statsp->errlog.tcam = (uint32_t)tcam_err.value;
20073859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
20083859Sml29623 			NXGE_FM_EREPORT_FFLP_TCAM_ERR);
20093859Sml29623 		npi_fflp_tcam_error_clear(handle);
20103859Sml29623 	}
20113859Sml29623 
20123859Sml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
20133859Sml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
20143859Sml29623 
20153859Sml29623 	for (rdc_grp = p_cfgp->start_rdc_grpid;
20163859Sml29623 		rdc_grp < p_cfgp->max_rdc_grpids; rdc_grp++) {
20173859Sml29623 		npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp);
20183859Sml29623 		if (fcram_err.bits.ldw.pio_err) {
20193859Sml29623 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
20203859Sml29623 				" FCRAM PIO ECC error on port %d"
20213859Sml29623 				" rdc group: %d Hash Table addr: 0x%x"
20223859Sml29623 				" syndrome: 0x%x",
20233859Sml29623 				portn, rdc_grp,
20243859Sml29623 				fcram_err.bits.ldw.fcram_addr,
20253859Sml29623 				fcram_err.bits.ldw.syndrome));
20263859Sml29623 			statsp->hash_pio_err[rdc_grp]++;
20273859Sml29623 			statsp->errlog.hash_pio[rdc_grp] =
20283859Sml29623 				(uint32_t)fcram_err.value;
20293859Sml29623 			NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
20303859Sml29623 				NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR);
20313859Sml29623 			npi_fflp_fcram_error_clear(handle, rdc_grp);
20323859Sml29623 		}
20333859Sml29623 	}
20343859Sml29623 
20353859Sml29623 	npi_fflp_fcram_error_log1_get(handle, &fcram1_err);
20363859Sml29623 	if (fcram1_err.bits.ldw.ecc_err) {
20373859Sml29623 		char *multi_str = "";
20383859Sml29623 		char *multi_bit_str = "";
20393859Sml29623 
20403859Sml29623 		npi_fflp_fcram_error_log2_get(handle, &fcram2_err);
20413859Sml29623 		if (fcram1_err.bits.ldw.mult_lk) {
20423859Sml29623 			multi_str = "multiple";
20433859Sml29623 		}
20443859Sml29623 		if (fcram1_err.bits.ldw.mult_bit) {
20453859Sml29623 			multi_bit_str = "multiple bits";
20463859Sml29623 		}
20473859Sml29623 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
20483859Sml29623 			" FCRAM %s lookup %s ECC error on port %d"
20493859Sml29623 			" H1: 0x%x Subarea: 0x%x Syndrome: 0x%x",
20503859Sml29623 			multi_str, multi_bit_str, portn,
20513859Sml29623 			fcram2_err.bits.ldw.h1,
20523859Sml29623 			fcram2_err.bits.ldw.subarea,
20533859Sml29623 			fcram2_err.bits.ldw.syndrome));
20543859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
20553859Sml29623 			NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR);
20563859Sml29623 	}
20573859Sml29623 	statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value;
20583859Sml29623 	statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value;
20593859Sml29623 	return (NXGE_OK);
20603859Sml29623 }
2061