xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_fflp.c (revision 678453a8)
144961713Sgirish /*
244961713Sgirish  * CDDL HEADER START
344961713Sgirish  *
444961713Sgirish  * The contents of this file are subject to the terms of the
544961713Sgirish  * Common Development and Distribution License (the "License").
644961713Sgirish  * You may not use this file except in compliance with the License.
744961713Sgirish  *
844961713Sgirish  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
944961713Sgirish  * or http://www.opensolaris.org/os/licensing.
1044961713Sgirish  * See the License for the specific language governing permissions
1144961713Sgirish  * and limitations under the License.
1244961713Sgirish  *
1344961713Sgirish  * When distributing Covered Code, include this CDDL HEADER in each
1444961713Sgirish  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1544961713Sgirish  * If applicable, add the following below this CDDL HEADER, with the
1644961713Sgirish  * fields enclosed by brackets "[]" replaced with your own identifying
1744961713Sgirish  * information: Portions Copyright [yyyy] [name of copyright owner]
1844961713Sgirish  *
1944961713Sgirish  * CDDL HEADER END
2044961713Sgirish  */
2144961713Sgirish /*
22*678453a8Sspeer  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2344961713Sgirish  * Use is subject to license terms.
2444961713Sgirish  */
2544961713Sgirish 
2644961713Sgirish #pragma ident	"%Z%%M%	%I%	%E% SMI"
2744961713Sgirish 
2844961713Sgirish #include <npi_fflp.h>
2944961713Sgirish #include <npi_mac.h>
3044961713Sgirish #include <nxge_defs.h>
3144961713Sgirish #include <nxge_flow.h>
3244961713Sgirish #include <nxge_fflp.h>
3344961713Sgirish #include <nxge_impl.h>
3444961713Sgirish #include <nxge_fflp_hash.h>
3544961713Sgirish #include <nxge_common.h>
3644961713Sgirish 
3744961713Sgirish 
38a3c5bd6dSspeer /*
39a3c5bd6dSspeer  * Function prototypes
40a3c5bd6dSspeer  */
4144961713Sgirish static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t);
4244961713Sgirish static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t);
4344961713Sgirish static nxge_status_t nxge_fflp_tcam_init(p_nxge_t);
4444961713Sgirish static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t);
4544961713Sgirish static nxge_status_t nxge_fflp_fcram_init(p_nxge_t);
4644961713Sgirish static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *);
47a3c5bd6dSspeer static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
48a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
49a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
5044961713Sgirish static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *,
51a3c5bd6dSspeer 	tcam_entry_t *);
52a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *,
53a3c5bd6dSspeer 	tcam_entry_t *);
54a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *,
55a3c5bd6dSspeer 	tcam_entry_t *);
5644961713Sgirish static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, intptr_t);
5744961713Sgirish static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, intptr_t);
5844961713Sgirish static tcam_location_t nxge_get_tcam_location(p_nxge_t, uint8_t);
5944961713Sgirish 
60a3c5bd6dSspeer /*
61a3c5bd6dSspeer  * functions used outside this file
62a3c5bd6dSspeer  */
6344961713Sgirish nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t);
6444961713Sgirish nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t);
6544961713Sgirish nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *);
6614ea4bb7Ssd static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t);
6744961713Sgirish nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *);
6844961713Sgirish nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *);
6944961713Sgirish nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *,
70a3c5bd6dSspeer 	uint32_t *, uint16_t *);
7144961713Sgirish 
7244961713Sgirish nxge_status_t
7344961713Sgirish nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location)
7444961713Sgirish {
7544961713Sgirish 	tcam_entry_t tcam_rdptr;
7644961713Sgirish 	uint64_t asc_ram = 0;
7744961713Sgirish 	npi_handle_t handle;
7844961713Sgirish 	npi_status_t status;
7944961713Sgirish 
8044961713Sgirish 	handle = nxgep->npi_reg_handle;
8144961713Sgirish 
8244961713Sgirish 	bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry));
8344961713Sgirish 	status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location,
84a3c5bd6dSspeer 		(struct tcam_entry *)&tcam_rdptr);
8544961713Sgirish 	if (status & NPI_FAILURE) {
8644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
87a3c5bd6dSspeer 			" nxge_tcam_dump_entry:"
88a3c5bd6dSspeer 			"  tcam read failed at location %d ", location));
8944961713Sgirish 		return (NXGE_ERROR);
9044961713Sgirish 	}
9144961713Sgirish 	status = npi_fflp_tcam_asc_ram_entry_read(handle,
92a3c5bd6dSspeer 		(tcam_location_t)location, &asc_ram);
9344961713Sgirish 
9444961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n"
95a3c5bd6dSspeer 		" key:  %llx %llx %llx %llx \n"
96a3c5bd6dSspeer 		" mask: %llx %llx %llx %llx \n"
97a3c5bd6dSspeer 		" ASC RAM %llx \n", location,
98a3c5bd6dSspeer 		tcam_rdptr.key0, tcam_rdptr.key1,
99a3c5bd6dSspeer 		tcam_rdptr.key2, tcam_rdptr.key3,
100a3c5bd6dSspeer 		tcam_rdptr.mask0, tcam_rdptr.mask1,
101a3c5bd6dSspeer 		tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram));
10244961713Sgirish 	return (NXGE_OK);
10344961713Sgirish }
10444961713Sgirish 
10544961713Sgirish void
10644961713Sgirish nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp)
10744961713Sgirish {
10844961713Sgirish 	uint32_t tcam_loc;
10944961713Sgirish 	int *lptr;
11044961713Sgirish 	int location;
11144961713Sgirish 
11244961713Sgirish 	uint32_t start_location = 0;
11344961713Sgirish 	uint32_t stop_location = nxgep->classifier.tcam_size;
11444961713Sgirish 	lptr = (int *)mp->b_rptr;
11544961713Sgirish 	location = *lptr;
11644961713Sgirish 
11744961713Sgirish 	if ((location >= nxgep->classifier.tcam_size) || (location < -1)) {
11844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
119a3c5bd6dSspeer 			"nxge_tcam_dump: Invalid location %d \n", location));
12044961713Sgirish 		return;
12144961713Sgirish 	}
12244961713Sgirish 	if (location == -1) {
12344961713Sgirish 		start_location = 0;
12444961713Sgirish 		stop_location = nxgep->classifier.tcam_size;
12544961713Sgirish 	} else {
12644961713Sgirish 		start_location = location;
127a3c5bd6dSspeer 		stop_location = location + 1;
12844961713Sgirish 	}
12944961713Sgirish 	for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++)
13044961713Sgirish 		(void) nxge_tcam_dump_entry(nxgep, tcam_loc);
13144961713Sgirish }
13244961713Sgirish 
13344961713Sgirish /*
13444961713Sgirish  * nxge_fflp_vlan_table_invalidate_all
13544961713Sgirish  * invalidates the vlan RDC table entries.
13644961713Sgirish  * INPUT
13744961713Sgirish  * nxge    soft state data structure
13844961713Sgirish  * Return
13944961713Sgirish  *      NXGE_OK
14044961713Sgirish  *      NXGE_ERROR
14144961713Sgirish  *
14244961713Sgirish  */
143a3c5bd6dSspeer 
14444961713Sgirish static nxge_status_t
14544961713Sgirish nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)
14644961713Sgirish {
14744961713Sgirish 	vlan_id_t vlan_id;
14844961713Sgirish 	npi_handle_t handle;
14944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
15044961713Sgirish 	vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
15144961713Sgirish 
15244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all "));
15344961713Sgirish 	handle = nxgep->npi_reg_handle;
15444961713Sgirish 	for (vlan_id = start; vlan_id < stop; vlan_id++) {
15544961713Sgirish 		rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id);
15644961713Sgirish 		if (rs != NPI_SUCCESS) {
15744961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
158a3c5bd6dSspeer 				"VLAN Table invalidate failed for vlan id %d ",
159a3c5bd6dSspeer 				vlan_id));
16044961713Sgirish 			return (NXGE_ERROR | rs);
16144961713Sgirish 		}
16244961713Sgirish 	}
16344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all "));
16444961713Sgirish 	return (NXGE_OK);
16544961713Sgirish }
16644961713Sgirish 
16744961713Sgirish /*
16844961713Sgirish  * The following functions are used by other modules to init
16944961713Sgirish  * the fflp module.
17044961713Sgirish  * these functions are the basic API used to init
17144961713Sgirish  * the fflp modules (tcam, fcram etc ......)
17244961713Sgirish  *
17344961713Sgirish  * The TCAM search future would be disabled  by default.
17444961713Sgirish  */
17544961713Sgirish 
17644961713Sgirish static nxge_status_t
17744961713Sgirish nxge_fflp_tcam_init(p_nxge_t nxgep)
17844961713Sgirish {
17944961713Sgirish 	uint8_t access_ratio;
18044961713Sgirish 	tcam_class_t class;
18144961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
18244961713Sgirish 	npi_handle_t handle;
18344961713Sgirish 
18444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init"));
18544961713Sgirish 	handle = nxgep->npi_reg_handle;
18644961713Sgirish 
18744961713Sgirish 	rs = npi_fflp_cfg_tcam_disable(handle);
18844961713Sgirish 	if (rs != NPI_SUCCESS) {
18944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n"));
19044961713Sgirish 		return (NXGE_ERROR | rs);
19144961713Sgirish 	}
19244961713Sgirish 
19344961713Sgirish 	access_ratio = nxgep->param_arr[param_tcam_access_ratio].value;
19444961713Sgirish 	rs = npi_fflp_cfg_tcam_access(handle, access_ratio);
19544961713Sgirish 	if (rs != NPI_SUCCESS) {
19644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
197a3c5bd6dSspeer 				"failed TCAM Access cfg\n"));
19844961713Sgirish 		return (NXGE_ERROR | rs);
19944961713Sgirish 	}
20044961713Sgirish 
201a3c5bd6dSspeer 	/* disable configurable classes */
202a3c5bd6dSspeer 	/* disable the configurable ethernet classes; */
20344961713Sgirish 	for (class = TCAM_CLASS_ETYPE_1;
20444961713Sgirish 		class <= TCAM_CLASS_ETYPE_2; class++) {
20544961713Sgirish 		rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class);
20644961713Sgirish 		if (rs != NPI_SUCCESS) {
20744961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
208a3c5bd6dSspeer 				"TCAM USR Ether Class config failed."));
20944961713Sgirish 			return (NXGE_ERROR | rs);
21044961713Sgirish 		}
21144961713Sgirish 	}
21244961713Sgirish 
213a3c5bd6dSspeer 	/* disable the configurable ip classes; */
21444961713Sgirish 	for (class = TCAM_CLASS_IP_USER_4;
21544961713Sgirish 		class <= TCAM_CLASS_IP_USER_7; class++) {
21644961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
21744961713Sgirish 		if (rs != NPI_SUCCESS) {
21844961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
219a3c5bd6dSspeer 				"TCAM USR IP Class cnfg failed."));
22044961713Sgirish 			return (NXGE_ERROR | rs);
22144961713Sgirish 		}
22244961713Sgirish 	}
22344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init"));
22444961713Sgirish 	return (NXGE_OK);
22544961713Sgirish }
22644961713Sgirish 
22744961713Sgirish /*
22844961713Sgirish  * nxge_fflp_tcam_invalidate_all
22944961713Sgirish  * invalidates all the tcam entries.
23044961713Sgirish  * INPUT
23144961713Sgirish  * nxge    soft state data structure
23244961713Sgirish  * Return
23344961713Sgirish  *      NXGE_OK
23444961713Sgirish  *      NXGE_ERROR
23544961713Sgirish  *
23644961713Sgirish  */
237a3c5bd6dSspeer 
238a3c5bd6dSspeer 
23944961713Sgirish static nxge_status_t
24044961713Sgirish nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)
24144961713Sgirish {
24244961713Sgirish 	uint16_t location;
24344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
24444961713Sgirish 	npi_handle_t handle;
24544961713Sgirish 	uint16_t start = 0, stop = nxgep->classifier.tcam_size;
246a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
24744961713Sgirish 
24844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
249a3c5bd6dSspeer 		"==> nxge_fflp_tcam_invalidate_all"));
25044961713Sgirish 	handle = nxgep->npi_reg_handle;
25144961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
25244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25344961713Sgirish 			" nxge_fflp_tcam_invalidate_all:"
254a3c5bd6dSspeer 			" common hardware not set", nxgep->niu_type));
25544961713Sgirish 		return (NXGE_ERROR);
25644961713Sgirish 	}
25744961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
25844961713Sgirish 	for (location = start; location < stop; location++) {
25944961713Sgirish 		rs = npi_fflp_tcam_entry_invalidate(handle, location);
26044961713Sgirish 		if (rs != NPI_SUCCESS) {
26144961713Sgirish 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
26244961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
263a3c5bd6dSspeer 				"TCAM invalidate failed at loc %d ", location));
26444961713Sgirish 			return (NXGE_ERROR | rs);
26544961713Sgirish 		}
26644961713Sgirish 	}
26744961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
26844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
269a3c5bd6dSspeer 			"<== nxge_fflp_tcam_invalidate_all"));
27044961713Sgirish 	return (NXGE_OK);
27144961713Sgirish }
27244961713Sgirish 
27344961713Sgirish /*
27444961713Sgirish  * nxge_fflp_fcram_entry_invalidate_all
27544961713Sgirish  * invalidates all the FCRAM entries.
27644961713Sgirish  * INPUT
27744961713Sgirish  * nxge    soft state data structure
27844961713Sgirish  * Return
27944961713Sgirish  *      NXGE_OK
28044961713Sgirish  *      NXGE_ERROR
28144961713Sgirish  *
28244961713Sgirish  */
283a3c5bd6dSspeer 
28444961713Sgirish static nxge_status_t
28544961713Sgirish nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)
28644961713Sgirish {
287a3c5bd6dSspeer 	npi_handle_t handle;
288a3c5bd6dSspeer 	npi_status_t rs = NPI_SUCCESS;
289a3c5bd6dSspeer 	part_id_t pid = 0;
290a3c5bd6dSspeer 	uint8_t base_mask, base_reloc;
291a3c5bd6dSspeer 	fcram_entry_t fc;
292a3c5bd6dSspeer 	uint32_t location;
293a3c5bd6dSspeer 	uint32_t increment, last_location;
29444961713Sgirish 
295a3c5bd6dSspeer 	/*
296a3c5bd6dSspeer 	 * (1) configure and enable partition 0 with no relocation
297a3c5bd6dSspeer 	 * (2) Assume the FCRAM is used as IPv4 exact match entry cells
298a3c5bd6dSspeer 	 * (3) Invalidate these cells by clearing the valid bit in
299a3c5bd6dSspeer 	 * the subareas 0 and 4
300a3c5bd6dSspeer 	 * (4) disable the partition
301a3c5bd6dSspeer 	 *
302a3c5bd6dSspeer 	 */
30344961713Sgirish 
30444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all"));
30544961713Sgirish 
30644961713Sgirish 	base_mask = base_reloc = 0x0;
30744961713Sgirish 	handle = nxgep->npi_reg_handle;
308a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc);
30944961713Sgirish 
31044961713Sgirish 	if (rs != NPI_SUCCESS) {
311a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n"));
31244961713Sgirish 		return (NXGE_ERROR | rs);
31344961713Sgirish 	}
314a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_partition_disable(handle, pid);
31544961713Sgirish 
31644961713Sgirish 	if (rs != NPI_SUCCESS) {
31744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
318a3c5bd6dSspeer 			"failed partition enable\n"));
31944961713Sgirish 		return (NXGE_ERROR | rs);
32044961713Sgirish 	}
321a3c5bd6dSspeer 	fc.dreg[0].value = 0;
322a3c5bd6dSspeer 	fc.hash_hdr_valid = 0;
323a3c5bd6dSspeer 	fc.hash_hdr_ext = 1;	/* specify as IPV4 exact match entry */
324a3c5bd6dSspeer 	increment = sizeof (hash_ipv4_t);
325a3c5bd6dSspeer 	last_location = FCRAM_SIZE * 0x40;
32644961713Sgirish 
327a3c5bd6dSspeer 	for (location = 0; location < last_location; location += increment) {
32844961713Sgirish 		rs = npi_fflp_fcram_subarea_write(handle, pid,
329a3c5bd6dSspeer 			location,
330a3c5bd6dSspeer 			fc.value[0]);
33144961713Sgirish 		if (rs != NPI_SUCCESS) {
33244961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
333a3c5bd6dSspeer 					"failed write"
334a3c5bd6dSspeer 					"at location %x ",
335a3c5bd6dSspeer 					location));
33644961713Sgirish 			return (NXGE_ERROR | rs);
33744961713Sgirish 		}
33844961713Sgirish 	}
33944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all"));
340a3c5bd6dSspeer 	return (NXGE_OK);
34144961713Sgirish }
34244961713Sgirish 
34344961713Sgirish static nxge_status_t
34444961713Sgirish nxge_fflp_fcram_init(p_nxge_t nxgep)
34544961713Sgirish {
34644961713Sgirish 	fflp_fcram_output_drive_t strength;
34744961713Sgirish 	fflp_fcram_qs_t qs;
34844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
34944961713Sgirish 	uint8_t access_ratio;
350a3c5bd6dSspeer 	int partition;
35144961713Sgirish 	npi_handle_t handle;
352a3c5bd6dSspeer 	uint32_t min_time, max_time, sys_time;
35344961713Sgirish 
35444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init"));
35544961713Sgirish 
356a3c5bd6dSspeer 	/*
357a3c5bd6dSspeer 	 * Recommended values are needed.
358a3c5bd6dSspeer 	 */
35944961713Sgirish 	min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME;
36044961713Sgirish 	max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME;
36144961713Sgirish 	sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME;
362a3c5bd6dSspeer 
36344961713Sgirish 	handle = nxgep->npi_reg_handle;
36444961713Sgirish 	strength = FCRAM_OUTDR_NORMAL;
36544961713Sgirish 	qs = FCRAM_QS_MODE_QS;
36644961713Sgirish 	rs = npi_fflp_cfg_fcram_reset(handle, strength, qs);
36744961713Sgirish 	if (rs != NPI_SUCCESS) {
36844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. "));
36944961713Sgirish 		return (NXGE_ERROR | rs);
37044961713Sgirish 	}
37144961713Sgirish 
372a3c5bd6dSspeer 	access_ratio = nxgep->param_arr[param_fcram_access_ratio].value;
373a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_access(handle, access_ratio);
374a3c5bd6dSspeer 	if (rs != NPI_SUCCESS) {
37544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio"
376a3c5bd6dSspeer 			"configuration \n"));
37744961713Sgirish 		return (NXGE_ERROR | rs);
37844961713Sgirish 	}
37944961713Sgirish 	rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time,
380a3c5bd6dSspeer 		max_time, sys_time);
38144961713Sgirish 	if (rs != NPI_SUCCESS) {
38244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
383a3c5bd6dSspeer 			"failed FCRAM refresh cfg"));
38444961713Sgirish 		return (NXGE_ERROR);
38544961713Sgirish 	}
38644961713Sgirish 
38744961713Sgirish 	/* disable all the partitions until explicitly enabled */
38844961713Sgirish 	for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) {
389a3c5bd6dSspeer 		rs = npi_fflp_cfg_fcram_partition_disable(handle, partition);
39044961713Sgirish 		if (rs != NPI_SUCCESS) {
39144961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
392a3c5bd6dSspeer 				"failed FCRAM partition"
393a3c5bd6dSspeer 				" enable for partition %d ", partition));
39444961713Sgirish 			return (NXGE_ERROR | rs);
39544961713Sgirish 		}
39644961713Sgirish 	}
39744961713Sgirish 
39844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init"));
399a3c5bd6dSspeer 	return (NXGE_OK);
40044961713Sgirish }
40144961713Sgirish 
40244961713Sgirish nxge_status_t
40344961713Sgirish nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac)
40444961713Sgirish {
40544961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
40644961713Sgirish 	hostinfo_t mac_rdc;
40744961713Sgirish 	npi_handle_t handle;
408a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
40944961713Sgirish 
410a3c5bd6dSspeer 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
41144961713Sgirish 	if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) {
412a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
413a3c5bd6dSspeer 			" nxge_logical_mac_assign_rdc_table"
414a3c5bd6dSspeer 			" unconfigured alt MAC addr %d ", alt_mac));
41544961713Sgirish 		return (NXGE_ERROR);
41644961713Sgirish 	}
41744961713Sgirish 	handle = nxgep->npi_reg_handle;
41844961713Sgirish 	mac_rdc.value = 0;
41944961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num =
420a3c5bd6dSspeer 		p_class_cfgp->mac_host_info[alt_mac].rdctbl;
42144961713Sgirish 	mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr;
42244961713Sgirish 
42344961713Sgirish 	rs = npi_mac_hostinfo_entry(handle, OP_SET,
424a3c5bd6dSspeer 		nxgep->function_num, alt_mac, &mac_rdc);
42544961713Sgirish 
42644961713Sgirish 	if (rs != NPI_SUCCESS) {
42744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
428a3c5bd6dSspeer 			"failed Assign RDC table"));
42944961713Sgirish 		return (NXGE_ERROR | rs);
43044961713Sgirish 	}
43144961713Sgirish 	return (NXGE_OK);
43244961713Sgirish }
43344961713Sgirish 
43444961713Sgirish nxge_status_t
43544961713Sgirish nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)
43644961713Sgirish {
43744961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
43844961713Sgirish 	hostinfo_t mac_rdc;
43944961713Sgirish 	npi_handle_t handle;
44044961713Sgirish 
44144961713Sgirish 	handle = nxgep->npi_reg_handle;
44244961713Sgirish 	mac_rdc.value = 0;
44344961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp;
44444961713Sgirish 	mac_rdc.bits.w0.mac_pref = 1;
44544961713Sgirish 	switch (nxgep->function_num) {
446a3c5bd6dSspeer 	case 0:
447a3c5bd6dSspeer 	case 1:
448a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
449a3c5bd6dSspeer 			nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY,
450a3c5bd6dSspeer 			&mac_rdc);
451a3c5bd6dSspeer 		break;
452a3c5bd6dSspeer 	case 2:
453a3c5bd6dSspeer 	case 3:
454a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
455a3c5bd6dSspeer 			nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY,
456a3c5bd6dSspeer 			&mac_rdc);
457a3c5bd6dSspeer 		break;
458a3c5bd6dSspeer 	default:
459a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
46058324dfcSspeer 			"failed Assign RDC table (invalid function #)"));
461a3c5bd6dSspeer 		return (NXGE_ERROR);
46244961713Sgirish 	}
46344961713Sgirish 
46444961713Sgirish 	if (rs != NPI_SUCCESS) {
46544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
466a3c5bd6dSspeer 				"failed Assign RDC table"));
46744961713Sgirish 		return (NXGE_ERROR | rs);
46844961713Sgirish 	}
46944961713Sgirish 	return (NXGE_OK);
47044961713Sgirish }
47144961713Sgirish 
47258324dfcSspeer /*
47358324dfcSspeer  * Initialize hostinfo registers for alternate MAC addresses and
47458324dfcSspeer  * multicast MAC address.
47558324dfcSspeer  */
47644961713Sgirish nxge_status_t
47758324dfcSspeer nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)
47844961713Sgirish {
47944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
48044961713Sgirish 	hostinfo_t mac_rdc;
48144961713Sgirish 	npi_handle_t handle;
48258324dfcSspeer 	int i;
48344961713Sgirish 
48444961713Sgirish 	handle = nxgep->npi_reg_handle;
48544961713Sgirish 	mac_rdc.value = 0;
48644961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp;
48744961713Sgirish 	mac_rdc.bits.w0.mac_pref = 1;
48844961713Sgirish 	switch (nxgep->function_num) {
489a3c5bd6dSspeer 	case 0:
490a3c5bd6dSspeer 	case 1:
49158324dfcSspeer 		/*
49258324dfcSspeer 		 * Tests indicate that it is OK not to re-initialize the
49358324dfcSspeer 		 * hostinfo registers for the XMAC's alternate MAC
49458324dfcSspeer 		 * addresses. But that is necessary for BMAC (case 2
49558324dfcSspeer 		 * and case 3 below)
49658324dfcSspeer 		 */
497a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
498a3c5bd6dSspeer 			nxgep->function_num,
499a3c5bd6dSspeer 			XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
500a3c5bd6dSspeer 		break;
501a3c5bd6dSspeer 	case 2:
502a3c5bd6dSspeer 	case 3:
50358324dfcSspeer 		for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
50458324dfcSspeer 			rs |= npi_mac_hostinfo_entry(handle, OP_SET,
50558324dfcSspeer 			nxgep->function_num, i, &mac_rdc);
50658324dfcSspeer 
50758324dfcSspeer 		rs |= npi_mac_hostinfo_entry(handle, OP_SET,
508a3c5bd6dSspeer 			nxgep->function_num,
509a3c5bd6dSspeer 			BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
510a3c5bd6dSspeer 		break;
511a3c5bd6dSspeer 	default:
512a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
513f6485eecSyc 			"failed Assign RDC table (invalid function #)"));
514a3c5bd6dSspeer 		return (NXGE_ERROR);
51544961713Sgirish 	}
51644961713Sgirish 
51744961713Sgirish 	if (rs != NPI_SUCCESS) {
51844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
519a3c5bd6dSspeer 			"failed Assign RDC table"));
52044961713Sgirish 		return (NXGE_ERROR | rs);
52144961713Sgirish 	}
52244961713Sgirish 	return (NXGE_OK);
52344961713Sgirish }
52444961713Sgirish 
52544961713Sgirish nxge_status_t
52644961713Sgirish nxge_fflp_init_hostinfo(p_nxge_t nxgep)
52744961713Sgirish {
52844961713Sgirish 	nxge_status_t status = NXGE_OK;
529a3c5bd6dSspeer 
53058324dfcSspeer 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
53158324dfcSspeer 	status |= nxge_main_mac_assign_rdc_table(nxgep);
53244961713Sgirish 	return (status);
53344961713Sgirish }
53444961713Sgirish 
53544961713Sgirish nxge_status_t
53644961713Sgirish nxge_fflp_hw_reset(p_nxge_t nxgep)
53744961713Sgirish {
53844961713Sgirish 	npi_handle_t handle;
53944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
54044961713Sgirish 	nxge_status_t status = NXGE_OK;
54144961713Sgirish 
54244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
54344961713Sgirish 
5442e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
54544961713Sgirish 		status = nxge_fflp_fcram_init(nxgep);
546a3c5bd6dSspeer 		if (status != NXGE_OK) {
54744961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
548a3c5bd6dSspeer 				" failed FCRAM init. "));
54944961713Sgirish 			return (status);
55044961713Sgirish 		}
55144961713Sgirish 	}
55244961713Sgirish 
55344961713Sgirish 	status = nxge_fflp_tcam_init(nxgep);
55444961713Sgirish 	if (status != NXGE_OK) {
555a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
556a3c5bd6dSspeer 			"failed TCAM init."));
557a3c5bd6dSspeer 		return (status);
55844961713Sgirish 	}
55944961713Sgirish 
56044961713Sgirish 	handle = nxgep->npi_reg_handle;
56144961713Sgirish 	rs = npi_fflp_cfg_llcsnap_enable(handle);
56244961713Sgirish 	if (rs != NPI_SUCCESS) {
563a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
564a3c5bd6dSspeer 			"failed LLCSNAP enable. "));
565a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
56644961713Sgirish 	}
56744961713Sgirish 
56844961713Sgirish 	rs = npi_fflp_cfg_cam_errorcheck_disable(handle);
56944961713Sgirish 	if (rs != NPI_SUCCESS) {
57044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
571a3c5bd6dSspeer 			"failed CAM Error Check enable. "));
57244961713Sgirish 		return (NXGE_ERROR | rs);
57344961713Sgirish 	}
57444961713Sgirish 
575a3c5bd6dSspeer 	/* init the hash generators */
57644961713Sgirish 	rs = npi_fflp_cfg_hash_h1poly(handle, 0);
57744961713Sgirish 	if (rs != NPI_SUCCESS) {
578a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
579a3c5bd6dSspeer 			"failed H1 Poly Init. "));
580a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
58144961713Sgirish 	}
58244961713Sgirish 
58344961713Sgirish 	rs = npi_fflp_cfg_hash_h2poly(handle, 0);
58444961713Sgirish 	if (rs != NPI_SUCCESS) {
585a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
586a3c5bd6dSspeer 			"failed H2 Poly Init. "));
587a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
58844961713Sgirish 	}
58944961713Sgirish 
590a3c5bd6dSspeer 	/* invalidate TCAM entries */
59144961713Sgirish 	status = nxge_fflp_tcam_invalidate_all(nxgep);
59244961713Sgirish 	if (status != NXGE_OK) {
59344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
594a3c5bd6dSspeer 			"failed TCAM Entry Invalidate. "));
59544961713Sgirish 		return (status);
59644961713Sgirish 	}
59744961713Sgirish 
598a3c5bd6dSspeer 	/* invalidate FCRAM entries */
5992e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
60044961713Sgirish 		status = nxge_fflp_fcram_invalidate_all(nxgep);
60144961713Sgirish 		if (status != NXGE_OK) {
60244961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
603a3c5bd6dSspeer 					"failed FCRAM Entry Invalidate."));
60444961713Sgirish 			return (status);
60544961713Sgirish 		}
60644961713Sgirish 	}
60744961713Sgirish 
608a3c5bd6dSspeer 	/* invalidate VLAN RDC tables */
60944961713Sgirish 	status = nxge_fflp_vlan_tbl_clear_all(nxgep);
61044961713Sgirish 	if (status != NXGE_OK) {
61144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
612a3c5bd6dSspeer 			"failed VLAN Table Invalidate. "));
61344961713Sgirish 		return (status);
61444961713Sgirish 	}
61544961713Sgirish 	nxgep->classifier.state |= NXGE_FFLP_HW_RESET;
61644961713Sgirish 
61744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset"));
61844961713Sgirish 	return (NXGE_OK);
61944961713Sgirish }
62044961713Sgirish 
62144961713Sgirish nxge_status_t
62244961713Sgirish nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class,
623a3c5bd6dSspeer 	uint32_t class_config)
62444961713Sgirish {
62544961713Sgirish 	flow_key_cfg_t fcfg;
62644961713Sgirish 	npi_handle_t handle;
62744961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
62844961713Sgirish 
62944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key"));
63044961713Sgirish 	handle = nxgep->npi_reg_handle;
63144961713Sgirish 	bzero(&fcfg, sizeof (flow_key_cfg_t));
63244961713Sgirish 
633a3c5bd6dSspeer 	if (class_config & NXGE_CLASS_FLOW_USE_PROTO)
63444961713Sgirish 		fcfg.use_proto = 1;
63544961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT)
63644961713Sgirish 		fcfg.use_dport = 1;
63744961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT)
63844961713Sgirish 		fcfg.use_sport = 1;
63944961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_IPDST)
64044961713Sgirish 		fcfg.use_daddr = 1;
64144961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_IPSRC)
64244961713Sgirish 		fcfg.use_saddr = 1;
64344961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_VLAN)
64444961713Sgirish 		fcfg.use_vlan = 1;
64544961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_L2DA)
64644961713Sgirish 		fcfg.use_l2da = 1;
64744961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM)
64844961713Sgirish 		fcfg.use_portnum = 1;
64944961713Sgirish 	fcfg.ip_opts_exist = 0;
65044961713Sgirish 
65144961713Sgirish 	rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg);
65244961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
65344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
654a3c5bd6dSspeer 			" opt %x for class %d failed ",
655a3c5bd6dSspeer 			class_config, l3_class));
65644961713Sgirish 		return (NXGE_ERROR | rs);
65744961713Sgirish 	}
65844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key"));
65944961713Sgirish 	return (NXGE_OK);
66044961713Sgirish }
66144961713Sgirish 
66244961713Sgirish nxge_status_t
66344961713Sgirish nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class,
664a3c5bd6dSspeer 	uint32_t *class_config)
66544961713Sgirish {
66644961713Sgirish 	flow_key_cfg_t fcfg;
66744961713Sgirish 	npi_handle_t handle;
66844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
66944961713Sgirish 	uint32_t ccfg = 0;
670a3c5bd6dSspeer 
67144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get"));
67244961713Sgirish 	handle = nxgep->npi_reg_handle;
67344961713Sgirish 	bzero(&fcfg, sizeof (flow_key_cfg_t));
67444961713Sgirish 
67544961713Sgirish 	rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg);
67644961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
67744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
678a3c5bd6dSspeer 				" opt %x for class %d failed ",
679a3c5bd6dSspeer 				class_config, l3_class));
68044961713Sgirish 		return (NXGE_ERROR | rs);
68144961713Sgirish 	}
68244961713Sgirish 
68344961713Sgirish 	if (fcfg.use_proto)
68444961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_PROTO;
68544961713Sgirish 	if (fcfg.use_dport)
68644961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT;
68744961713Sgirish 	if (fcfg.use_sport)
68844961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT;
68944961713Sgirish 	if (fcfg.use_daddr)
69044961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_IPDST;
69144961713Sgirish 	if (fcfg.use_saddr)
69244961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_IPSRC;
69344961713Sgirish 	if (fcfg.use_vlan)
69444961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_VLAN;
69544961713Sgirish 	if (fcfg.use_l2da)
69644961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_L2DA;
69744961713Sgirish 	if (fcfg.use_portnum)
698a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM;
69944961713Sgirish 
70044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
701a3c5bd6dSspeer 		" nxge_cfg_ip_cls_flow_key_get %x", ccfg));
70244961713Sgirish 	*class_config = ccfg;
70344961713Sgirish 
70444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
705a3c5bd6dSspeer 		" <== nxge_cfg_ip_cls_flow_key_get"));
70644961713Sgirish 	return (NXGE_OK);
70744961713Sgirish }
70844961713Sgirish 
70944961713Sgirish static nxge_status_t
71044961713Sgirish nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class,
711a3c5bd6dSspeer 	uint32_t *class_config)
71244961713Sgirish {
71344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
71444961713Sgirish 	tcam_key_cfg_t cfg;
71544961713Sgirish 	npi_handle_t handle;
71644961713Sgirish 	uint32_t ccfg = 0;
71744961713Sgirish 
71844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
71944961713Sgirish 
72044961713Sgirish 	bzero(&cfg, sizeof (tcam_key_cfg_t));
72144961713Sgirish 	handle = nxgep->npi_reg_handle;
72244961713Sgirish 
72344961713Sgirish 	rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg);
72444961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
72544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
726a3c5bd6dSspeer 			" opt %x for class %d failed ",
727a3c5bd6dSspeer 			class_config, class));
72844961713Sgirish 		return (NXGE_ERROR | rs);
72944961713Sgirish 	}
73044961713Sgirish 	if (cfg.discard)
731a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_DISCARD;
73244961713Sgirish 	if (cfg.lookup_enable)
73344961713Sgirish 		ccfg |= NXGE_CLASS_TCAM_LOOKUP;
73444961713Sgirish 	if (cfg.use_ip_daddr)
735a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR;
73644961713Sgirish 	*class_config = ccfg;
73744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
738a3c5bd6dSspeer 			" ==> nxge_cfg_tcam_ip_class %x", ccfg));
73944961713Sgirish 	return (NXGE_OK);
74044961713Sgirish }
74144961713Sgirish 
74244961713Sgirish static nxge_status_t
74344961713Sgirish nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class,
744a3c5bd6dSspeer 	uint32_t class_config)
74544961713Sgirish {
74644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
74744961713Sgirish 	tcam_key_cfg_t cfg;
74844961713Sgirish 	npi_handle_t handle;
749a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
75044961713Sgirish 
75144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
752a3c5bd6dSspeer 
75344961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
75444961713Sgirish 	p_class_cfgp->class_cfg[class] = class_config;
75544961713Sgirish 
75644961713Sgirish 	bzero(&cfg, sizeof (tcam_key_cfg_t));
75744961713Sgirish 	handle = nxgep->npi_reg_handle;
75844961713Sgirish 	cfg.discard = 0;
75944961713Sgirish 	cfg.lookup_enable = 0;
76044961713Sgirish 	cfg.use_ip_daddr = 0;
76144961713Sgirish 	if (class_config & NXGE_CLASS_DISCARD)
76244961713Sgirish 		cfg.discard = 1;
76344961713Sgirish 	if (class_config & NXGE_CLASS_TCAM_LOOKUP)
76444961713Sgirish 		cfg.lookup_enable = 1;
765a3c5bd6dSspeer 	if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR)
76644961713Sgirish 		cfg.use_ip_daddr = 1;
76744961713Sgirish 
76844961713Sgirish 	rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg);
76944961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
77044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
771a3c5bd6dSspeer 			" opt %x for class %d failed ",
772a3c5bd6dSspeer 			class_config, class));
77344961713Sgirish 		return (NXGE_ERROR | rs);
77444961713Sgirish 	}
77544961713Sgirish 	return (NXGE_OK);
77644961713Sgirish }
77744961713Sgirish 
77844961713Sgirish nxge_status_t
77944961713Sgirish nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1)
78044961713Sgirish {
78144961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
78244961713Sgirish 	npi_handle_t handle;
783a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
78444961713Sgirish 
78544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1"));
78644961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
78744961713Sgirish 	p_class_cfgp->init_h1 = h1;
78844961713Sgirish 	handle = nxgep->npi_reg_handle;
78944961713Sgirish 	rs = npi_fflp_cfg_hash_h1poly(handle, h1);
79044961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
791a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
792a3c5bd6dSspeer 			" nxge_fflp_init_h1 %x failed ", h1));
79344961713Sgirish 		return (NXGE_ERROR | rs);
79444961713Sgirish 	}
79544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1"));
79644961713Sgirish 	return (NXGE_OK);
79744961713Sgirish }
79844961713Sgirish 
79944961713Sgirish nxge_status_t
80044961713Sgirish nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2)
80144961713Sgirish {
80244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
80344961713Sgirish 	npi_handle_t handle;
804a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
80544961713Sgirish 
80644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2"));
80744961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
80844961713Sgirish 	p_class_cfgp->init_h2 = h2;
80944961713Sgirish 
81044961713Sgirish 	handle = nxgep->npi_reg_handle;
81144961713Sgirish 	rs = npi_fflp_cfg_hash_h2poly(handle, h2);
81244961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
813a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
814a3c5bd6dSspeer 			" nxge_fflp_init_h2 %x failed ", h2));
81544961713Sgirish 		return (NXGE_ERROR | rs);
81644961713Sgirish 	}
81744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2"));
81844961713Sgirish 	return (NXGE_OK);
81944961713Sgirish }
82044961713Sgirish 
82144961713Sgirish nxge_status_t
82244961713Sgirish nxge_classify_init_sw(p_nxge_t nxgep)
82344961713Sgirish {
82444961713Sgirish 	int alloc_size;
82544961713Sgirish 	nxge_classify_t *classify_ptr;
82644961713Sgirish 
82744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw"));
82844961713Sgirish 	classify_ptr = &nxgep->classifier;
82944961713Sgirish 
83044961713Sgirish 	if (classify_ptr->state & NXGE_FFLP_SW_INIT) {
83144961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
832a3c5bd6dSspeer 			"nxge_classify_init_sw already init"));
83344961713Sgirish 		return (NXGE_OK);
83444961713Sgirish 	}
835a3c5bd6dSspeer 	/* Init SW structures */
83644961713Sgirish 	classify_ptr->tcam_size = TCAM_NIU_TCAM_MAX_ENTRY;
837a3c5bd6dSspeer 
838a3c5bd6dSspeer 	/* init data structures, based on HW type */
8392e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
84044961713Sgirish 		classify_ptr->tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY;
841a3c5bd6dSspeer 		/*
842a3c5bd6dSspeer 		 * check if fcram based classification is required and init the
843a3c5bd6dSspeer 		 * flow storage
844a3c5bd6dSspeer 		 */
84544961713Sgirish 	}
84644961713Sgirish 	alloc_size = sizeof (tcam_flow_spec_t) * classify_ptr->tcam_size;
84744961713Sgirish 	classify_ptr->tcam_entries = KMEM_ZALLOC(alloc_size, NULL);
84844961713Sgirish 
849a3c5bd6dSspeer 	/* Init defaults */
850a3c5bd6dSspeer 	/*
851a3c5bd6dSspeer 	 * add hacks required for HW shortcomings for example, code to handle
852a3c5bd6dSspeer 	 * fragmented packets
853a3c5bd6dSspeer 	 */
85444961713Sgirish 	nxge_init_h1_table();
85544961713Sgirish 	nxge_crc_ccitt_init();
85644961713Sgirish 	nxgep->classifier.tcam_location = nxgep->function_num;
85744961713Sgirish 	nxgep->classifier.fragment_bug = 1;
85844961713Sgirish 	classify_ptr->state |= NXGE_FFLP_SW_INIT;
85944961713Sgirish 
86044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw"));
86144961713Sgirish 	return (NXGE_OK);
86244961713Sgirish }
86344961713Sgirish 
86444961713Sgirish nxge_status_t
86544961713Sgirish nxge_classify_exit_sw(p_nxge_t nxgep)
86644961713Sgirish {
86744961713Sgirish 	int alloc_size;
86844961713Sgirish 	nxge_classify_t *classify_ptr;
86944961713Sgirish 	int fsize;
870a3c5bd6dSspeer 
87144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw"));
87244961713Sgirish 	classify_ptr = &nxgep->classifier;
87344961713Sgirish 
87444961713Sgirish 	fsize = sizeof (tcam_flow_spec_t);
87544961713Sgirish 	if (classify_ptr->tcam_entries) {
876a3c5bd6dSspeer 		alloc_size = fsize * classify_ptr->tcam_size;
877a3c5bd6dSspeer 		KMEM_FREE((void *) classify_ptr->tcam_entries, alloc_size);
87844961713Sgirish 	}
87944961713Sgirish 	nxgep->classifier.state = NULL;
88044961713Sgirish 
88144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw"));
88244961713Sgirish 	return (NXGE_OK);
88344961713Sgirish }
88444961713Sgirish 
88544961713Sgirish /*
88644961713Sgirish  * Figures out the location where the TCAM entry is
88744961713Sgirish  * to be inserted.
88844961713Sgirish  *
88944961713Sgirish  * The current implementation is just a place holder and it
89044961713Sgirish  * returns the next tcam location.
89144961713Sgirish  * The real location determining algorithm would consider
89244961713Sgirish  * the priority, partition etc ... before deciding which
89344961713Sgirish  * location to insert.
89444961713Sgirish  *
89544961713Sgirish  */
89644961713Sgirish 
8970a8e077aSspeer /* ARGSUSED */
89844961713Sgirish static tcam_location_t
89944961713Sgirish nxge_get_tcam_location(p_nxge_t nxgep, uint8_t class)
90044961713Sgirish {
90144961713Sgirish 	tcam_location_t location;
902a3c5bd6dSspeer 
90344961713Sgirish 	location = nxgep->classifier.tcam_location;
90444961713Sgirish 	nxgep->classifier.tcam_location = (location + nxgep->nports) %
905a3c5bd6dSspeer 		nxgep->classifier.tcam_size;
90644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
907a3c5bd6dSspeer 		"nxge_get_tcam_location: location %d next %d \n",
908a3c5bd6dSspeer 		location, nxgep->classifier.tcam_location));
90944961713Sgirish 	return (location);
91044961713Sgirish }
91144961713Sgirish 
91244961713Sgirish /*
91344961713Sgirish  * Figures out the RDC Group for the entry
91444961713Sgirish  *
91544961713Sgirish  * The current implementation is just a place holder and it
91644961713Sgirish  * returns 0.
91744961713Sgirish  * The real location determining algorithm would consider
91844961713Sgirish  * the partition etc ... before deciding w
91944961713Sgirish  *
92044961713Sgirish  */
921a3c5bd6dSspeer 
9220a8e077aSspeer /* ARGSUSED */
92344961713Sgirish static uint8_t
92444961713Sgirish nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, intptr_t cookie)
92544961713Sgirish {
92644961713Sgirish 	int use_port_rdc_grp = 0;
92744961713Sgirish 	uint8_t rdc_grp = 0;
928a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
929a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
930a3c5bd6dSspeer 	p_nxge_rdc_grp_t rdc_grp_p;
931a3c5bd6dSspeer 
93244961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
93344961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
93444961713Sgirish 	rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp];
935*678453a8Sspeer 	rdc_grp = p_cfgp->def_mac_rxdma_grpid;
936a3c5bd6dSspeer 
93744961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
938a3c5bd6dSspeer 		"nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
939a3c5bd6dSspeer 		cookie, rdc_grp, rdc_grp_p));
94044961713Sgirish 	return (rdc_grp);
94144961713Sgirish }
94244961713Sgirish 
94344961713Sgirish /* ARGSUSED */
94444961713Sgirish static uint8_t
94544961713Sgirish nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, intptr_t cookie)
94644961713Sgirish {
94744961713Sgirish 	return ((uint8_t)cookie);
94844961713Sgirish }
94944961713Sgirish 
9500a8e077aSspeer /* ARGSUSED */
95144961713Sgirish static void
95244961713Sgirish nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec,
953a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
95444961713Sgirish {
95544961713Sgirish 	udpip4_spec_t *fspec_key;
95644961713Sgirish 	udpip4_spec_t *fspec_mask;
95744961713Sgirish 
95844961713Sgirish 	fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec;
95944961713Sgirish 	fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec;
96044961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
96144961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
96244961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
96344961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
96444961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
965a3c5bd6dSspeer 		fspec_key->pdst, fspec_key->psrc);
96644961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
967a3c5bd6dSspeer 		fspec_mask->pdst, fspec_mask->psrc);
96844961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
969a3c5bd6dSspeer 		tcam_ptr->ip4_class_mask,
970a3c5bd6dSspeer 		TCAM_CLASS_UDP_IPV4);
97144961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
972a3c5bd6dSspeer 		tcam_ptr->ip4_proto_mask,
973a3c5bd6dSspeer 		IPPROTO_UDP);
97444961713Sgirish }
97544961713Sgirish 
97644961713Sgirish static void
97744961713Sgirish nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
978a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
97944961713Sgirish {
98044961713Sgirish 	udpip6_spec_t *fspec_key;
98144961713Sgirish 	udpip6_spec_t *fspec_mask;
982a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
98344961713Sgirish 
98444961713Sgirish 	fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec;
98544961713Sgirish 	fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec;
98644961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
98744961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
988a3c5bd6dSspeer 			NXGE_CLASS_TCAM_USE_SRC_ADDR) {
98944961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
99044961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
99144961713Sgirish 	} else {
99244961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
99344961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
99444961713Sgirish 	}
99544961713Sgirish 
99644961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
997a3c5bd6dSspeer 		tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6);
99844961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
999a3c5bd6dSspeer 		tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP);
100044961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
1001a3c5bd6dSspeer 		fspec_key->pdst, fspec_key->psrc);
100244961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
1003a3c5bd6dSspeer 		fspec_mask->pdst, fspec_mask->psrc);
100444961713Sgirish }
100544961713Sgirish 
10060a8e077aSspeer /* ARGSUSED */
100744961713Sgirish static void
100844961713Sgirish nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec,
1009a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
101044961713Sgirish {
101144961713Sgirish 	tcpip4_spec_t *fspec_key;
101244961713Sgirish 	tcpip4_spec_t *fspec_mask;
101344961713Sgirish 
101444961713Sgirish 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
101544961713Sgirish 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
101644961713Sgirish 
101744961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
101844961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
101944961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
102044961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
102144961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
1022a3c5bd6dSspeer 		fspec_key->pdst, fspec_key->psrc);
102344961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
1024a3c5bd6dSspeer 		fspec_mask->pdst, fspec_mask->psrc);
102544961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
1026a3c5bd6dSspeer 		tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4);
102744961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
1028a3c5bd6dSspeer 		tcam_ptr->ip4_proto_mask, IPPROTO_TCP);
102944961713Sgirish }
103044961713Sgirish 
10310a8e077aSspeer /* ARGSUSED */
103244961713Sgirish static void
103344961713Sgirish nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec,
1034a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
103544961713Sgirish {
103644961713Sgirish 	tcpip4_spec_t *fspec_key;
103744961713Sgirish 	tcpip4_spec_t *fspec_mask;
103844961713Sgirish 
103944961713Sgirish 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
104044961713Sgirish 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
104144961713Sgirish 
104244961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
104344961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
104444961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
104544961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
104644961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
1047a3c5bd6dSspeer 		tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4);
104844961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
1049a3c5bd6dSspeer 		tcam_ptr->ip4_proto_mask, IPPROTO_SCTP);
105044961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
1051a3c5bd6dSspeer 		fspec_key->pdst, fspec_key->psrc);
105244961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
1053a3c5bd6dSspeer 		fspec_mask->pdst, fspec_mask->psrc);
105444961713Sgirish }
105544961713Sgirish 
105644961713Sgirish static void
105744961713Sgirish nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1058a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
105944961713Sgirish {
106044961713Sgirish 	tcpip6_spec_t *fspec_key;
106144961713Sgirish 	tcpip6_spec_t *fspec_mask;
1062a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1063a3c5bd6dSspeer 
106444961713Sgirish 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
106544961713Sgirish 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
106644961713Sgirish 
106744961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
106844961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
1069a3c5bd6dSspeer 			NXGE_CLASS_TCAM_USE_SRC_ADDR) {
107044961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
107144961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
107244961713Sgirish 	} else {
107344961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
107444961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
107544961713Sgirish 	}
107644961713Sgirish 
107744961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
1078a3c5bd6dSspeer 		tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6);
107944961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
1080a3c5bd6dSspeer 		tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP);
108144961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
1082a3c5bd6dSspeer 		fspec_key->pdst, fspec_key->psrc);
108344961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
1084a3c5bd6dSspeer 		fspec_mask->pdst, fspec_mask->psrc);
108544961713Sgirish }
108644961713Sgirish 
108744961713Sgirish static void
108844961713Sgirish nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1089a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
109044961713Sgirish {
109144961713Sgirish 	tcpip6_spec_t *fspec_key;
109244961713Sgirish 	tcpip6_spec_t *fspec_mask;
1093a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
109444961713Sgirish 
109544961713Sgirish 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
109644961713Sgirish 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
109744961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
109844961713Sgirish 
109944961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
1100a3c5bd6dSspeer 			NXGE_CLASS_TCAM_USE_SRC_ADDR) {
110144961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
110244961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
110344961713Sgirish 	} else {
110444961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
110544961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
110644961713Sgirish 	}
110744961713Sgirish 
110844961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
1109a3c5bd6dSspeer 		tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6);
111044961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
1111a3c5bd6dSspeer 		tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP);
111244961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
1113a3c5bd6dSspeer 		fspec_key->pdst, fspec_key->psrc);
111444961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
1115a3c5bd6dSspeer 		fspec_mask->pdst, fspec_mask->psrc);
111644961713Sgirish }
111744961713Sgirish 
111844961713Sgirish nxge_status_t
111944961713Sgirish nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res,
1120a3c5bd6dSspeer 	uint32_t *H1, uint16_t *H2)
112144961713Sgirish {
112244961713Sgirish 	flow_spec_t *flow_spec;
112344961713Sgirish 	uint32_t class_cfg;
112444961713Sgirish 	flow_template_t ft;
1125a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
112644961713Sgirish 
112744961713Sgirish 	int ft_size = sizeof (flow_template_t);
1128a3c5bd6dSspeer 
112944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash"));
113044961713Sgirish 
113144961713Sgirish 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
113244961713Sgirish 	bzero((char *)&ft, ft_size);
113344961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1134a3c5bd6dSspeer 
113544961713Sgirish 	switch (flow_spec->flow_type) {
1136a3c5bd6dSspeer 	case FSPEC_TCPIP4:
1137a3c5bd6dSspeer 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4];
1138a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1139a3c5bd6dSspeer 			ft.ip_proto = IPPROTO_TCP;
1140a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1141a3c5bd6dSspeer 			ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src;
1142a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1143a3c5bd6dSspeer 			ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst;
1144a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1145a3c5bd6dSspeer 			ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc;
1146a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1147a3c5bd6dSspeer 			ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst;
1148a3c5bd6dSspeer 		break;
1149a3c5bd6dSspeer 
1150a3c5bd6dSspeer 	case FSPEC_UDPIP4:
1151a3c5bd6dSspeer 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4];
1152a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1153a3c5bd6dSspeer 			ft.ip_proto = IPPROTO_UDP;
1154a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1155a3c5bd6dSspeer 			ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src;
1156a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1157a3c5bd6dSspeer 			ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst;
1158a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1159a3c5bd6dSspeer 			ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc;
1160a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1161a3c5bd6dSspeer 			ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst;
1162a3c5bd6dSspeer 		break;
1163a3c5bd6dSspeer 
1164a3c5bd6dSspeer 	default:
1165a3c5bd6dSspeer 		return (NXGE_ERROR);
116644961713Sgirish 	}
116744961713Sgirish 
116844961713Sgirish 	*H1 = nxge_compute_h1(p_class_cfgp->init_h1,
1169a3c5bd6dSspeer 		(uint32_t *)&ft, ft_size) & 0xfffff;
117044961713Sgirish 	*H2 = nxge_compute_h2(p_class_cfgp->init_h2,
1171a3c5bd6dSspeer 		(uint8_t *)&ft, ft_size);
117244961713Sgirish 
117344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash"));
117444961713Sgirish 	return (NXGE_OK);
117544961713Sgirish }
117644961713Sgirish 
117744961713Sgirish nxge_status_t
117844961713Sgirish nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
117944961713Sgirish {
118044961713Sgirish 	uint32_t H1;
118144961713Sgirish 	uint16_t H2;
118244961713Sgirish 	nxge_status_t status = NXGE_OK;
118344961713Sgirish 
118444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry"));
118544961713Sgirish 	status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2);
118644961713Sgirish 	if (status != NXGE_OK) {
118744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1188a3c5bd6dSspeer 			" nxge_add_fcram_entry failed "));
118944961713Sgirish 		return (status);
119044961713Sgirish 	}
119144961713Sgirish 
119244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry"));
119344961713Sgirish 	return (NXGE_OK);
119444961713Sgirish }
119544961713Sgirish 
119644961713Sgirish /*
119744961713Sgirish  * Already decided this flow goes into the tcam
119844961713Sgirish  */
119944961713Sgirish 
120044961713Sgirish nxge_status_t
120144961713Sgirish nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
120244961713Sgirish {
120344961713Sgirish 	npi_handle_t handle;
120444961713Sgirish 	intptr_t channel_cookie;
120544961713Sgirish 	intptr_t flow_cookie;
120644961713Sgirish 	flow_spec_t *flow_spec;
120744961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
120844961713Sgirish 	tcam_entry_t tcam_ptr;
120944961713Sgirish 	tcam_location_t location = 0;
121044961713Sgirish 	uint8_t offset, rdc_grp;
1211a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
121244961713Sgirish 
121344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry"));
121444961713Sgirish 	handle = nxgep->npi_reg_handle;
121544961713Sgirish 
1216a3c5bd6dSspeer 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
121744961713Sgirish 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
121844961713Sgirish 	flow_cookie = flow_res->flow_cookie;
121944961713Sgirish 	channel_cookie = flow_res->channel_cookie;
122044961713Sgirish 
122144961713Sgirish 	switch (flow_spec->flow_type) {
1222a3c5bd6dSspeer 	case FSPEC_TCPIP4:
1223a3c5bd6dSspeer 		nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr);
1224a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1225a3c5bd6dSspeer 			TCAM_CLASS_TCP_IPV4);
1226a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4,
1227a3c5bd6dSspeer 			flow_cookie);
1228a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4,
1229a3c5bd6dSspeer 			channel_cookie);
1230a3c5bd6dSspeer 		break;
1231a3c5bd6dSspeer 
1232a3c5bd6dSspeer 	case FSPEC_UDPIP4:
1233a3c5bd6dSspeer 		nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr);
1234a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1235a3c5bd6dSspeer 			TCAM_CLASS_UDP_IPV4);
1236a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
1237a3c5bd6dSspeer 			TCAM_CLASS_UDP_IPV4,
1238a3c5bd6dSspeer 			flow_cookie);
1239a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
1240a3c5bd6dSspeer 			TCAM_CLASS_UDP_IPV4,
1241a3c5bd6dSspeer 			channel_cookie);
1242a3c5bd6dSspeer 		break;
1243a3c5bd6dSspeer 
1244a3c5bd6dSspeer 	case FSPEC_TCPIP6:
1245a3c5bd6dSspeer 		nxge_fill_tcam_entry_tcp_ipv6(nxgep,
1246a3c5bd6dSspeer 			flow_spec, &tcam_ptr);
1247a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1248a3c5bd6dSspeer 			TCAM_CLASS_TCP_IPV6);
1249a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6,
1250a3c5bd6dSspeer 			flow_cookie);
1251a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6,
1252a3c5bd6dSspeer 			channel_cookie);
1253a3c5bd6dSspeer 		break;
1254a3c5bd6dSspeer 
1255a3c5bd6dSspeer 	case FSPEC_UDPIP6:
1256a3c5bd6dSspeer 		nxge_fill_tcam_entry_udp_ipv6(nxgep,
1257a3c5bd6dSspeer 			flow_spec, &tcam_ptr);
1258a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1259a3c5bd6dSspeer 			TCAM_CLASS_UDP_IPV6);
1260a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
1261a3c5bd6dSspeer 			TCAM_CLASS_UDP_IPV6,
1262a3c5bd6dSspeer 			channel_cookie);
1263a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
1264a3c5bd6dSspeer 			TCAM_CLASS_UDP_IPV6,
1265a3c5bd6dSspeer 			flow_cookie);
1266a3c5bd6dSspeer 		break;
1267a3c5bd6dSspeer 
1268a3c5bd6dSspeer 	case FSPEC_SCTPIP4:
1269a3c5bd6dSspeer 		nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr);
1270a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1271a3c5bd6dSspeer 			TCAM_CLASS_SCTP_IPV4);
1272a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
1273a3c5bd6dSspeer 			TCAM_CLASS_SCTP_IPV4,
1274a3c5bd6dSspeer 			channel_cookie);
1275a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
1276a3c5bd6dSspeer 			TCAM_CLASS_SCTP_IPV4,
1277a3c5bd6dSspeer 			flow_cookie);
1278a3c5bd6dSspeer 		break;
1279a3c5bd6dSspeer 
1280a3c5bd6dSspeer 	case FSPEC_SCTPIP6:
1281a3c5bd6dSspeer 		nxge_fill_tcam_entry_sctp_ipv6(nxgep,
1282a3c5bd6dSspeer 			flow_spec, &tcam_ptr);
1283a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1284a3c5bd6dSspeer 			TCAM_CLASS_SCTP_IPV4);
1285a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
1286a3c5bd6dSspeer 			TCAM_CLASS_SCTP_IPV6,
1287a3c5bd6dSspeer 			channel_cookie);
1288a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
1289a3c5bd6dSspeer 			TCAM_CLASS_SCTP_IPV6,
1290a3c5bd6dSspeer 			flow_cookie);
1291a3c5bd6dSspeer 		break;
1292a3c5bd6dSspeer 
1293a3c5bd6dSspeer 	default:
1294a3c5bd6dSspeer 		return (NXGE_OK);
129544961713Sgirish 	}
129644961713Sgirish 
129744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1298a3c5bd6dSspeer 		" nxge_add_tcam_entry write"
1299a3c5bd6dSspeer 		" for location %d offset %d", location, offset));
130044961713Sgirish 
130144961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
130244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1303a3c5bd6dSspeer 			" nxge_add_tcam_entry: common hardware not set",
130444961713Sgirish 			nxgep->niu_type));
130544961713Sgirish 		return (NXGE_ERROR);
130644961713Sgirish 	}
1307a3c5bd6dSspeer 
130844961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
1309a3c5bd6dSspeer 	rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr);
131044961713Sgirish 
131144961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
131244961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
131344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1314a3c5bd6dSspeer 			" nxge_add_tcam_entry write"
1315a3c5bd6dSspeer 			" failed for location %d", location));
131644961713Sgirish 		return (NXGE_ERROR | rs);
131744961713Sgirish 	}
1318a3c5bd6dSspeer 
131944961713Sgirish 	tcam_ptr.match_action.value = 0;
132044961713Sgirish 	tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp;
132144961713Sgirish 	tcam_ptr.match_action.bits.ldw.offset = offset;
132244961713Sgirish 	tcam_ptr.match_action.bits.ldw.tres =
132344961713Sgirish 		TRES_TERM_OVRD_L2RDC;
132444961713Sgirish 	if (channel_cookie == -1)
132544961713Sgirish 		tcam_ptr.match_action.bits.ldw.disc = 1;
132644961713Sgirish 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
1327a3c5bd6dSspeer 		location, tcam_ptr.match_action.value);
132844961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
132944961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
133044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1331a3c5bd6dSspeer 			" nxge_add_tcam_entry write"
1332a3c5bd6dSspeer 			" failed for ASC RAM location %d", location));
133344961713Sgirish 		return (NXGE_ERROR | rs);
133444961713Sgirish 	}
1335a3c5bd6dSspeer 	bcopy((void *) &tcam_ptr,
1336a3c5bd6dSspeer 		(void *) &nxgep->classifier.tcam_entries[location].tce,
1337a3c5bd6dSspeer 		sizeof (tcam_entry_t));
133844961713Sgirish 
133944961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
134044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry"));
134144961713Sgirish 	return (NXGE_OK);
134244961713Sgirish }
134344961713Sgirish 
134414ea4bb7Ssd static nxge_status_t
134514ea4bb7Ssd nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)
134644961713Sgirish {
134744961713Sgirish 	tcam_entry_t tcam_ptr;
134844961713Sgirish 	tcam_location_t location;
134944961713Sgirish 	uint8_t class;
135014ea4bb7Ssd 	uint32_t class_config;
135144961713Sgirish 	npi_handle_t handle;
135244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1353a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
135414ea4bb7Ssd 	nxge_status_t status = NXGE_OK;
135544961713Sgirish 
135644961713Sgirish 	handle = nxgep->npi_reg_handle;
135744961713Sgirish 	class = 0;
1358a3c5bd6dSspeer 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
135944961713Sgirish 	tcam_ptr.ip4_noport_key = 1;
136044961713Sgirish 	tcam_ptr.ip4_noport_mask = 1;
136114ea4bb7Ssd 	location = nxgep->function_num;
136244961713Sgirish 	nxgep->classifier.fragment_bug_location = location;
136344961713Sgirish 
136444961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
136544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
136614ea4bb7Ssd 			" nxge_tcam_handle_ip_fragment:"
136744961713Sgirish 			" common hardware not set",
136844961713Sgirish 			nxgep->niu_type));
136914ea4bb7Ssd 		return (NXGE_ERROR);
137044961713Sgirish 	}
137144961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
137244961713Sgirish 	rs = npi_fflp_tcam_entry_write(handle,
1373a3c5bd6dSspeer 		location, &tcam_ptr);
137444961713Sgirish 
137544961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
137644961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
137744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1378a3c5bd6dSspeer 			" nxge_tcam_handle_ip_fragment "
1379a3c5bd6dSspeer 			" tcam_entry write"
1380a3c5bd6dSspeer 			" failed for location %d", location));
138114ea4bb7Ssd 		return (NXGE_ERROR);
138244961713Sgirish 	}
138344961713Sgirish 	tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp;
1384a3c5bd6dSspeer 	tcam_ptr.match_action.bits.ldw.offset = 0;	/* use the default */
138544961713Sgirish 	tcam_ptr.match_action.bits.ldw.tres =
138644961713Sgirish 		TRES_TERM_USE_OFFSET;
138744961713Sgirish 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
1388a3c5bd6dSspeer 		location, tcam_ptr.match_action.value);
138944961713Sgirish 
139044961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
139144961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
139244961713Sgirish 		NXGE_DEBUG_MSG((nxgep,
1393a3c5bd6dSspeer 			FFLP_CTL,
1394a3c5bd6dSspeer 			" nxge_tcam_handle_ip_fragment "
1395a3c5bd6dSspeer 			" tcam_entry write"
1396a3c5bd6dSspeer 			" failed for ASC RAM location %d", location));
139714ea4bb7Ssd 		return (NXGE_ERROR);
139844961713Sgirish 	}
1399a3c5bd6dSspeer 	bcopy((void *) &tcam_ptr,
1400a3c5bd6dSspeer 		(void *) &nxgep->classifier.tcam_entries[location].tce,
1401a3c5bd6dSspeer 		sizeof (tcam_entry_t));
140214ea4bb7Ssd 	for (class = TCAM_CLASS_TCP_IPV4;
1403a3c5bd6dSspeer 		class <= TCAM_CLASS_SCTP_IPV6; class++) {
140414ea4bb7Ssd 		class_config = nxgep->class_config.class_cfg[class];
140514ea4bb7Ssd 		class_config |= NXGE_CLASS_TCAM_LOOKUP;
140614ea4bb7Ssd 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
140714ea4bb7Ssd 
140814ea4bb7Ssd 		if (status & NPI_FFLP_ERROR) {
140914ea4bb7Ssd 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
141014ea4bb7Ssd 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1411a3c5bd6dSspeer 				"nxge_tcam_handle_ip_fragment "
1412a3c5bd6dSspeer 				"nxge_fflp_ip_class_config failed "
1413a3c5bd6dSspeer 				" class %d config %x ", class, class_config));
141414ea4bb7Ssd 			return (NXGE_ERROR);
141514ea4bb7Ssd 		}
141614ea4bb7Ssd 	}
141714ea4bb7Ssd 
141814ea4bb7Ssd 	rs = npi_fflp_cfg_tcam_enable(handle);
141914ea4bb7Ssd 	if (rs & NPI_FFLP_ERROR) {
142014ea4bb7Ssd 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
142114ea4bb7Ssd 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1422a3c5bd6dSspeer 			"nxge_tcam_handle_ip_fragment "
1423a3c5bd6dSspeer 			" nxge_fflp_config_tcam_enable failed"));
142414ea4bb7Ssd 		return (NXGE_ERROR);
142514ea4bb7Ssd 	}
142644961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
142714ea4bb7Ssd 	return (NXGE_OK);
142844961713Sgirish }
142944961713Sgirish 
143044961713Sgirish /* ARGSUSED */
143144961713Sgirish static int
1432a3c5bd6dSspeer nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res)
143344961713Sgirish {
143444961713Sgirish 	return (0);
143544961713Sgirish }
143644961713Sgirish 
143744961713Sgirish nxge_status_t
143844961713Sgirish nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res)
143944961713Sgirish {
144044961713Sgirish 
144144961713Sgirish 	int insert_hash = 0;
144244961713Sgirish 	nxge_status_t status = NXGE_OK;
144344961713Sgirish 
14442e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
1445a3c5bd6dSspeer 		/* determine whether to do TCAM or Hash flow */
144644961713Sgirish 		insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res);
144744961713Sgirish 	}
144844961713Sgirish 	if (insert_hash) {
144944961713Sgirish 		status = nxge_add_fcram_entry(nxgep, flow_res);
145044961713Sgirish 	} else {
145144961713Sgirish 		status = nxge_add_tcam_entry(nxgep, flow_res);
145244961713Sgirish 	}
145344961713Sgirish 	return (status);
145444961713Sgirish }
145544961713Sgirish 
145644961713Sgirish void
145744961713Sgirish nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp)
145844961713Sgirish {
145944961713Sgirish 	flow_resource_t *fs;
146044961713Sgirish 
1461a3c5bd6dSspeer 	fs = (flow_resource_t *)mp->b_rptr;
146244961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1463a3c5bd6dSspeer 		"nxge_put_tcam addr fs $%p  type %x offset %x",
1464a3c5bd6dSspeer 		fs, fs->flow_spec.flow_type, fs->channel_cookie));
146544961713Sgirish 	(void) nxge_add_tcam_entry(nxgep, fs);
146644961713Sgirish }
146744961713Sgirish 
146844961713Sgirish nxge_status_t
146944961713Sgirish nxge_fflp_config_tcam_enable(p_nxge_t nxgep)
147044961713Sgirish {
147144961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
147244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
147344961713Sgirish 
147444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable"));
147544961713Sgirish 	rs = npi_fflp_cfg_tcam_enable(handle);
147644961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
147744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1478a3c5bd6dSspeer 			" nxge_fflp_config_tcam_enable failed"));
147944961713Sgirish 		return (NXGE_ERROR | rs);
148044961713Sgirish 	}
148144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable"));
148244961713Sgirish 	return (NXGE_OK);
148344961713Sgirish }
148444961713Sgirish 
148544961713Sgirish nxge_status_t
148644961713Sgirish nxge_fflp_config_tcam_disable(p_nxge_t nxgep)
148744961713Sgirish {
148844961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
148944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
149044961713Sgirish 
149144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1492a3c5bd6dSspeer 		" ==> nxge_fflp_config_tcam_disable"));
149344961713Sgirish 	rs = npi_fflp_cfg_tcam_disable(handle);
149444961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
149544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1496a3c5bd6dSspeer 				" nxge_fflp_config_tcam_disable failed"));
149744961713Sgirish 		return (NXGE_ERROR | rs);
149844961713Sgirish 	}
149944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1500a3c5bd6dSspeer 		" <== nxge_fflp_config_tcam_disable"));
150144961713Sgirish 	return (NXGE_OK);
150244961713Sgirish }
150344961713Sgirish 
150444961713Sgirish nxge_status_t
150544961713Sgirish nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)
150644961713Sgirish {
150744961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
150844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1509a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1510a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1511a3c5bd6dSspeer 	uint8_t partition;
151244961713Sgirish 
151344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1514a3c5bd6dSspeer 		" ==> nxge_fflp_config_hash_lookup_enable"));
151544961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
151644961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
151744961713Sgirish 
1518*678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1519*678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
1520*678453a8Sspeer 			rs = npi_fflp_cfg_fcram_partition_enable(
1521*678453a8Sspeer 				handle, partition);
1522*678453a8Sspeer 			if (rs != NPI_SUCCESS) {
1523*678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1524*678453a8Sspeer 				    " nxge_fflp_config_hash_lookup_enable"
1525*678453a8Sspeer 				    "failed FCRAM partition"
1526*678453a8Sspeer 				    " enable for partition %d ", partition));
1527*678453a8Sspeer 				return (NXGE_ERROR | rs);
1528*678453a8Sspeer 			}
152944961713Sgirish 		}
153044961713Sgirish 	}
153144961713Sgirish 
153244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1533a3c5bd6dSspeer 		" <== nxge_fflp_config_hash_lookup_enable"));
153444961713Sgirish 	return (NXGE_OK);
153544961713Sgirish }
153644961713Sgirish 
153744961713Sgirish nxge_status_t
153844961713Sgirish nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)
153944961713Sgirish {
154044961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
154144961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1542a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1543a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1544a3c5bd6dSspeer 	uint8_t partition;
154544961713Sgirish 
154644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1547a3c5bd6dSspeer 		" ==> nxge_fflp_config_hash_lookup_disable"));
154844961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
154944961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
155044961713Sgirish 
1551*678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1552*678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
1553*678453a8Sspeer 			rs = npi_fflp_cfg_fcram_partition_disable(handle,
1554*678453a8Sspeer 			    partition);
1555*678453a8Sspeer 			if (rs != NPI_SUCCESS) {
1556*678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1557*678453a8Sspeer 				    " nxge_fflp_config_hash_lookup_disable"
1558*678453a8Sspeer 				    " failed FCRAM partition"
1559*678453a8Sspeer 				    " disable for partition %d ", partition));
1560*678453a8Sspeer 				return (NXGE_ERROR | rs);
1561*678453a8Sspeer 			}
156244961713Sgirish 		}
156344961713Sgirish 	}
156444961713Sgirish 
156544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1566a3c5bd6dSspeer 		" <== nxge_fflp_config_hash_lookup_disable"));
156744961713Sgirish 	return (NXGE_OK);
156844961713Sgirish }
156944961713Sgirish 
157044961713Sgirish nxge_status_t
157144961713Sgirish nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)
157244961713Sgirish {
157344961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
157444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
157544961713Sgirish 
157644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1577a3c5bd6dSspeer 		" ==> nxge_fflp_config_llc_snap_enable"));
157844961713Sgirish 	rs = npi_fflp_cfg_llcsnap_enable(handle);
157944961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
158044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1581a3c5bd6dSspeer 			" nxge_fflp_config_llc_snap_enable failed"));
158244961713Sgirish 		return (NXGE_ERROR | rs);
158344961713Sgirish 	}
158444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1585a3c5bd6dSspeer 		" <== nxge_fflp_config_llc_snap_enable"));
158644961713Sgirish 	return (NXGE_OK);
158744961713Sgirish }
158844961713Sgirish 
158944961713Sgirish nxge_status_t
159044961713Sgirish nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)
159144961713Sgirish {
159244961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
159344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1594a3c5bd6dSspeer 
159544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1596a3c5bd6dSspeer 		" ==> nxge_fflp_config_llc_snap_disable"));
159744961713Sgirish 	rs = npi_fflp_cfg_llcsnap_disable(handle);
159844961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
159944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1600a3c5bd6dSspeer 			" nxge_fflp_config_llc_snap_disable failed"));
160144961713Sgirish 		return (NXGE_ERROR | rs);
160244961713Sgirish 	}
160344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1604a3c5bd6dSspeer 		" <== nxge_fflp_config_llc_snap_disable"));
160544961713Sgirish 	return (NXGE_OK);
160644961713Sgirish }
160744961713Sgirish 
160844961713Sgirish nxge_status_t
160944961713Sgirish nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class,
1610a3c5bd6dSspeer 	uint32_t config)
161144961713Sgirish {
161244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
161344961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
161444961713Sgirish 	uint8_t tos, tos_mask, proto, ver = 0;
161544961713Sgirish 	uint8_t class_enable = 0;
161644961713Sgirish 
161744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config"));
161844961713Sgirish 
161944961713Sgirish 	tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >>
1620a3c5bd6dSspeer 		NXGE_CLASS_CFG_IP_TOS_SHIFT;
162144961713Sgirish 	tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >>
162244961713Sgirish 		NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT;
162344961713Sgirish 	proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >>
162444961713Sgirish 		NXGE_CLASS_CFG_IP_PROTO_SHIFT;
162544961713Sgirish 	if (config & NXGE_CLASS_CFG_IP_IPV6_MASK)
162644961713Sgirish 		ver = 1;
162744961713Sgirish 	if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK)
162844961713Sgirish 		class_enable = 1;
162944961713Sgirish 	rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask,
1630a3c5bd6dSspeer 		proto, ver);
163144961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
163244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
163344961713Sgirish 			" nxge_fflp_ip_usr_class_config"
163444961713Sgirish 			" for class %d failed ", class));
163544961713Sgirish 		return (NXGE_ERROR | rs);
163644961713Sgirish 	}
163744961713Sgirish 	if (class_enable)
163844961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class);
163944961713Sgirish 	else
164044961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
164144961713Sgirish 
164244961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
164344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1644a3c5bd6dSspeer 			" nxge_fflp_ip_usr_class_config"
1645a3c5bd6dSspeer 			" TCAM enable/disable for class %d failed ", class));
164644961713Sgirish 		return (NXGE_ERROR | rs);
164744961713Sgirish 	}
164844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config"));
164944961713Sgirish 	return (NXGE_OK);
165044961713Sgirish }
165144961713Sgirish 
165244961713Sgirish nxge_status_t
1653a3c5bd6dSspeer nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config)
165444961713Sgirish {
165544961713Sgirish 	uint32_t class_config;
165644961713Sgirish 	nxge_status_t t_status = NXGE_OK;
165744961713Sgirish 	nxge_status_t f_status = NXGE_OK;
1658a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
165944961713Sgirish 
166044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
1661a3c5bd6dSspeer 
166244961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
166344961713Sgirish 	class_config = p_class_cfgp->class_cfg[class];
166444961713Sgirish 
166544961713Sgirish 	if (class_config != config) {
166644961713Sgirish 		p_class_cfgp->class_cfg[class] = config;
166744961713Sgirish 		class_config = config;
166844961713Sgirish 	}
166944961713Sgirish 
167044961713Sgirish 	t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config);
167144961713Sgirish 	f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config);
167244961713Sgirish 
167344961713Sgirish 	if (t_status & NPI_FFLP_ERROR) {
167444961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1675a3c5bd6dSspeer 			" nxge_fflp_ip_class_config %x"
1676a3c5bd6dSspeer 			" for class %d tcam failed", config, class));
167744961713Sgirish 		return (t_status);
167844961713Sgirish 	}
167944961713Sgirish 	if (f_status & NPI_FFLP_ERROR) {
168044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1681a3c5bd6dSspeer 			" nxge_fflp_ip_class_config %x"
1682a3c5bd6dSspeer 			" for class %d flow key failed", config, class));
168344961713Sgirish 		return (f_status);
168444961713Sgirish 	}
168544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
168644961713Sgirish 	return (NXGE_OK);
168744961713Sgirish }
168844961713Sgirish 
168944961713Sgirish nxge_status_t
169044961713Sgirish nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class,
1691a3c5bd6dSspeer 	uint32_t *config)
169244961713Sgirish {
169344961713Sgirish 	uint32_t t_class_config, f_class_config;
169444961713Sgirish 	int t_status = NXGE_OK;
169544961713Sgirish 	int f_status = NXGE_OK;
169644961713Sgirish 
169744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
1698a3c5bd6dSspeer 
169944961713Sgirish 	t_class_config = f_class_config = 0;
170044961713Sgirish 	t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config);
170144961713Sgirish 	f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config);
170244961713Sgirish 
170344961713Sgirish 	if (t_status & NPI_FFLP_ERROR) {
170444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1705a3c5bd6dSspeer 			" nxge_fflp_ip_class_config_get  "
1706a3c5bd6dSspeer 			" for class %d tcam failed", class));
170744961713Sgirish 		return (t_status);
170844961713Sgirish 	}
170944961713Sgirish 
171044961713Sgirish 	if (f_status & NPI_FFLP_ERROR) {
171144961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1712a3c5bd6dSspeer 			" nxge_fflp_ip_class_config_get  "
1713a3c5bd6dSspeer 			" for class %d flow key failed", class));
171444961713Sgirish 		return (f_status);
171544961713Sgirish 	}
171644961713Sgirish 
171744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1718a3c5bd6dSspeer 		" nxge_fflp_ip_class_config tcam %x flow %x",
1719a3c5bd6dSspeer 		t_class_config, f_class_config));
172044961713Sgirish 
172144961713Sgirish 	*config = t_class_config | f_class_config;
172244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get"));
172344961713Sgirish 	return (NXGE_OK);
172444961713Sgirish }
172544961713Sgirish 
172644961713Sgirish nxge_status_t
172744961713Sgirish nxge_fflp_ip_class_config_all(p_nxge_t nxgep)
172844961713Sgirish {
172944961713Sgirish 	uint32_t class_config;
173044961713Sgirish 	tcam_class_t class;
173144961713Sgirish 
173244961713Sgirish #ifdef	NXGE_DEBUG
173344961713Sgirish 	int status = NXGE_OK;
173444961713Sgirish #endif
173544961713Sgirish 
173644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config"));
173744961713Sgirish 	for (class = TCAM_CLASS_TCP_IPV4;
1738a3c5bd6dSspeer 		class <= TCAM_CLASS_SCTP_IPV6; class++) {
173944961713Sgirish 		class_config = nxgep->class_config.class_cfg[class];
174044961713Sgirish #ifndef	NXGE_DEBUG
174144961713Sgirish 		(void) nxge_fflp_ip_class_config(nxgep, class, class_config);
174244961713Sgirish #else
174344961713Sgirish 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
174444961713Sgirish 		if (status & NPI_FFLP_ERROR) {
174544961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1746a3c5bd6dSspeer 				"nxge_fflp_ip_class_config failed "
1747a3c5bd6dSspeer 				" class %d config %x ",
1748a3c5bd6dSspeer 				class, class_config));
174944961713Sgirish 		}
175044961713Sgirish #endif
175144961713Sgirish 	}
175244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
175344961713Sgirish 	return (NXGE_OK);
175444961713Sgirish }
175544961713Sgirish 
175644961713Sgirish nxge_status_t
175744961713Sgirish nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id)
175844961713Sgirish {
175944961713Sgirish 	uint8_t port, rdc_grp;
176044961713Sgirish 	npi_handle_t handle;
176144961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
176244961713Sgirish 	uint8_t priority = 1;
176344961713Sgirish 	p_nxge_mv_cfg_t vlan_table;
1764a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1765a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
176644961713Sgirish 
176744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table"));
176844961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
176944961713Sgirish 	handle = nxgep->npi_reg_handle;
177044961713Sgirish 	vlan_table = p_class_cfgp->vlan_tbl;
177144961713Sgirish 	port = nxgep->function_num;
177244961713Sgirish 
177344961713Sgirish 	if (vlan_table[vlan_id].flag == 0) {
177444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1775a3c5bd6dSspeer 			" nxge_fflp_config_vlan_table"
1776a3c5bd6dSspeer 			" vlan id is not configured %d", vlan_id));
177744961713Sgirish 		return (NXGE_ERROR);
177844961713Sgirish 	}
177944961713Sgirish 
178044961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
178144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
178244961713Sgirish 			" nxge_fflp_config_vlan_table:"
1783a3c5bd6dSspeer 			" common hardware not set", nxgep->niu_type));
178444961713Sgirish 		return (NXGE_ERROR);
178544961713Sgirish 	}
178644961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_vlan_lock);
178744961713Sgirish 	rdc_grp = vlan_table[vlan_id].rdctbl;
178844961713Sgirish 	rs = npi_fflp_cfg_enet_vlan_table_assoc(handle,
1789a3c5bd6dSspeer 		port, vlan_id,
1790a3c5bd6dSspeer 		rdc_grp, priority);
179144961713Sgirish 
179244961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_vlan_lock);
179344961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
179444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1795a3c5bd6dSspeer 			"nxge_fflp_config_vlan_table failed "
1796a3c5bd6dSspeer 			" Port %d vlan_id %d rdc_grp %d",
1797a3c5bd6dSspeer 			port, vlan_id, rdc_grp));
179844961713Sgirish 		return (NXGE_ERROR | rs);
179944961713Sgirish 	}
1800a3c5bd6dSspeer 
180144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table"));
180244961713Sgirish 	return (NXGE_OK);
180344961713Sgirish }
180444961713Sgirish 
180544961713Sgirish nxge_status_t
180644961713Sgirish nxge_fflp_update_hw(p_nxge_t nxgep)
180744961713Sgirish {
180844961713Sgirish 	nxge_status_t status = NXGE_OK;
180944961713Sgirish 	p_nxge_param_t pa;
181044961713Sgirish 	uint64_t cfgd_vlans;
181144961713Sgirish 	uint64_t *val_ptr;
181244961713Sgirish 	int i;
181344961713Sgirish 	int num_macs;
181444961713Sgirish 	uint8_t alt_mac;
181544961713Sgirish 	nxge_param_map_t *p_map;
181644961713Sgirish 	p_nxge_mv_cfg_t vlan_table;
1817a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1818a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_all_cfgp;
1819a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
182044961713Sgirish 
182144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw"));
1822a3c5bd6dSspeer 
182344961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
182444961713Sgirish 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
182544961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
182644961713Sgirish 
182744961713Sgirish 	status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1);
182844961713Sgirish 	if (status != NXGE_OK) {
182944961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1830a3c5bd6dSspeer 			"nxge_fflp_set_hash1 Failed"));
183144961713Sgirish 		return (NXGE_ERROR);
183244961713Sgirish 	}
183344961713Sgirish 
183444961713Sgirish 	status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2);
183544961713Sgirish 	if (status != NXGE_OK) {
183644961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1837a3c5bd6dSspeer 			"nxge_fflp_set_hash2 Failed"));
183844961713Sgirish 		return (NXGE_ERROR);
183944961713Sgirish 	}
184044961713Sgirish 	vlan_table = p_class_cfgp->vlan_tbl;
184144961713Sgirish 
1842a3c5bd6dSspeer 	/* configure vlan tables */
184344961713Sgirish 	pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp];
1844adfcba55Sjoycey #if defined(__i386)
1845adfcba55Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
1846adfcba55Sjoycey #else
184744961713Sgirish 	val_ptr = (uint64_t *)pa->value;
1848adfcba55Sjoycey #endif
1849a3c5bd6dSspeer 	cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >>
1850a3c5bd6dSspeer 		NXGE_PARAM_ARRAY_CNT_SHIFT);
185144961713Sgirish 
185244961713Sgirish 	for (i = 0; i < cfgd_vlans; i++) {
185344961713Sgirish 		p_map = (nxge_param_map_t *)&val_ptr[i];
185444961713Sgirish 		if (vlan_table[p_map->param_id].flag) {
185544961713Sgirish 			status = nxge_fflp_config_vlan_table(nxgep,
1856a3c5bd6dSspeer 				p_map->param_id);
185744961713Sgirish 			if (status != NXGE_OK) {
185844961713Sgirish 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1859a3c5bd6dSspeer 					"nxge_fflp_config_vlan_table Failed"));
186044961713Sgirish 				return (NXGE_ERROR);
186144961713Sgirish 			}
186244961713Sgirish 		}
186344961713Sgirish 	}
1864a3c5bd6dSspeer 
1865a3c5bd6dSspeer 	/* config MAC addresses */
186644961713Sgirish 	num_macs = p_cfgp->max_macs;
186744961713Sgirish 	pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp];
1868adfcba55Sjoycey #if defined(__i386)
1869adfcba55Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
1870adfcba55Sjoycey #else
187144961713Sgirish 	val_ptr = (uint64_t *)pa->value;
1872adfcba55Sjoycey #endif
187344961713Sgirish 
187444961713Sgirish 	for (alt_mac = 0; alt_mac < num_macs; alt_mac++) {
187544961713Sgirish 		if (p_class_cfgp->mac_host_info[alt_mac].flag) {
187644961713Sgirish 			status = nxge_logical_mac_assign_rdc_table(nxgep,
1877a3c5bd6dSspeer 				alt_mac);
187844961713Sgirish 			if (status != NXGE_OK) {
187944961713Sgirish 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1880a3c5bd6dSspeer 					"nxge_logical_mac_assign_rdc_table"
1881a3c5bd6dSspeer 					" Failed"));
188244961713Sgirish 				return (NXGE_ERROR);
188344961713Sgirish 			}
188444961713Sgirish 		}
188544961713Sgirish 	}
1886a3c5bd6dSspeer 
1887a3c5bd6dSspeer 	/* Config Hash values */
1888f6485eecSyc 	/* config classes */
188944961713Sgirish 	status = nxge_fflp_ip_class_config_all(nxgep);
189044961713Sgirish 	if (status != NXGE_OK) {
189144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1892a3c5bd6dSspeer 			"nxge_fflp_ip_class_config_all Failed"));
189344961713Sgirish 		return (NXGE_ERROR);
189444961713Sgirish 	}
189544961713Sgirish 	return (NXGE_OK);
189644961713Sgirish }
189744961713Sgirish 
189844961713Sgirish nxge_status_t
189944961713Sgirish nxge_classify_init_hw(p_nxge_t nxgep)
190044961713Sgirish {
190144961713Sgirish 	nxge_status_t status = NXGE_OK;
190244961713Sgirish 
190344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw"));
190444961713Sgirish 
190544961713Sgirish 	if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) {
190644961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1907a3c5bd6dSspeer 			"nxge_classify_init_hw already init"));
190844961713Sgirish 		return (NXGE_OK);
190944961713Sgirish 	}
191044961713Sgirish 
1911a3c5bd6dSspeer 	/* Now do a real configuration */
191244961713Sgirish 	status = nxge_fflp_update_hw(nxgep);
191344961713Sgirish 	if (status != NXGE_OK) {
191444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1915a3c5bd6dSspeer 			"nxge_fflp_update_hw failed"));
191644961713Sgirish 		return (NXGE_ERROR);
191744961713Sgirish 	}
1918a3c5bd6dSspeer 
1919a3c5bd6dSspeer 	/* Init RDC tables? ? who should do that? rxdma or fflp ? */
1920a3c5bd6dSspeer 	/* attach rdc table to the MAC port. */
192144961713Sgirish 	status = nxge_main_mac_assign_rdc_table(nxgep);
192244961713Sgirish 	if (status != NXGE_OK) {
192344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1924a3c5bd6dSspeer 				"nxge_main_mac_assign_rdc_table failed"));
192544961713Sgirish 		return (NXGE_ERROR);
192644961713Sgirish 	}
1927a3c5bd6dSspeer 
192858324dfcSspeer 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
192944961713Sgirish 	if (status != NXGE_OK) {
193044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1931a3c5bd6dSspeer 			"nxge_multicast_mac_assign_rdc_table failed"));
193244961713Sgirish 		return (NXGE_ERROR);
193344961713Sgirish 	}
193414ea4bb7Ssd 
193514ea4bb7Ssd 	status = nxge_tcam_handle_ip_fragment(nxgep);
193614ea4bb7Ssd 	if (status != NXGE_OK) {
193714ea4bb7Ssd 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1938a3c5bd6dSspeer 			"nxge_tcam_handle_ip_fragment failed"));
193914ea4bb7Ssd 		return (NXGE_ERROR);
194014ea4bb7Ssd 	}
194144961713Sgirish 
194244961713Sgirish 	nxgep->classifier.state |= NXGE_FFLP_HW_INIT;
194344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw"));
194444961713Sgirish 	return (NXGE_OK);
194544961713Sgirish }
194644961713Sgirish 
194744961713Sgirish nxge_status_t
194844961713Sgirish nxge_fflp_handle_sys_errors(p_nxge_t nxgep)
194944961713Sgirish {
1950a3c5bd6dSspeer 	npi_handle_t handle;
1951a3c5bd6dSspeer 	p_nxge_fflp_stats_t statsp;
1952a3c5bd6dSspeer 	uint8_t portn, rdc_grp;
1953a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1954a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1955a3c5bd6dSspeer 	vlan_par_err_t vlan_err;
1956a3c5bd6dSspeer 	tcam_err_t tcam_err;
1957a3c5bd6dSspeer 	hash_lookup_err_log1_t fcram1_err;
1958a3c5bd6dSspeer 	hash_lookup_err_log2_t fcram2_err;
1959a3c5bd6dSspeer 	hash_tbl_data_log_t fcram_err;
196044961713Sgirish 
196144961713Sgirish 	handle = nxgep->npi_handle;
196244961713Sgirish 	statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats;
196344961713Sgirish 	portn = nxgep->mac.portnum;
196444961713Sgirish 
196544961713Sgirish 	/*
1966a3c5bd6dSspeer 	 * need to read the fflp error registers to figure out what the error
1967a3c5bd6dSspeer 	 * is
196844961713Sgirish 	 */
196944961713Sgirish 	npi_fflp_vlan_error_get(handle, &vlan_err);
197044961713Sgirish 	npi_fflp_tcam_error_get(handle, &tcam_err);
197144961713Sgirish 
197244961713Sgirish 	if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) {
197344961713Sgirish 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
1974a3c5bd6dSspeer 			" vlan table parity error on port %d"
1975a3c5bd6dSspeer 			" addr: 0x%x data: 0x%x",
1976a3c5bd6dSspeer 			portn, vlan_err.bits.ldw.addr,
1977a3c5bd6dSspeer 			vlan_err.bits.ldw.data));
197844961713Sgirish 		statsp->vlan_parity_err++;
197944961713Sgirish 
198044961713Sgirish 		if (vlan_err.bits.ldw.m_err) {
198144961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
1982a3c5bd6dSspeer 				" vlan table multiple errors on port %d",
1983a3c5bd6dSspeer 				portn));
198444961713Sgirish 		}
198544961713Sgirish 		statsp->errlog.vlan = (uint32_t)vlan_err.value;
198644961713Sgirish 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
1987a3c5bd6dSspeer 			NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR);
198844961713Sgirish 		npi_fflp_vlan_error_clear(handle);
198944961713Sgirish 	}
199044961713Sgirish 
199144961713Sgirish 	if (tcam_err.bits.ldw.err) {
199244961713Sgirish 		if (tcam_err.bits.ldw.p_ecc != 0) {
199344961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
1994a3c5bd6dSspeer 				" TCAM ECC error on port %d"
1995a3c5bd6dSspeer 				" TCAM entry: 0x%x syndrome: 0x%x",
1996a3c5bd6dSspeer 				portn, tcam_err.bits.ldw.addr,
1997a3c5bd6dSspeer 				tcam_err.bits.ldw.syndrome));
199844961713Sgirish 			statsp->tcam_ecc_err++;
199944961713Sgirish 		} else {
200044961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
2001a3c5bd6dSspeer 				" TCAM Parity error on port %d"
2002a3c5bd6dSspeer 				" addr: 0x%x parity value: 0x%x",
2003a3c5bd6dSspeer 				portn, tcam_err.bits.ldw.addr,
2004a3c5bd6dSspeer 				tcam_err.bits.ldw.syndrome));
200544961713Sgirish 			statsp->tcam_parity_err++;
200644961713Sgirish 		}
200744961713Sgirish 
200844961713Sgirish 		if (tcam_err.bits.ldw.mult) {
200944961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
2010a3c5bd6dSspeer 				" TCAM Multiple errors on port %d", portn));
201144961713Sgirish 		} else {
201244961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
2013a3c5bd6dSspeer 					" TCAM PIO error on port %d",
2014a3c5bd6dSspeer 					portn));
201544961713Sgirish 		}
201644961713Sgirish 
201744961713Sgirish 		statsp->errlog.tcam = (uint32_t)tcam_err.value;
201844961713Sgirish 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
2019a3c5bd6dSspeer 			NXGE_FM_EREPORT_FFLP_TCAM_ERR);
202044961713Sgirish 		npi_fflp_tcam_error_clear(handle);
202144961713Sgirish 	}
202244961713Sgirish 
202344961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
202444961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
202544961713Sgirish 
2026*678453a8Sspeer 	for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) {
2027*678453a8Sspeer 		if (p_cfgp->grpids[rdc_grp]) {
2028*678453a8Sspeer 			npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp);
2029*678453a8Sspeer 			if (fcram_err.bits.ldw.pio_err) {
2030*678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, FFLP_CTL,
2031*678453a8Sspeer 					" FCRAM PIO ECC error on port %d"
2032*678453a8Sspeer 					" rdc group: %d Hash Table addr: 0x%x"
2033*678453a8Sspeer 					" syndrome: 0x%x",
2034*678453a8Sspeer 					portn, rdc_grp,
2035*678453a8Sspeer 					fcram_err.bits.ldw.fcram_addr,
2036*678453a8Sspeer 					fcram_err.bits.ldw.syndrome));
2037*678453a8Sspeer 				statsp->hash_pio_err[rdc_grp]++;
2038*678453a8Sspeer 				statsp->errlog.hash_pio[rdc_grp] =
2039*678453a8Sspeer 				    (uint32_t)fcram_err.value;
2040*678453a8Sspeer 				NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
2041*678453a8Sspeer 				    NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR);
2042*678453a8Sspeer 				npi_fflp_fcram_error_clear(handle, rdc_grp);
2043*678453a8Sspeer 			}
204444961713Sgirish 		}
204544961713Sgirish 	}
204644961713Sgirish 
204744961713Sgirish 	npi_fflp_fcram_error_log1_get(handle, &fcram1_err);
204844961713Sgirish 	if (fcram1_err.bits.ldw.ecc_err) {
204944961713Sgirish 		char *multi_str = "";
205044961713Sgirish 		char *multi_bit_str = "";
2051a3c5bd6dSspeer 
205244961713Sgirish 		npi_fflp_fcram_error_log2_get(handle, &fcram2_err);
205344961713Sgirish 		if (fcram1_err.bits.ldw.mult_lk) {
205444961713Sgirish 			multi_str = "multiple";
205544961713Sgirish 		}
205644961713Sgirish 		if (fcram1_err.bits.ldw.mult_bit) {
205744961713Sgirish 			multi_bit_str = "multiple bits";
205844961713Sgirish 		}
2059f6485eecSyc 		statsp->hash_lookup_err++;
206044961713Sgirish 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
2061a3c5bd6dSspeer 			" FCRAM %s lookup %s ECC error on port %d"
2062a3c5bd6dSspeer 			" H1: 0x%x Subarea: 0x%x Syndrome: 0x%x",
2063a3c5bd6dSspeer 			multi_str, multi_bit_str, portn,
2064a3c5bd6dSspeer 			fcram2_err.bits.ldw.h1,
2065a3c5bd6dSspeer 			fcram2_err.bits.ldw.subarea,
2066a3c5bd6dSspeer 			fcram2_err.bits.ldw.syndrome));
206744961713Sgirish 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
2068a3c5bd6dSspeer 			NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR);
206944961713Sgirish 	}
207044961713Sgirish 	statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value;
207144961713Sgirish 	statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value;
207244961713Sgirish 	return (NXGE_OK);
207344961713Sgirish }
2074