xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_fflp.c (revision 52ccf843)
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 /*
22678453a8Sspeer  * 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,
84*52ccf843Smisaki 	    (struct tcam_entry *)&tcam_rdptr);
8544961713Sgirish 	if (status & NPI_FAILURE) {
8644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
87*52ccf843Smisaki 		    " nxge_tcam_dump_entry:"
88*52ccf843Smisaki 		    "  tcam read failed at location %d ", location));
8944961713Sgirish 		return (NXGE_ERROR);
9044961713Sgirish 	}
9144961713Sgirish 	status = npi_fflp_tcam_asc_ram_entry_read(handle,
92*52ccf843Smisaki 	    (tcam_location_t)location, &asc_ram);
9344961713Sgirish 
9444961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n"
95*52ccf843Smisaki 	    " key:  %llx %llx %llx %llx \n"
96*52ccf843Smisaki 	    " mask: %llx %llx %llx %llx \n"
97*52ccf843Smisaki 	    " ASC RAM %llx \n", location,
98*52ccf843Smisaki 	    tcam_rdptr.key0, tcam_rdptr.key1,
99*52ccf843Smisaki 	    tcam_rdptr.key2, tcam_rdptr.key3,
100*52ccf843Smisaki 	    tcam_rdptr.mask0, tcam_rdptr.mask1,
101*52ccf843Smisaki 	    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,
119*52ccf843Smisaki 		    "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,
158*52ccf843Smisaki 			    "VLAN Table invalidate failed for vlan id %d ",
159*52ccf843Smisaki 			    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,
197*52ccf843Smisaki 		    "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;
204*52ccf843Smisaki 	    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,
208*52ccf843Smisaki 			    "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;
215*52ccf843Smisaki 	    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,
219*52ccf843Smisaki 			    "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,
249*52ccf843Smisaki 	    "==> 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,
253*52ccf843Smisaki 		    " nxge_fflp_tcam_invalidate_all:"
254*52ccf843Smisaki 		    " 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,
263*52ccf843Smisaki 			    "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,
269*52ccf843Smisaki 	    "<== 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,
318*52ccf843Smisaki 		    "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,
329*52ccf843Smisaki 		    location, fc.value[0]);
33044961713Sgirish 		if (rs != NPI_SUCCESS) {
33144961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
332*52ccf843Smisaki 			    "failed write at location %x ", location));
33344961713Sgirish 			return (NXGE_ERROR | rs);
33444961713Sgirish 		}
33544961713Sgirish 	}
33644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all"));
337a3c5bd6dSspeer 	return (NXGE_OK);
33844961713Sgirish }
33944961713Sgirish 
34044961713Sgirish static nxge_status_t
34144961713Sgirish nxge_fflp_fcram_init(p_nxge_t nxgep)
34244961713Sgirish {
34344961713Sgirish 	fflp_fcram_output_drive_t strength;
34444961713Sgirish 	fflp_fcram_qs_t qs;
34544961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
34644961713Sgirish 	uint8_t access_ratio;
347a3c5bd6dSspeer 	int partition;
34844961713Sgirish 	npi_handle_t handle;
349a3c5bd6dSspeer 	uint32_t min_time, max_time, sys_time;
35044961713Sgirish 
35144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init"));
35244961713Sgirish 
353a3c5bd6dSspeer 	/*
354a3c5bd6dSspeer 	 * Recommended values are needed.
355a3c5bd6dSspeer 	 */
35644961713Sgirish 	min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME;
35744961713Sgirish 	max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME;
35844961713Sgirish 	sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME;
359a3c5bd6dSspeer 
36044961713Sgirish 	handle = nxgep->npi_reg_handle;
36144961713Sgirish 	strength = FCRAM_OUTDR_NORMAL;
36244961713Sgirish 	qs = FCRAM_QS_MODE_QS;
36344961713Sgirish 	rs = npi_fflp_cfg_fcram_reset(handle, strength, qs);
36444961713Sgirish 	if (rs != NPI_SUCCESS) {
36544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. "));
36644961713Sgirish 		return (NXGE_ERROR | rs);
36744961713Sgirish 	}
36844961713Sgirish 
369a3c5bd6dSspeer 	access_ratio = nxgep->param_arr[param_fcram_access_ratio].value;
370a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_access(handle, access_ratio);
371a3c5bd6dSspeer 	if (rs != NPI_SUCCESS) {
37244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio"
373*52ccf843Smisaki 		    "configuration \n"));
37444961713Sgirish 		return (NXGE_ERROR | rs);
37544961713Sgirish 	}
37644961713Sgirish 	rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time,
377*52ccf843Smisaki 	    max_time, sys_time);
37844961713Sgirish 	if (rs != NPI_SUCCESS) {
37944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
380*52ccf843Smisaki 		    "failed FCRAM refresh cfg"));
38144961713Sgirish 		return (NXGE_ERROR);
38244961713Sgirish 	}
38344961713Sgirish 
38444961713Sgirish 	/* disable all the partitions until explicitly enabled */
38544961713Sgirish 	for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) {
386a3c5bd6dSspeer 		rs = npi_fflp_cfg_fcram_partition_disable(handle, partition);
38744961713Sgirish 		if (rs != NPI_SUCCESS) {
38844961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
389*52ccf843Smisaki 			    "failed FCRAM partition"
390*52ccf843Smisaki 			    " enable for partition %d ", partition));
39144961713Sgirish 			return (NXGE_ERROR | rs);
39244961713Sgirish 		}
39344961713Sgirish 	}
39444961713Sgirish 
39544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init"));
396a3c5bd6dSspeer 	return (NXGE_OK);
39744961713Sgirish }
39844961713Sgirish 
39944961713Sgirish nxge_status_t
40044961713Sgirish nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac)
40144961713Sgirish {
40244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
40344961713Sgirish 	hostinfo_t mac_rdc;
40444961713Sgirish 	npi_handle_t handle;
405a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
40644961713Sgirish 
407a3c5bd6dSspeer 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
40844961713Sgirish 	if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) {
409a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
410*52ccf843Smisaki 		    " nxge_logical_mac_assign_rdc_table"
411*52ccf843Smisaki 		    " unconfigured alt MAC addr %d ", alt_mac));
41244961713Sgirish 		return (NXGE_ERROR);
41344961713Sgirish 	}
41444961713Sgirish 	handle = nxgep->npi_reg_handle;
41544961713Sgirish 	mac_rdc.value = 0;
41644961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num =
417*52ccf843Smisaki 	    p_class_cfgp->mac_host_info[alt_mac].rdctbl;
41844961713Sgirish 	mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr;
41944961713Sgirish 
42044961713Sgirish 	rs = npi_mac_hostinfo_entry(handle, OP_SET,
421*52ccf843Smisaki 	    nxgep->function_num, alt_mac, &mac_rdc);
42244961713Sgirish 
42344961713Sgirish 	if (rs != NPI_SUCCESS) {
42444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
425*52ccf843Smisaki 		    "failed Assign RDC table"));
42644961713Sgirish 		return (NXGE_ERROR | rs);
42744961713Sgirish 	}
42844961713Sgirish 	return (NXGE_OK);
42944961713Sgirish }
43044961713Sgirish 
43144961713Sgirish nxge_status_t
43244961713Sgirish nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)
43344961713Sgirish {
43444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
43544961713Sgirish 	hostinfo_t mac_rdc;
43644961713Sgirish 	npi_handle_t handle;
43744961713Sgirish 
43844961713Sgirish 	handle = nxgep->npi_reg_handle;
43944961713Sgirish 	mac_rdc.value = 0;
44044961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp;
44144961713Sgirish 	mac_rdc.bits.w0.mac_pref = 1;
44244961713Sgirish 	switch (nxgep->function_num) {
443a3c5bd6dSspeer 	case 0:
444a3c5bd6dSspeer 	case 1:
445a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
446*52ccf843Smisaki 		    nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
447a3c5bd6dSspeer 		break;
448a3c5bd6dSspeer 	case 2:
449a3c5bd6dSspeer 	case 3:
450a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
451*52ccf843Smisaki 		    nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
452a3c5bd6dSspeer 		break;
453a3c5bd6dSspeer 	default:
454a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
455*52ccf843Smisaki 		    "failed Assign RDC table (invalid function #)"));
456a3c5bd6dSspeer 		return (NXGE_ERROR);
45744961713Sgirish 	}
45844961713Sgirish 
45944961713Sgirish 	if (rs != NPI_SUCCESS) {
46044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
461*52ccf843Smisaki 		    "failed Assign RDC table"));
46244961713Sgirish 		return (NXGE_ERROR | rs);
46344961713Sgirish 	}
46444961713Sgirish 	return (NXGE_OK);
46544961713Sgirish }
46644961713Sgirish 
46758324dfcSspeer /*
46858324dfcSspeer  * Initialize hostinfo registers for alternate MAC addresses and
46958324dfcSspeer  * multicast MAC address.
47058324dfcSspeer  */
47144961713Sgirish nxge_status_t
47258324dfcSspeer nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)
47344961713Sgirish {
47444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
47544961713Sgirish 	hostinfo_t mac_rdc;
47644961713Sgirish 	npi_handle_t handle;
47758324dfcSspeer 	int i;
47844961713Sgirish 
47944961713Sgirish 	handle = nxgep->npi_reg_handle;
48044961713Sgirish 	mac_rdc.value = 0;
48144961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp;
48244961713Sgirish 	mac_rdc.bits.w0.mac_pref = 1;
48344961713Sgirish 	switch (nxgep->function_num) {
484a3c5bd6dSspeer 	case 0:
485a3c5bd6dSspeer 	case 1:
48658324dfcSspeer 		/*
48758324dfcSspeer 		 * Tests indicate that it is OK not to re-initialize the
48858324dfcSspeer 		 * hostinfo registers for the XMAC's alternate MAC
48958324dfcSspeer 		 * addresses. But that is necessary for BMAC (case 2
49058324dfcSspeer 		 * and case 3 below)
49158324dfcSspeer 		 */
492a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
493*52ccf843Smisaki 		    nxgep->function_num,
494*52ccf843Smisaki 		    XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
495a3c5bd6dSspeer 		break;
496a3c5bd6dSspeer 	case 2:
497a3c5bd6dSspeer 	case 3:
49858324dfcSspeer 		for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
49958324dfcSspeer 			rs |= npi_mac_hostinfo_entry(handle, OP_SET,
500*52ccf843Smisaki 			    nxgep->function_num, i, &mac_rdc);
50158324dfcSspeer 
50258324dfcSspeer 		rs |= npi_mac_hostinfo_entry(handle, OP_SET,
503*52ccf843Smisaki 		    nxgep->function_num,
504*52ccf843Smisaki 		    BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
505a3c5bd6dSspeer 		break;
506a3c5bd6dSspeer 	default:
507a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
508*52ccf843Smisaki 		    "failed Assign RDC table (invalid function #)"));
509a3c5bd6dSspeer 		return (NXGE_ERROR);
51044961713Sgirish 	}
51144961713Sgirish 
51244961713Sgirish 	if (rs != NPI_SUCCESS) {
51344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
514*52ccf843Smisaki 		    "failed Assign RDC table"));
51544961713Sgirish 		return (NXGE_ERROR | rs);
51644961713Sgirish 	}
51744961713Sgirish 	return (NXGE_OK);
51844961713Sgirish }
51944961713Sgirish 
52044961713Sgirish nxge_status_t
52144961713Sgirish nxge_fflp_init_hostinfo(p_nxge_t nxgep)
52244961713Sgirish {
52344961713Sgirish 	nxge_status_t status = NXGE_OK;
524a3c5bd6dSspeer 
52558324dfcSspeer 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
52658324dfcSspeer 	status |= nxge_main_mac_assign_rdc_table(nxgep);
52744961713Sgirish 	return (status);
52844961713Sgirish }
52944961713Sgirish 
53044961713Sgirish nxge_status_t
53144961713Sgirish nxge_fflp_hw_reset(p_nxge_t nxgep)
53244961713Sgirish {
53344961713Sgirish 	npi_handle_t handle;
53444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
53544961713Sgirish 	nxge_status_t status = NXGE_OK;
53644961713Sgirish 
53744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
53844961713Sgirish 
5392e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
54044961713Sgirish 		status = nxge_fflp_fcram_init(nxgep);
541a3c5bd6dSspeer 		if (status != NXGE_OK) {
54244961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
543*52ccf843Smisaki 			    " failed FCRAM init. "));
54444961713Sgirish 			return (status);
54544961713Sgirish 		}
54644961713Sgirish 	}
54744961713Sgirish 
54844961713Sgirish 	status = nxge_fflp_tcam_init(nxgep);
54944961713Sgirish 	if (status != NXGE_OK) {
550a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
551*52ccf843Smisaki 		    "failed TCAM init."));
552a3c5bd6dSspeer 		return (status);
55344961713Sgirish 	}
55444961713Sgirish 
55544961713Sgirish 	handle = nxgep->npi_reg_handle;
55644961713Sgirish 	rs = npi_fflp_cfg_llcsnap_enable(handle);
55744961713Sgirish 	if (rs != NPI_SUCCESS) {
558a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
559*52ccf843Smisaki 		    "failed LLCSNAP enable. "));
560a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
56144961713Sgirish 	}
56244961713Sgirish 
56344961713Sgirish 	rs = npi_fflp_cfg_cam_errorcheck_disable(handle);
56444961713Sgirish 	if (rs != NPI_SUCCESS) {
56544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
566*52ccf843Smisaki 		    "failed CAM Error Check enable. "));
56744961713Sgirish 		return (NXGE_ERROR | rs);
56844961713Sgirish 	}
56944961713Sgirish 
570a3c5bd6dSspeer 	/* init the hash generators */
57144961713Sgirish 	rs = npi_fflp_cfg_hash_h1poly(handle, 0);
57244961713Sgirish 	if (rs != NPI_SUCCESS) {
573a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
574*52ccf843Smisaki 		    "failed H1 Poly Init. "));
575a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
57644961713Sgirish 	}
57744961713Sgirish 
57844961713Sgirish 	rs = npi_fflp_cfg_hash_h2poly(handle, 0);
57944961713Sgirish 	if (rs != NPI_SUCCESS) {
580a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
581*52ccf843Smisaki 		    "failed H2 Poly Init. "));
582a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
58344961713Sgirish 	}
58444961713Sgirish 
585a3c5bd6dSspeer 	/* invalidate TCAM entries */
58644961713Sgirish 	status = nxge_fflp_tcam_invalidate_all(nxgep);
58744961713Sgirish 	if (status != NXGE_OK) {
58844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
589*52ccf843Smisaki 		    "failed TCAM Entry Invalidate. "));
59044961713Sgirish 		return (status);
59144961713Sgirish 	}
59244961713Sgirish 
593a3c5bd6dSspeer 	/* invalidate FCRAM entries */
5942e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
59544961713Sgirish 		status = nxge_fflp_fcram_invalidate_all(nxgep);
59644961713Sgirish 		if (status != NXGE_OK) {
59744961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
598*52ccf843Smisaki 			    "failed FCRAM Entry Invalidate."));
59944961713Sgirish 			return (status);
60044961713Sgirish 		}
60144961713Sgirish 	}
60244961713Sgirish 
603a3c5bd6dSspeer 	/* invalidate VLAN RDC tables */
60444961713Sgirish 	status = nxge_fflp_vlan_tbl_clear_all(nxgep);
60544961713Sgirish 	if (status != NXGE_OK) {
60644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
607*52ccf843Smisaki 		    "failed VLAN Table Invalidate. "));
60844961713Sgirish 		return (status);
60944961713Sgirish 	}
61044961713Sgirish 	nxgep->classifier.state |= NXGE_FFLP_HW_RESET;
61144961713Sgirish 
61244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset"));
61344961713Sgirish 	return (NXGE_OK);
61444961713Sgirish }
61544961713Sgirish 
61644961713Sgirish nxge_status_t
61744961713Sgirish nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class,
618a3c5bd6dSspeer 	uint32_t class_config)
61944961713Sgirish {
62044961713Sgirish 	flow_key_cfg_t fcfg;
62144961713Sgirish 	npi_handle_t handle;
62244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
62344961713Sgirish 
62444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key"));
62544961713Sgirish 	handle = nxgep->npi_reg_handle;
62644961713Sgirish 	bzero(&fcfg, sizeof (flow_key_cfg_t));
62744961713Sgirish 
628a3c5bd6dSspeer 	if (class_config & NXGE_CLASS_FLOW_USE_PROTO)
62944961713Sgirish 		fcfg.use_proto = 1;
63044961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT)
63144961713Sgirish 		fcfg.use_dport = 1;
63244961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT)
63344961713Sgirish 		fcfg.use_sport = 1;
63444961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_IPDST)
63544961713Sgirish 		fcfg.use_daddr = 1;
63644961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_IPSRC)
63744961713Sgirish 		fcfg.use_saddr = 1;
63844961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_VLAN)
63944961713Sgirish 		fcfg.use_vlan = 1;
64044961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_L2DA)
64144961713Sgirish 		fcfg.use_l2da = 1;
64244961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM)
64344961713Sgirish 		fcfg.use_portnum = 1;
64444961713Sgirish 	fcfg.ip_opts_exist = 0;
64544961713Sgirish 
64644961713Sgirish 	rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg);
64744961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
64844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
649*52ccf843Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
65044961713Sgirish 		return (NXGE_ERROR | rs);
65144961713Sgirish 	}
65244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key"));
65344961713Sgirish 	return (NXGE_OK);
65444961713Sgirish }
65544961713Sgirish 
65644961713Sgirish nxge_status_t
65744961713Sgirish nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class,
658a3c5bd6dSspeer 	uint32_t *class_config)
65944961713Sgirish {
66044961713Sgirish 	flow_key_cfg_t fcfg;
66144961713Sgirish 	npi_handle_t handle;
66244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
66344961713Sgirish 	uint32_t ccfg = 0;
664a3c5bd6dSspeer 
66544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get"));
66644961713Sgirish 	handle = nxgep->npi_reg_handle;
66744961713Sgirish 	bzero(&fcfg, sizeof (flow_key_cfg_t));
66844961713Sgirish 
66944961713Sgirish 	rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg);
67044961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
67144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
672*52ccf843Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
67344961713Sgirish 		return (NXGE_ERROR | rs);
67444961713Sgirish 	}
67544961713Sgirish 
67644961713Sgirish 	if (fcfg.use_proto)
67744961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_PROTO;
67844961713Sgirish 	if (fcfg.use_dport)
67944961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT;
68044961713Sgirish 	if (fcfg.use_sport)
68144961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT;
68244961713Sgirish 	if (fcfg.use_daddr)
68344961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_IPDST;
68444961713Sgirish 	if (fcfg.use_saddr)
68544961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_IPSRC;
68644961713Sgirish 	if (fcfg.use_vlan)
68744961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_VLAN;
68844961713Sgirish 	if (fcfg.use_l2da)
68944961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_L2DA;
69044961713Sgirish 	if (fcfg.use_portnum)
691a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM;
69244961713Sgirish 
69344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
694*52ccf843Smisaki 	    " nxge_cfg_ip_cls_flow_key_get %x", ccfg));
69544961713Sgirish 	*class_config = ccfg;
69644961713Sgirish 
69744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
698*52ccf843Smisaki 	    " <== nxge_cfg_ip_cls_flow_key_get"));
69944961713Sgirish 	return (NXGE_OK);
70044961713Sgirish }
70144961713Sgirish 
70244961713Sgirish static nxge_status_t
70344961713Sgirish nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class,
704a3c5bd6dSspeer 	uint32_t *class_config)
70544961713Sgirish {
70644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
70744961713Sgirish 	tcam_key_cfg_t cfg;
70844961713Sgirish 	npi_handle_t handle;
70944961713Sgirish 	uint32_t ccfg = 0;
71044961713Sgirish 
71144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
71244961713Sgirish 
71344961713Sgirish 	bzero(&cfg, sizeof (tcam_key_cfg_t));
71444961713Sgirish 	handle = nxgep->npi_reg_handle;
71544961713Sgirish 
71644961713Sgirish 	rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg);
71744961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
71844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
719*52ccf843Smisaki 		    " opt %x for class %d failed ", class_config, class));
72044961713Sgirish 		return (NXGE_ERROR | rs);
72144961713Sgirish 	}
72244961713Sgirish 	if (cfg.discard)
723a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_DISCARD;
72444961713Sgirish 	if (cfg.lookup_enable)
72544961713Sgirish 		ccfg |= NXGE_CLASS_TCAM_LOOKUP;
72644961713Sgirish 	if (cfg.use_ip_daddr)
727a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR;
72844961713Sgirish 	*class_config = ccfg;
72944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
730*52ccf843Smisaki 	    " ==> nxge_cfg_tcam_ip_class %x", ccfg));
73144961713Sgirish 	return (NXGE_OK);
73244961713Sgirish }
73344961713Sgirish 
73444961713Sgirish static nxge_status_t
73544961713Sgirish nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class,
736a3c5bd6dSspeer 	uint32_t class_config)
73744961713Sgirish {
73844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
73944961713Sgirish 	tcam_key_cfg_t cfg;
74044961713Sgirish 	npi_handle_t handle;
741a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
74244961713Sgirish 
74344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
744a3c5bd6dSspeer 
74544961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
74644961713Sgirish 	p_class_cfgp->class_cfg[class] = class_config;
74744961713Sgirish 
74844961713Sgirish 	bzero(&cfg, sizeof (tcam_key_cfg_t));
74944961713Sgirish 	handle = nxgep->npi_reg_handle;
75044961713Sgirish 	cfg.discard = 0;
75144961713Sgirish 	cfg.lookup_enable = 0;
75244961713Sgirish 	cfg.use_ip_daddr = 0;
75344961713Sgirish 	if (class_config & NXGE_CLASS_DISCARD)
75444961713Sgirish 		cfg.discard = 1;
75544961713Sgirish 	if (class_config & NXGE_CLASS_TCAM_LOOKUP)
75644961713Sgirish 		cfg.lookup_enable = 1;
757a3c5bd6dSspeer 	if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR)
75844961713Sgirish 		cfg.use_ip_daddr = 1;
75944961713Sgirish 
76044961713Sgirish 	rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg);
76144961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
76244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
763*52ccf843Smisaki 		    " opt %x for class %d failed ", class_config, class));
76444961713Sgirish 		return (NXGE_ERROR | rs);
76544961713Sgirish 	}
76644961713Sgirish 	return (NXGE_OK);
76744961713Sgirish }
76844961713Sgirish 
76944961713Sgirish nxge_status_t
77044961713Sgirish nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1)
77144961713Sgirish {
77244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
77344961713Sgirish 	npi_handle_t handle;
774a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
77544961713Sgirish 
77644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1"));
77744961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
77844961713Sgirish 	p_class_cfgp->init_h1 = h1;
77944961713Sgirish 	handle = nxgep->npi_reg_handle;
78044961713Sgirish 	rs = npi_fflp_cfg_hash_h1poly(handle, h1);
78144961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
782a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
783*52ccf843Smisaki 		    " nxge_fflp_init_h1 %x failed ", h1));
78444961713Sgirish 		return (NXGE_ERROR | rs);
78544961713Sgirish 	}
78644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1"));
78744961713Sgirish 	return (NXGE_OK);
78844961713Sgirish }
78944961713Sgirish 
79044961713Sgirish nxge_status_t
79144961713Sgirish nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2)
79244961713Sgirish {
79344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
79444961713Sgirish 	npi_handle_t handle;
795a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
79644961713Sgirish 
79744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2"));
79844961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
79944961713Sgirish 	p_class_cfgp->init_h2 = h2;
80044961713Sgirish 
80144961713Sgirish 	handle = nxgep->npi_reg_handle;
80244961713Sgirish 	rs = npi_fflp_cfg_hash_h2poly(handle, h2);
80344961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
804a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
805*52ccf843Smisaki 		    " nxge_fflp_init_h2 %x failed ", h2));
80644961713Sgirish 		return (NXGE_ERROR | rs);
80744961713Sgirish 	}
80844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2"));
80944961713Sgirish 	return (NXGE_OK);
81044961713Sgirish }
81144961713Sgirish 
81244961713Sgirish nxge_status_t
81344961713Sgirish nxge_classify_init_sw(p_nxge_t nxgep)
81444961713Sgirish {
81544961713Sgirish 	int alloc_size;
81644961713Sgirish 	nxge_classify_t *classify_ptr;
81744961713Sgirish 
81844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw"));
81944961713Sgirish 	classify_ptr = &nxgep->classifier;
82044961713Sgirish 
82144961713Sgirish 	if (classify_ptr->state & NXGE_FFLP_SW_INIT) {
82244961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
823*52ccf843Smisaki 		    "nxge_classify_init_sw already init"));
82444961713Sgirish 		return (NXGE_OK);
82544961713Sgirish 	}
826a3c5bd6dSspeer 	/* Init SW structures */
82744961713Sgirish 	classify_ptr->tcam_size = TCAM_NIU_TCAM_MAX_ENTRY;
828a3c5bd6dSspeer 
829a3c5bd6dSspeer 	/* init data structures, based on HW type */
8302e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
83144961713Sgirish 		classify_ptr->tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY;
832a3c5bd6dSspeer 		/*
833a3c5bd6dSspeer 		 * check if fcram based classification is required and init the
834a3c5bd6dSspeer 		 * flow storage
835a3c5bd6dSspeer 		 */
83644961713Sgirish 	}
83744961713Sgirish 	alloc_size = sizeof (tcam_flow_spec_t) * classify_ptr->tcam_size;
83844961713Sgirish 	classify_ptr->tcam_entries = KMEM_ZALLOC(alloc_size, NULL);
83944961713Sgirish 
840a3c5bd6dSspeer 	/* Init defaults */
841a3c5bd6dSspeer 	/*
842a3c5bd6dSspeer 	 * add hacks required for HW shortcomings for example, code to handle
843a3c5bd6dSspeer 	 * fragmented packets
844a3c5bd6dSspeer 	 */
84544961713Sgirish 	nxge_init_h1_table();
84644961713Sgirish 	nxge_crc_ccitt_init();
84744961713Sgirish 	nxgep->classifier.tcam_location = nxgep->function_num;
84844961713Sgirish 	nxgep->classifier.fragment_bug = 1;
84944961713Sgirish 	classify_ptr->state |= NXGE_FFLP_SW_INIT;
85044961713Sgirish 
85144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw"));
85244961713Sgirish 	return (NXGE_OK);
85344961713Sgirish }
85444961713Sgirish 
85544961713Sgirish nxge_status_t
85644961713Sgirish nxge_classify_exit_sw(p_nxge_t nxgep)
85744961713Sgirish {
85844961713Sgirish 	int alloc_size;
85944961713Sgirish 	nxge_classify_t *classify_ptr;
86044961713Sgirish 	int fsize;
861a3c5bd6dSspeer 
86244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw"));
86344961713Sgirish 	classify_ptr = &nxgep->classifier;
86444961713Sgirish 
86544961713Sgirish 	fsize = sizeof (tcam_flow_spec_t);
86644961713Sgirish 	if (classify_ptr->tcam_entries) {
867a3c5bd6dSspeer 		alloc_size = fsize * classify_ptr->tcam_size;
868a3c5bd6dSspeer 		KMEM_FREE((void *) classify_ptr->tcam_entries, alloc_size);
86944961713Sgirish 	}
87044961713Sgirish 	nxgep->classifier.state = NULL;
87144961713Sgirish 
87244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw"));
87344961713Sgirish 	return (NXGE_OK);
87444961713Sgirish }
87544961713Sgirish 
87644961713Sgirish /*
87744961713Sgirish  * Figures out the location where the TCAM entry is
87844961713Sgirish  * to be inserted.
87944961713Sgirish  *
88044961713Sgirish  * The current implementation is just a place holder and it
88144961713Sgirish  * returns the next tcam location.
88244961713Sgirish  * The real location determining algorithm would consider
88344961713Sgirish  * the priority, partition etc ... before deciding which
88444961713Sgirish  * location to insert.
88544961713Sgirish  *
88644961713Sgirish  */
88744961713Sgirish 
8880a8e077aSspeer /* ARGSUSED */
88944961713Sgirish static tcam_location_t
89044961713Sgirish nxge_get_tcam_location(p_nxge_t nxgep, uint8_t class)
89144961713Sgirish {
89244961713Sgirish 	tcam_location_t location;
893a3c5bd6dSspeer 
89444961713Sgirish 	location = nxgep->classifier.tcam_location;
89544961713Sgirish 	nxgep->classifier.tcam_location = (location + nxgep->nports) %
896*52ccf843Smisaki 	    nxgep->classifier.tcam_size;
89744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
898*52ccf843Smisaki 	    "nxge_get_tcam_location: location %d next %d \n",
899*52ccf843Smisaki 	    location, nxgep->classifier.tcam_location));
90044961713Sgirish 	return (location);
90144961713Sgirish }
90244961713Sgirish 
90344961713Sgirish /*
90444961713Sgirish  * Figures out the RDC Group for the entry
90544961713Sgirish  *
90644961713Sgirish  * The current implementation is just a place holder and it
90744961713Sgirish  * returns 0.
90844961713Sgirish  * The real location determining algorithm would consider
90944961713Sgirish  * the partition etc ... before deciding w
91044961713Sgirish  *
91144961713Sgirish  */
912a3c5bd6dSspeer 
9130a8e077aSspeer /* ARGSUSED */
91444961713Sgirish static uint8_t
91544961713Sgirish nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, intptr_t cookie)
91644961713Sgirish {
91744961713Sgirish 	int use_port_rdc_grp = 0;
91844961713Sgirish 	uint8_t rdc_grp = 0;
919a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
920a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
921a3c5bd6dSspeer 	p_nxge_rdc_grp_t rdc_grp_p;
922a3c5bd6dSspeer 
92344961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
92444961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
92544961713Sgirish 	rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp];
926678453a8Sspeer 	rdc_grp = p_cfgp->def_mac_rxdma_grpid;
927a3c5bd6dSspeer 
92844961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
929*52ccf843Smisaki 	    "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
930*52ccf843Smisaki 	    cookie, rdc_grp, rdc_grp_p));
93144961713Sgirish 	return (rdc_grp);
93244961713Sgirish }
93344961713Sgirish 
93444961713Sgirish /* ARGSUSED */
93544961713Sgirish static uint8_t
93644961713Sgirish nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, intptr_t cookie)
93744961713Sgirish {
93844961713Sgirish 	return ((uint8_t)cookie);
93944961713Sgirish }
94044961713Sgirish 
9410a8e077aSspeer /* ARGSUSED */
94244961713Sgirish static void
94344961713Sgirish nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec,
944a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
94544961713Sgirish {
94644961713Sgirish 	udpip4_spec_t *fspec_key;
94744961713Sgirish 	udpip4_spec_t *fspec_mask;
94844961713Sgirish 
94944961713Sgirish 	fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec;
95044961713Sgirish 	fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec;
95144961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
95244961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
95344961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
95444961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
95544961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
956*52ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
95744961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
958*52ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
95944961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
960*52ccf843Smisaki 	    tcam_ptr->ip4_class_mask,
961*52ccf843Smisaki 	    TCAM_CLASS_UDP_IPV4);
96244961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
963*52ccf843Smisaki 	    tcam_ptr->ip4_proto_mask,
964*52ccf843Smisaki 	    IPPROTO_UDP);
96544961713Sgirish }
96644961713Sgirish 
96744961713Sgirish static void
96844961713Sgirish nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
969a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
97044961713Sgirish {
97144961713Sgirish 	udpip6_spec_t *fspec_key;
97244961713Sgirish 	udpip6_spec_t *fspec_mask;
973a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
97444961713Sgirish 
97544961713Sgirish 	fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec;
97644961713Sgirish 	fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec;
97744961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
97844961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
979*52ccf843Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
98044961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
98144961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
98244961713Sgirish 	} else {
98344961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
98444961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
98544961713Sgirish 	}
98644961713Sgirish 
98744961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
988*52ccf843Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6);
98944961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
990*52ccf843Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP);
99144961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
992*52ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
99344961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
994*52ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
99544961713Sgirish }
99644961713Sgirish 
9970a8e077aSspeer /* ARGSUSED */
99844961713Sgirish static void
99944961713Sgirish nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec,
1000a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
100144961713Sgirish {
100244961713Sgirish 	tcpip4_spec_t *fspec_key;
100344961713Sgirish 	tcpip4_spec_t *fspec_mask;
100444961713Sgirish 
100544961713Sgirish 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
100644961713Sgirish 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
100744961713Sgirish 
100844961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
100944961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
101044961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
101144961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
101244961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
1013*52ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
101444961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
1015*52ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
101644961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
1017*52ccf843Smisaki 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4);
101844961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
1019*52ccf843Smisaki 	    tcam_ptr->ip4_proto_mask, IPPROTO_TCP);
102044961713Sgirish }
102144961713Sgirish 
10220a8e077aSspeer /* ARGSUSED */
102344961713Sgirish static void
102444961713Sgirish nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec,
1025a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
102644961713Sgirish {
102744961713Sgirish 	tcpip4_spec_t *fspec_key;
102844961713Sgirish 	tcpip4_spec_t *fspec_mask;
102944961713Sgirish 
103044961713Sgirish 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
103144961713Sgirish 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
103244961713Sgirish 
103344961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
103444961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
103544961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
103644961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
103744961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
1038*52ccf843Smisaki 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4);
103944961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
1040*52ccf843Smisaki 	    tcam_ptr->ip4_proto_mask, IPPROTO_SCTP);
104144961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
1042*52ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
104344961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
1044*52ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
104544961713Sgirish }
104644961713Sgirish 
104744961713Sgirish static void
104844961713Sgirish nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1049a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
105044961713Sgirish {
105144961713Sgirish 	tcpip6_spec_t *fspec_key;
105244961713Sgirish 	tcpip6_spec_t *fspec_mask;
1053a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1054a3c5bd6dSspeer 
105544961713Sgirish 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
105644961713Sgirish 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
105744961713Sgirish 
105844961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
105944961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
1060*52ccf843Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
106144961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
106244961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
106344961713Sgirish 	} else {
106444961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
106544961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
106644961713Sgirish 	}
106744961713Sgirish 
106844961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
1069*52ccf843Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6);
107044961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
1071*52ccf843Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP);
107244961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
1073*52ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
107444961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
1075*52ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
107644961713Sgirish }
107744961713Sgirish 
107844961713Sgirish static void
107944961713Sgirish nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1080a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
108144961713Sgirish {
108244961713Sgirish 	tcpip6_spec_t *fspec_key;
108344961713Sgirish 	tcpip6_spec_t *fspec_mask;
1084a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
108544961713Sgirish 
108644961713Sgirish 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
108744961713Sgirish 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
108844961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
108944961713Sgirish 
109044961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
1091*52ccf843Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
109244961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
109344961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
109444961713Sgirish 	} else {
109544961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
109644961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
109744961713Sgirish 	}
109844961713Sgirish 
109944961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
1100*52ccf843Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6);
110144961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
1102*52ccf843Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP);
110344961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
1104*52ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
110544961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
1106*52ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
110744961713Sgirish }
110844961713Sgirish 
110944961713Sgirish nxge_status_t
111044961713Sgirish nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res,
1111a3c5bd6dSspeer 	uint32_t *H1, uint16_t *H2)
111244961713Sgirish {
111344961713Sgirish 	flow_spec_t *flow_spec;
111444961713Sgirish 	uint32_t class_cfg;
111544961713Sgirish 	flow_template_t ft;
1116a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
111744961713Sgirish 
111844961713Sgirish 	int ft_size = sizeof (flow_template_t);
1119a3c5bd6dSspeer 
112044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash"));
112144961713Sgirish 
112244961713Sgirish 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
112344961713Sgirish 	bzero((char *)&ft, ft_size);
112444961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1125a3c5bd6dSspeer 
112644961713Sgirish 	switch (flow_spec->flow_type) {
1127a3c5bd6dSspeer 	case FSPEC_TCPIP4:
1128a3c5bd6dSspeer 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4];
1129a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1130a3c5bd6dSspeer 			ft.ip_proto = IPPROTO_TCP;
1131a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1132a3c5bd6dSspeer 			ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src;
1133a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1134a3c5bd6dSspeer 			ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst;
1135a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1136a3c5bd6dSspeer 			ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc;
1137a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1138a3c5bd6dSspeer 			ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst;
1139a3c5bd6dSspeer 		break;
1140a3c5bd6dSspeer 
1141a3c5bd6dSspeer 	case FSPEC_UDPIP4:
1142a3c5bd6dSspeer 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4];
1143a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1144a3c5bd6dSspeer 			ft.ip_proto = IPPROTO_UDP;
1145a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1146a3c5bd6dSspeer 			ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src;
1147a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1148a3c5bd6dSspeer 			ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst;
1149a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1150a3c5bd6dSspeer 			ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc;
1151a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1152a3c5bd6dSspeer 			ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst;
1153a3c5bd6dSspeer 		break;
1154a3c5bd6dSspeer 
1155a3c5bd6dSspeer 	default:
1156a3c5bd6dSspeer 		return (NXGE_ERROR);
115744961713Sgirish 	}
115844961713Sgirish 
115944961713Sgirish 	*H1 = nxge_compute_h1(p_class_cfgp->init_h1,
1160*52ccf843Smisaki 	    (uint32_t *)&ft, ft_size) & 0xfffff;
116144961713Sgirish 	*H2 = nxge_compute_h2(p_class_cfgp->init_h2,
1162*52ccf843Smisaki 	    (uint8_t *)&ft, ft_size);
116344961713Sgirish 
116444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash"));
116544961713Sgirish 	return (NXGE_OK);
116644961713Sgirish }
116744961713Sgirish 
116844961713Sgirish nxge_status_t
116944961713Sgirish nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
117044961713Sgirish {
117144961713Sgirish 	uint32_t H1;
117244961713Sgirish 	uint16_t H2;
117344961713Sgirish 	nxge_status_t status = NXGE_OK;
117444961713Sgirish 
117544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry"));
117644961713Sgirish 	status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2);
117744961713Sgirish 	if (status != NXGE_OK) {
117844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1179*52ccf843Smisaki 		    " nxge_add_fcram_entry failed "));
118044961713Sgirish 		return (status);
118144961713Sgirish 	}
118244961713Sgirish 
118344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry"));
118444961713Sgirish 	return (NXGE_OK);
118544961713Sgirish }
118644961713Sgirish 
118744961713Sgirish /*
118844961713Sgirish  * Already decided this flow goes into the tcam
118944961713Sgirish  */
119044961713Sgirish 
119144961713Sgirish nxge_status_t
119244961713Sgirish nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
119344961713Sgirish {
119444961713Sgirish 	npi_handle_t handle;
119544961713Sgirish 	intptr_t channel_cookie;
119644961713Sgirish 	intptr_t flow_cookie;
119744961713Sgirish 	flow_spec_t *flow_spec;
119844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
119944961713Sgirish 	tcam_entry_t tcam_ptr;
120044961713Sgirish 	tcam_location_t location = 0;
120144961713Sgirish 	uint8_t offset, rdc_grp;
1202a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
120344961713Sgirish 
120444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry"));
120544961713Sgirish 	handle = nxgep->npi_reg_handle;
120644961713Sgirish 
1207a3c5bd6dSspeer 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
120844961713Sgirish 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
120944961713Sgirish 	flow_cookie = flow_res->flow_cookie;
121044961713Sgirish 	channel_cookie = flow_res->channel_cookie;
121144961713Sgirish 
121244961713Sgirish 	switch (flow_spec->flow_type) {
1213a3c5bd6dSspeer 	case FSPEC_TCPIP4:
1214a3c5bd6dSspeer 		nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr);
1215a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1216*52ccf843Smisaki 		    TCAM_CLASS_TCP_IPV4);
1217a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4,
1218*52ccf843Smisaki 		    flow_cookie);
1219a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4,
1220*52ccf843Smisaki 		    channel_cookie);
1221a3c5bd6dSspeer 		break;
1222a3c5bd6dSspeer 
1223a3c5bd6dSspeer 	case FSPEC_UDPIP4:
1224a3c5bd6dSspeer 		nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr);
1225a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1226*52ccf843Smisaki 		    TCAM_CLASS_UDP_IPV4);
1227a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
1228*52ccf843Smisaki 		    TCAM_CLASS_UDP_IPV4,
1229*52ccf843Smisaki 		    flow_cookie);
1230a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
1231*52ccf843Smisaki 		    TCAM_CLASS_UDP_IPV4,
1232*52ccf843Smisaki 		    channel_cookie);
1233a3c5bd6dSspeer 		break;
1234a3c5bd6dSspeer 
1235a3c5bd6dSspeer 	case FSPEC_TCPIP6:
1236a3c5bd6dSspeer 		nxge_fill_tcam_entry_tcp_ipv6(nxgep,
1237*52ccf843Smisaki 		    flow_spec, &tcam_ptr);
1238a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1239*52ccf843Smisaki 		    TCAM_CLASS_TCP_IPV6);
1240a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6,
1241*52ccf843Smisaki 		    flow_cookie);
1242a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6,
1243*52ccf843Smisaki 		    channel_cookie);
1244a3c5bd6dSspeer 		break;
1245a3c5bd6dSspeer 
1246a3c5bd6dSspeer 	case FSPEC_UDPIP6:
1247a3c5bd6dSspeer 		nxge_fill_tcam_entry_udp_ipv6(nxgep,
1248*52ccf843Smisaki 		    flow_spec, &tcam_ptr);
1249a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1250*52ccf843Smisaki 		    TCAM_CLASS_UDP_IPV6);
1251a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
1252*52ccf843Smisaki 		    TCAM_CLASS_UDP_IPV6,
1253*52ccf843Smisaki 		    channel_cookie);
1254a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
1255*52ccf843Smisaki 		    TCAM_CLASS_UDP_IPV6,
1256*52ccf843Smisaki 		    flow_cookie);
1257a3c5bd6dSspeer 		break;
1258a3c5bd6dSspeer 
1259a3c5bd6dSspeer 	case FSPEC_SCTPIP4:
1260a3c5bd6dSspeer 		nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr);
1261a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1262*52ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV4);
1263a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
1264*52ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV4,
1265*52ccf843Smisaki 		    channel_cookie);
1266a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
1267*52ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV4,
1268*52ccf843Smisaki 		    flow_cookie);
1269a3c5bd6dSspeer 		break;
1270a3c5bd6dSspeer 
1271a3c5bd6dSspeer 	case FSPEC_SCTPIP6:
1272a3c5bd6dSspeer 		nxge_fill_tcam_entry_sctp_ipv6(nxgep,
1273*52ccf843Smisaki 		    flow_spec, &tcam_ptr);
1274a3c5bd6dSspeer 		location = nxge_get_tcam_location(nxgep,
1275*52ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV4);
1276a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
1277*52ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV6,
1278*52ccf843Smisaki 		    channel_cookie);
1279a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
1280*52ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV6,
1281*52ccf843Smisaki 		    flow_cookie);
1282a3c5bd6dSspeer 		break;
1283a3c5bd6dSspeer 
1284a3c5bd6dSspeer 	default:
1285a3c5bd6dSspeer 		return (NXGE_OK);
128644961713Sgirish 	}
128744961713Sgirish 
128844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1289*52ccf843Smisaki 	    " nxge_add_tcam_entry write"
1290*52ccf843Smisaki 	    " for location %d offset %d", location, offset));
129144961713Sgirish 
129244961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
129344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1294*52ccf843Smisaki 		    " nxge_add_tcam_entry: common hardware not set",
1295*52ccf843Smisaki 		    nxgep->niu_type));
129644961713Sgirish 		return (NXGE_ERROR);
129744961713Sgirish 	}
1298a3c5bd6dSspeer 
129944961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
1300a3c5bd6dSspeer 	rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr);
130144961713Sgirish 
130244961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
130344961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
130444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1305*52ccf843Smisaki 		    " nxge_add_tcam_entry write"
1306*52ccf843Smisaki 		    " failed for location %d", location));
130744961713Sgirish 		return (NXGE_ERROR | rs);
130844961713Sgirish 	}
1309a3c5bd6dSspeer 
131044961713Sgirish 	tcam_ptr.match_action.value = 0;
131144961713Sgirish 	tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp;
131244961713Sgirish 	tcam_ptr.match_action.bits.ldw.offset = offset;
131344961713Sgirish 	tcam_ptr.match_action.bits.ldw.tres =
1314*52ccf843Smisaki 	    TRES_TERM_OVRD_L2RDC;
131544961713Sgirish 	if (channel_cookie == -1)
131644961713Sgirish 		tcam_ptr.match_action.bits.ldw.disc = 1;
131744961713Sgirish 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
1318*52ccf843Smisaki 	    location, tcam_ptr.match_action.value);
131944961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
132044961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
132144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1322*52ccf843Smisaki 		    " nxge_add_tcam_entry write"
1323*52ccf843Smisaki 		    " failed for ASC RAM location %d", location));
132444961713Sgirish 		return (NXGE_ERROR | rs);
132544961713Sgirish 	}
1326a3c5bd6dSspeer 	bcopy((void *) &tcam_ptr,
1327*52ccf843Smisaki 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
1328*52ccf843Smisaki 	    sizeof (tcam_entry_t));
132944961713Sgirish 
133044961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
133144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry"));
133244961713Sgirish 	return (NXGE_OK);
133344961713Sgirish }
133444961713Sgirish 
133514ea4bb7Ssd static nxge_status_t
133614ea4bb7Ssd nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)
133744961713Sgirish {
133844961713Sgirish 	tcam_entry_t tcam_ptr;
133944961713Sgirish 	tcam_location_t location;
134044961713Sgirish 	uint8_t class;
134114ea4bb7Ssd 	uint32_t class_config;
134244961713Sgirish 	npi_handle_t handle;
134344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1344a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
134514ea4bb7Ssd 	nxge_status_t status = NXGE_OK;
134644961713Sgirish 
134744961713Sgirish 	handle = nxgep->npi_reg_handle;
134844961713Sgirish 	class = 0;
1349a3c5bd6dSspeer 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
135044961713Sgirish 	tcam_ptr.ip4_noport_key = 1;
135144961713Sgirish 	tcam_ptr.ip4_noport_mask = 1;
135214ea4bb7Ssd 	location = nxgep->function_num;
135344961713Sgirish 	nxgep->classifier.fragment_bug_location = location;
135444961713Sgirish 
135544961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
135644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1357*52ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment: common hardware not set",
1358*52ccf843Smisaki 		    nxgep->niu_type));
135914ea4bb7Ssd 		return (NXGE_ERROR);
136044961713Sgirish 	}
136144961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
136244961713Sgirish 	rs = npi_fflp_tcam_entry_write(handle,
1363*52ccf843Smisaki 	    location, &tcam_ptr);
136444961713Sgirish 
136544961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
136644961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
136744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1368*52ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment "
1369*52ccf843Smisaki 		    " tcam_entry write"
1370*52ccf843Smisaki 		    " failed for location %d", location));
137114ea4bb7Ssd 		return (NXGE_ERROR);
137244961713Sgirish 	}
137344961713Sgirish 	tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp;
1374a3c5bd6dSspeer 	tcam_ptr.match_action.bits.ldw.offset = 0;	/* use the default */
137544961713Sgirish 	tcam_ptr.match_action.bits.ldw.tres =
1376*52ccf843Smisaki 	    TRES_TERM_USE_OFFSET;
137744961713Sgirish 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
1378*52ccf843Smisaki 	    location, tcam_ptr.match_action.value);
137944961713Sgirish 
138044961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
138144961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
138244961713Sgirish 		NXGE_DEBUG_MSG((nxgep,
1383*52ccf843Smisaki 		    FFLP_CTL,
1384*52ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment "
1385*52ccf843Smisaki 		    " tcam_entry write"
1386*52ccf843Smisaki 		    " failed for ASC RAM location %d", location));
138714ea4bb7Ssd 		return (NXGE_ERROR);
138844961713Sgirish 	}
1389a3c5bd6dSspeer 	bcopy((void *) &tcam_ptr,
1390*52ccf843Smisaki 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
1391*52ccf843Smisaki 	    sizeof (tcam_entry_t));
139214ea4bb7Ssd 	for (class = TCAM_CLASS_TCP_IPV4;
1393*52ccf843Smisaki 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
139414ea4bb7Ssd 		class_config = nxgep->class_config.class_cfg[class];
139514ea4bb7Ssd 		class_config |= NXGE_CLASS_TCAM_LOOKUP;
139614ea4bb7Ssd 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
139714ea4bb7Ssd 
139814ea4bb7Ssd 		if (status & NPI_FFLP_ERROR) {
139914ea4bb7Ssd 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
140014ea4bb7Ssd 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1401*52ccf843Smisaki 			    "nxge_tcam_handle_ip_fragment "
1402*52ccf843Smisaki 			    "nxge_fflp_ip_class_config failed "
1403*52ccf843Smisaki 			    " class %d config %x ", class, class_config));
140414ea4bb7Ssd 			return (NXGE_ERROR);
140514ea4bb7Ssd 		}
140614ea4bb7Ssd 	}
140714ea4bb7Ssd 
140814ea4bb7Ssd 	rs = npi_fflp_cfg_tcam_enable(handle);
140914ea4bb7Ssd 	if (rs & NPI_FFLP_ERROR) {
141014ea4bb7Ssd 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
141114ea4bb7Ssd 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1412*52ccf843Smisaki 		    "nxge_tcam_handle_ip_fragment "
1413*52ccf843Smisaki 		    " nxge_fflp_config_tcam_enable failed"));
141414ea4bb7Ssd 		return (NXGE_ERROR);
141514ea4bb7Ssd 	}
141644961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
141714ea4bb7Ssd 	return (NXGE_OK);
141844961713Sgirish }
141944961713Sgirish 
142044961713Sgirish /* ARGSUSED */
142144961713Sgirish static int
1422a3c5bd6dSspeer nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res)
142344961713Sgirish {
142444961713Sgirish 	return (0);
142544961713Sgirish }
142644961713Sgirish 
142744961713Sgirish nxge_status_t
142844961713Sgirish nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res)
142944961713Sgirish {
143044961713Sgirish 
143144961713Sgirish 	int insert_hash = 0;
143244961713Sgirish 	nxge_status_t status = NXGE_OK;
143344961713Sgirish 
14342e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
1435a3c5bd6dSspeer 		/* determine whether to do TCAM or Hash flow */
143644961713Sgirish 		insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res);
143744961713Sgirish 	}
143844961713Sgirish 	if (insert_hash) {
143944961713Sgirish 		status = nxge_add_fcram_entry(nxgep, flow_res);
144044961713Sgirish 	} else {
144144961713Sgirish 		status = nxge_add_tcam_entry(nxgep, flow_res);
144244961713Sgirish 	}
144344961713Sgirish 	return (status);
144444961713Sgirish }
144544961713Sgirish 
144644961713Sgirish void
144744961713Sgirish nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp)
144844961713Sgirish {
144944961713Sgirish 	flow_resource_t *fs;
145044961713Sgirish 
1451a3c5bd6dSspeer 	fs = (flow_resource_t *)mp->b_rptr;
145244961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1453*52ccf843Smisaki 	    "nxge_put_tcam addr fs $%p  type %x offset %x",
1454*52ccf843Smisaki 	    fs, fs->flow_spec.flow_type, fs->channel_cookie));
145544961713Sgirish 	(void) nxge_add_tcam_entry(nxgep, fs);
145644961713Sgirish }
145744961713Sgirish 
145844961713Sgirish nxge_status_t
145944961713Sgirish nxge_fflp_config_tcam_enable(p_nxge_t nxgep)
146044961713Sgirish {
146144961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
146244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
146344961713Sgirish 
146444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable"));
146544961713Sgirish 	rs = npi_fflp_cfg_tcam_enable(handle);
146644961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
146744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1468*52ccf843Smisaki 		    " nxge_fflp_config_tcam_enable failed"));
146944961713Sgirish 		return (NXGE_ERROR | rs);
147044961713Sgirish 	}
147144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable"));
147244961713Sgirish 	return (NXGE_OK);
147344961713Sgirish }
147444961713Sgirish 
147544961713Sgirish nxge_status_t
147644961713Sgirish nxge_fflp_config_tcam_disable(p_nxge_t nxgep)
147744961713Sgirish {
147844961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
147944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
148044961713Sgirish 
148144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1482*52ccf843Smisaki 	    " ==> nxge_fflp_config_tcam_disable"));
148344961713Sgirish 	rs = npi_fflp_cfg_tcam_disable(handle);
148444961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
148544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1486*52ccf843Smisaki 		    " nxge_fflp_config_tcam_disable failed"));
148744961713Sgirish 		return (NXGE_ERROR | rs);
148844961713Sgirish 	}
148944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1490*52ccf843Smisaki 	    " <== nxge_fflp_config_tcam_disable"));
149144961713Sgirish 	return (NXGE_OK);
149244961713Sgirish }
149344961713Sgirish 
149444961713Sgirish nxge_status_t
149544961713Sgirish nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)
149644961713Sgirish {
149744961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
149844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1499a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1500a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1501a3c5bd6dSspeer 	uint8_t partition;
150244961713Sgirish 
150344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1504*52ccf843Smisaki 	    " ==> nxge_fflp_config_hash_lookup_enable"));
150544961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
150644961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
150744961713Sgirish 
1508678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1509678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
1510678453a8Sspeer 			rs = npi_fflp_cfg_fcram_partition_enable(
1511*52ccf843Smisaki 			    handle, partition);
1512678453a8Sspeer 			if (rs != NPI_SUCCESS) {
1513678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1514678453a8Sspeer 				    " nxge_fflp_config_hash_lookup_enable"
1515678453a8Sspeer 				    "failed FCRAM partition"
1516678453a8Sspeer 				    " enable for partition %d ", partition));
1517678453a8Sspeer 				return (NXGE_ERROR | rs);
1518678453a8Sspeer 			}
151944961713Sgirish 		}
152044961713Sgirish 	}
152144961713Sgirish 
152244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1523*52ccf843Smisaki 	    " <== nxge_fflp_config_hash_lookup_enable"));
152444961713Sgirish 	return (NXGE_OK);
152544961713Sgirish }
152644961713Sgirish 
152744961713Sgirish nxge_status_t
152844961713Sgirish nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)
152944961713Sgirish {
153044961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
153144961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1532a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1533a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1534a3c5bd6dSspeer 	uint8_t partition;
153544961713Sgirish 
153644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1537*52ccf843Smisaki 	    " ==> nxge_fflp_config_hash_lookup_disable"));
153844961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
153944961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
154044961713Sgirish 
1541678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1542678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
1543678453a8Sspeer 			rs = npi_fflp_cfg_fcram_partition_disable(handle,
1544678453a8Sspeer 			    partition);
1545678453a8Sspeer 			if (rs != NPI_SUCCESS) {
1546678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1547678453a8Sspeer 				    " nxge_fflp_config_hash_lookup_disable"
1548678453a8Sspeer 				    " failed FCRAM partition"
1549678453a8Sspeer 				    " disable for partition %d ", partition));
1550678453a8Sspeer 				return (NXGE_ERROR | rs);
1551678453a8Sspeer 			}
155244961713Sgirish 		}
155344961713Sgirish 	}
155444961713Sgirish 
155544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1556*52ccf843Smisaki 	    " <== nxge_fflp_config_hash_lookup_disable"));
155744961713Sgirish 	return (NXGE_OK);
155844961713Sgirish }
155944961713Sgirish 
156044961713Sgirish nxge_status_t
156144961713Sgirish nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)
156244961713Sgirish {
156344961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
156444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
156544961713Sgirish 
156644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1567*52ccf843Smisaki 	    " ==> nxge_fflp_config_llc_snap_enable"));
156844961713Sgirish 	rs = npi_fflp_cfg_llcsnap_enable(handle);
156944961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
157044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1571*52ccf843Smisaki 		    " nxge_fflp_config_llc_snap_enable failed"));
157244961713Sgirish 		return (NXGE_ERROR | rs);
157344961713Sgirish 	}
157444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1575*52ccf843Smisaki 	    " <== nxge_fflp_config_llc_snap_enable"));
157644961713Sgirish 	return (NXGE_OK);
157744961713Sgirish }
157844961713Sgirish 
157944961713Sgirish nxge_status_t
158044961713Sgirish nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)
158144961713Sgirish {
158244961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
158344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1584a3c5bd6dSspeer 
158544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1586*52ccf843Smisaki 	    " ==> nxge_fflp_config_llc_snap_disable"));
158744961713Sgirish 	rs = npi_fflp_cfg_llcsnap_disable(handle);
158844961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
158944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1590*52ccf843Smisaki 		    " nxge_fflp_config_llc_snap_disable failed"));
159144961713Sgirish 		return (NXGE_ERROR | rs);
159244961713Sgirish 	}
159344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1594*52ccf843Smisaki 	    " <== nxge_fflp_config_llc_snap_disable"));
159544961713Sgirish 	return (NXGE_OK);
159644961713Sgirish }
159744961713Sgirish 
159844961713Sgirish nxge_status_t
159944961713Sgirish nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class,
1600a3c5bd6dSspeer 	uint32_t config)
160144961713Sgirish {
160244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
160344961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
160444961713Sgirish 	uint8_t tos, tos_mask, proto, ver = 0;
160544961713Sgirish 	uint8_t class_enable = 0;
160644961713Sgirish 
160744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config"));
160844961713Sgirish 
160944961713Sgirish 	tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >>
1610*52ccf843Smisaki 	    NXGE_CLASS_CFG_IP_TOS_SHIFT;
161144961713Sgirish 	tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >>
1612*52ccf843Smisaki 	    NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT;
161344961713Sgirish 	proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >>
1614*52ccf843Smisaki 	    NXGE_CLASS_CFG_IP_PROTO_SHIFT;
161544961713Sgirish 	if (config & NXGE_CLASS_CFG_IP_IPV6_MASK)
161644961713Sgirish 		ver = 1;
161744961713Sgirish 	if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK)
161844961713Sgirish 		class_enable = 1;
161944961713Sgirish 	rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask,
1620*52ccf843Smisaki 	    proto, ver);
162144961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
162244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1623*52ccf843Smisaki 		    " nxge_fflp_ip_usr_class_config"
1624*52ccf843Smisaki 		    " for class %d failed ", class));
162544961713Sgirish 		return (NXGE_ERROR | rs);
162644961713Sgirish 	}
162744961713Sgirish 	if (class_enable)
162844961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class);
162944961713Sgirish 	else
163044961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
163144961713Sgirish 
163244961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
163344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1634*52ccf843Smisaki 		    " nxge_fflp_ip_usr_class_config"
1635*52ccf843Smisaki 		    " TCAM enable/disable for class %d failed ", class));
163644961713Sgirish 		return (NXGE_ERROR | rs);
163744961713Sgirish 	}
163844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config"));
163944961713Sgirish 	return (NXGE_OK);
164044961713Sgirish }
164144961713Sgirish 
164244961713Sgirish nxge_status_t
1643a3c5bd6dSspeer nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config)
164444961713Sgirish {
164544961713Sgirish 	uint32_t class_config;
164644961713Sgirish 	nxge_status_t t_status = NXGE_OK;
164744961713Sgirish 	nxge_status_t f_status = NXGE_OK;
1648a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
164944961713Sgirish 
165044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
1651a3c5bd6dSspeer 
165244961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
165344961713Sgirish 	class_config = p_class_cfgp->class_cfg[class];
165444961713Sgirish 
165544961713Sgirish 	if (class_config != config) {
165644961713Sgirish 		p_class_cfgp->class_cfg[class] = config;
165744961713Sgirish 		class_config = config;
165844961713Sgirish 	}
165944961713Sgirish 
166044961713Sgirish 	t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config);
166144961713Sgirish 	f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config);
166244961713Sgirish 
166344961713Sgirish 	if (t_status & NPI_FFLP_ERROR) {
166444961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1665*52ccf843Smisaki 		    " nxge_fflp_ip_class_config %x"
1666*52ccf843Smisaki 		    " for class %d tcam failed", config, class));
166744961713Sgirish 		return (t_status);
166844961713Sgirish 	}
166944961713Sgirish 	if (f_status & NPI_FFLP_ERROR) {
167044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1671*52ccf843Smisaki 		    " nxge_fflp_ip_class_config %x"
1672*52ccf843Smisaki 		    " for class %d flow key failed", config, class));
167344961713Sgirish 		return (f_status);
167444961713Sgirish 	}
167544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
167644961713Sgirish 	return (NXGE_OK);
167744961713Sgirish }
167844961713Sgirish 
167944961713Sgirish nxge_status_t
168044961713Sgirish nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class,
1681a3c5bd6dSspeer 	uint32_t *config)
168244961713Sgirish {
168344961713Sgirish 	uint32_t t_class_config, f_class_config;
168444961713Sgirish 	int t_status = NXGE_OK;
168544961713Sgirish 	int f_status = NXGE_OK;
168644961713Sgirish 
168744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
1688a3c5bd6dSspeer 
168944961713Sgirish 	t_class_config = f_class_config = 0;
169044961713Sgirish 	t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config);
169144961713Sgirish 	f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config);
169244961713Sgirish 
169344961713Sgirish 	if (t_status & NPI_FFLP_ERROR) {
169444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1695*52ccf843Smisaki 		    " nxge_fflp_ip_class_config_get  "
1696*52ccf843Smisaki 		    " for class %d tcam failed", class));
169744961713Sgirish 		return (t_status);
169844961713Sgirish 	}
169944961713Sgirish 
170044961713Sgirish 	if (f_status & NPI_FFLP_ERROR) {
170144961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1702*52ccf843Smisaki 		    " nxge_fflp_ip_class_config_get  "
1703*52ccf843Smisaki 		    " for class %d flow key failed", class));
170444961713Sgirish 		return (f_status);
170544961713Sgirish 	}
170644961713Sgirish 
170744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1708*52ccf843Smisaki 	    " nxge_fflp_ip_class_config tcam %x flow %x",
1709*52ccf843Smisaki 	    t_class_config, f_class_config));
171044961713Sgirish 
171144961713Sgirish 	*config = t_class_config | f_class_config;
171244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get"));
171344961713Sgirish 	return (NXGE_OK);
171444961713Sgirish }
171544961713Sgirish 
171644961713Sgirish nxge_status_t
171744961713Sgirish nxge_fflp_ip_class_config_all(p_nxge_t nxgep)
171844961713Sgirish {
171944961713Sgirish 	uint32_t class_config;
172044961713Sgirish 	tcam_class_t class;
172144961713Sgirish 
172244961713Sgirish #ifdef	NXGE_DEBUG
172344961713Sgirish 	int status = NXGE_OK;
172444961713Sgirish #endif
172544961713Sgirish 
172644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config"));
172744961713Sgirish 	for (class = TCAM_CLASS_TCP_IPV4;
1728*52ccf843Smisaki 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
172944961713Sgirish 		class_config = nxgep->class_config.class_cfg[class];
173044961713Sgirish #ifndef	NXGE_DEBUG
173144961713Sgirish 		(void) nxge_fflp_ip_class_config(nxgep, class, class_config);
173244961713Sgirish #else
173344961713Sgirish 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
173444961713Sgirish 		if (status & NPI_FFLP_ERROR) {
173544961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1736*52ccf843Smisaki 			    "nxge_fflp_ip_class_config failed "
1737*52ccf843Smisaki 			    " class %d config %x ",
1738*52ccf843Smisaki 			    class, class_config));
173944961713Sgirish 		}
174044961713Sgirish #endif
174144961713Sgirish 	}
174244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
174344961713Sgirish 	return (NXGE_OK);
174444961713Sgirish }
174544961713Sgirish 
174644961713Sgirish nxge_status_t
174744961713Sgirish nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id)
174844961713Sgirish {
174944961713Sgirish 	uint8_t port, rdc_grp;
175044961713Sgirish 	npi_handle_t handle;
175144961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
175244961713Sgirish 	uint8_t priority = 1;
175344961713Sgirish 	p_nxge_mv_cfg_t vlan_table;
1754a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1755a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
175644961713Sgirish 
175744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table"));
175844961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
175944961713Sgirish 	handle = nxgep->npi_reg_handle;
176044961713Sgirish 	vlan_table = p_class_cfgp->vlan_tbl;
176144961713Sgirish 	port = nxgep->function_num;
176244961713Sgirish 
176344961713Sgirish 	if (vlan_table[vlan_id].flag == 0) {
176444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1765*52ccf843Smisaki 		    " nxge_fflp_config_vlan_table"
1766*52ccf843Smisaki 		    " vlan id is not configured %d", vlan_id));
176744961713Sgirish 		return (NXGE_ERROR);
176844961713Sgirish 	}
176944961713Sgirish 
177044961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
177144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1772*52ccf843Smisaki 		    " nxge_fflp_config_vlan_table:"
1773*52ccf843Smisaki 		    " common hardware not set", nxgep->niu_type));
177444961713Sgirish 		return (NXGE_ERROR);
177544961713Sgirish 	}
177644961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_vlan_lock);
177744961713Sgirish 	rdc_grp = vlan_table[vlan_id].rdctbl;
177844961713Sgirish 	rs = npi_fflp_cfg_enet_vlan_table_assoc(handle,
1779*52ccf843Smisaki 	    port, vlan_id,
1780*52ccf843Smisaki 	    rdc_grp, priority);
178144961713Sgirish 
178244961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_vlan_lock);
178344961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
178444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1785*52ccf843Smisaki 		    "nxge_fflp_config_vlan_table failed "
1786*52ccf843Smisaki 		    " Port %d vlan_id %d rdc_grp %d",
1787*52ccf843Smisaki 		    port, vlan_id, rdc_grp));
178844961713Sgirish 		return (NXGE_ERROR | rs);
178944961713Sgirish 	}
1790a3c5bd6dSspeer 
179144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table"));
179244961713Sgirish 	return (NXGE_OK);
179344961713Sgirish }
179444961713Sgirish 
179544961713Sgirish nxge_status_t
179644961713Sgirish nxge_fflp_update_hw(p_nxge_t nxgep)
179744961713Sgirish {
179844961713Sgirish 	nxge_status_t status = NXGE_OK;
179944961713Sgirish 	p_nxge_param_t pa;
180044961713Sgirish 	uint64_t cfgd_vlans;
180144961713Sgirish 	uint64_t *val_ptr;
180244961713Sgirish 	int i;
180344961713Sgirish 	int num_macs;
180444961713Sgirish 	uint8_t alt_mac;
180544961713Sgirish 	nxge_param_map_t *p_map;
180644961713Sgirish 	p_nxge_mv_cfg_t vlan_table;
1807a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1808a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_all_cfgp;
1809a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
181044961713Sgirish 
181144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw"));
1812a3c5bd6dSspeer 
181344961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
181444961713Sgirish 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
181544961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
181644961713Sgirish 
181744961713Sgirish 	status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1);
181844961713Sgirish 	if (status != NXGE_OK) {
181944961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1820*52ccf843Smisaki 		    "nxge_fflp_set_hash1 Failed"));
182144961713Sgirish 		return (NXGE_ERROR);
182244961713Sgirish 	}
182344961713Sgirish 
182444961713Sgirish 	status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2);
182544961713Sgirish 	if (status != NXGE_OK) {
182644961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1827*52ccf843Smisaki 		    "nxge_fflp_set_hash2 Failed"));
182844961713Sgirish 		return (NXGE_ERROR);
182944961713Sgirish 	}
183044961713Sgirish 	vlan_table = p_class_cfgp->vlan_tbl;
183144961713Sgirish 
1832a3c5bd6dSspeer 	/* configure vlan tables */
183344961713Sgirish 	pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp];
1834adfcba55Sjoycey #if defined(__i386)
1835adfcba55Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
1836adfcba55Sjoycey #else
183744961713Sgirish 	val_ptr = (uint64_t *)pa->value;
1838adfcba55Sjoycey #endif
1839a3c5bd6dSspeer 	cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >>
1840*52ccf843Smisaki 	    NXGE_PARAM_ARRAY_CNT_SHIFT);
184144961713Sgirish 
184244961713Sgirish 	for (i = 0; i < cfgd_vlans; i++) {
184344961713Sgirish 		p_map = (nxge_param_map_t *)&val_ptr[i];
184444961713Sgirish 		if (vlan_table[p_map->param_id].flag) {
184544961713Sgirish 			status = nxge_fflp_config_vlan_table(nxgep,
1846*52ccf843Smisaki 			    p_map->param_id);
184744961713Sgirish 			if (status != NXGE_OK) {
184844961713Sgirish 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1849*52ccf843Smisaki 				    "nxge_fflp_config_vlan_table Failed"));
185044961713Sgirish 				return (NXGE_ERROR);
185144961713Sgirish 			}
185244961713Sgirish 		}
185344961713Sgirish 	}
1854a3c5bd6dSspeer 
1855a3c5bd6dSspeer 	/* config MAC addresses */
185644961713Sgirish 	num_macs = p_cfgp->max_macs;
185744961713Sgirish 	pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp];
1858adfcba55Sjoycey #if defined(__i386)
1859adfcba55Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
1860adfcba55Sjoycey #else
186144961713Sgirish 	val_ptr = (uint64_t *)pa->value;
1862adfcba55Sjoycey #endif
186344961713Sgirish 
186444961713Sgirish 	for (alt_mac = 0; alt_mac < num_macs; alt_mac++) {
186544961713Sgirish 		if (p_class_cfgp->mac_host_info[alt_mac].flag) {
186644961713Sgirish 			status = nxge_logical_mac_assign_rdc_table(nxgep,
1867*52ccf843Smisaki 			    alt_mac);
186844961713Sgirish 			if (status != NXGE_OK) {
186944961713Sgirish 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1870*52ccf843Smisaki 				    "nxge_logical_mac_assign_rdc_table"
1871*52ccf843Smisaki 				    " Failed"));
187244961713Sgirish 				return (NXGE_ERROR);
187344961713Sgirish 			}
187444961713Sgirish 		}
187544961713Sgirish 	}
1876a3c5bd6dSspeer 
1877a3c5bd6dSspeer 	/* Config Hash values */
1878f6485eecSyc 	/* config classes */
187944961713Sgirish 	status = nxge_fflp_ip_class_config_all(nxgep);
188044961713Sgirish 	if (status != NXGE_OK) {
188144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1882*52ccf843Smisaki 		    "nxge_fflp_ip_class_config_all Failed"));
188344961713Sgirish 		return (NXGE_ERROR);
188444961713Sgirish 	}
188544961713Sgirish 	return (NXGE_OK);
188644961713Sgirish }
188744961713Sgirish 
188844961713Sgirish nxge_status_t
188944961713Sgirish nxge_classify_init_hw(p_nxge_t nxgep)
189044961713Sgirish {
189144961713Sgirish 	nxge_status_t status = NXGE_OK;
189244961713Sgirish 
189344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw"));
189444961713Sgirish 
189544961713Sgirish 	if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) {
189644961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
1897*52ccf843Smisaki 		    "nxge_classify_init_hw already init"));
189844961713Sgirish 		return (NXGE_OK);
189944961713Sgirish 	}
190044961713Sgirish 
1901a3c5bd6dSspeer 	/* Now do a real configuration */
190244961713Sgirish 	status = nxge_fflp_update_hw(nxgep);
190344961713Sgirish 	if (status != NXGE_OK) {
190444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1905*52ccf843Smisaki 		    "nxge_fflp_update_hw failed"));
190644961713Sgirish 		return (NXGE_ERROR);
190744961713Sgirish 	}
1908a3c5bd6dSspeer 
1909a3c5bd6dSspeer 	/* Init RDC tables? ? who should do that? rxdma or fflp ? */
1910a3c5bd6dSspeer 	/* attach rdc table to the MAC port. */
191144961713Sgirish 	status = nxge_main_mac_assign_rdc_table(nxgep);
191244961713Sgirish 	if (status != NXGE_OK) {
191344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1914*52ccf843Smisaki 		    "nxge_main_mac_assign_rdc_table failed"));
191544961713Sgirish 		return (NXGE_ERROR);
191644961713Sgirish 	}
1917a3c5bd6dSspeer 
191858324dfcSspeer 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
191944961713Sgirish 	if (status != NXGE_OK) {
192044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1921*52ccf843Smisaki 		    "nxge_multicast_mac_assign_rdc_table failed"));
192244961713Sgirish 		return (NXGE_ERROR);
192344961713Sgirish 	}
192414ea4bb7Ssd 
192514ea4bb7Ssd 	status = nxge_tcam_handle_ip_fragment(nxgep);
192614ea4bb7Ssd 	if (status != NXGE_OK) {
192714ea4bb7Ssd 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1928*52ccf843Smisaki 		    "nxge_tcam_handle_ip_fragment failed"));
192914ea4bb7Ssd 		return (NXGE_ERROR);
193014ea4bb7Ssd 	}
193144961713Sgirish 
193244961713Sgirish 	nxgep->classifier.state |= NXGE_FFLP_HW_INIT;
193344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw"));
193444961713Sgirish 	return (NXGE_OK);
193544961713Sgirish }
193644961713Sgirish 
193744961713Sgirish nxge_status_t
193844961713Sgirish nxge_fflp_handle_sys_errors(p_nxge_t nxgep)
193944961713Sgirish {
1940a3c5bd6dSspeer 	npi_handle_t handle;
1941a3c5bd6dSspeer 	p_nxge_fflp_stats_t statsp;
1942a3c5bd6dSspeer 	uint8_t portn, rdc_grp;
1943a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1944a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1945a3c5bd6dSspeer 	vlan_par_err_t vlan_err;
1946a3c5bd6dSspeer 	tcam_err_t tcam_err;
1947a3c5bd6dSspeer 	hash_lookup_err_log1_t fcram1_err;
1948a3c5bd6dSspeer 	hash_lookup_err_log2_t fcram2_err;
1949a3c5bd6dSspeer 	hash_tbl_data_log_t fcram_err;
195044961713Sgirish 
195144961713Sgirish 	handle = nxgep->npi_handle;
195244961713Sgirish 	statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats;
195344961713Sgirish 	portn = nxgep->mac.portnum;
195444961713Sgirish 
195544961713Sgirish 	/*
1956a3c5bd6dSspeer 	 * need to read the fflp error registers to figure out what the error
1957a3c5bd6dSspeer 	 * is
195844961713Sgirish 	 */
195944961713Sgirish 	npi_fflp_vlan_error_get(handle, &vlan_err);
196044961713Sgirish 	npi_fflp_tcam_error_get(handle, &tcam_err);
196144961713Sgirish 
196244961713Sgirish 	if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) {
196344961713Sgirish 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
1964*52ccf843Smisaki 		    " vlan table parity error on port %d"
1965*52ccf843Smisaki 		    " addr: 0x%x data: 0x%x",
1966*52ccf843Smisaki 		    portn, vlan_err.bits.ldw.addr,
1967*52ccf843Smisaki 		    vlan_err.bits.ldw.data));
196844961713Sgirish 		statsp->vlan_parity_err++;
196944961713Sgirish 
197044961713Sgirish 		if (vlan_err.bits.ldw.m_err) {
197144961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
1972*52ccf843Smisaki 			    " vlan table multiple errors on port %d",
1973*52ccf843Smisaki 			    portn));
197444961713Sgirish 		}
197544961713Sgirish 		statsp->errlog.vlan = (uint32_t)vlan_err.value;
197644961713Sgirish 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
1977*52ccf843Smisaki 		    NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR);
197844961713Sgirish 		npi_fflp_vlan_error_clear(handle);
197944961713Sgirish 	}
198044961713Sgirish 
198144961713Sgirish 	if (tcam_err.bits.ldw.err) {
198244961713Sgirish 		if (tcam_err.bits.ldw.p_ecc != 0) {
198344961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
1984*52ccf843Smisaki 			    " TCAM ECC error on port %d"
1985*52ccf843Smisaki 			    " TCAM entry: 0x%x syndrome: 0x%x",
1986*52ccf843Smisaki 			    portn, tcam_err.bits.ldw.addr,
1987*52ccf843Smisaki 			    tcam_err.bits.ldw.syndrome));
198844961713Sgirish 			statsp->tcam_ecc_err++;
198944961713Sgirish 		} else {
199044961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
1991*52ccf843Smisaki 			    " TCAM Parity error on port %d"
1992*52ccf843Smisaki 			    " addr: 0x%x parity value: 0x%x",
1993*52ccf843Smisaki 			    portn, tcam_err.bits.ldw.addr,
1994*52ccf843Smisaki 			    tcam_err.bits.ldw.syndrome));
199544961713Sgirish 			statsp->tcam_parity_err++;
199644961713Sgirish 		}
199744961713Sgirish 
199844961713Sgirish 		if (tcam_err.bits.ldw.mult) {
199944961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
2000*52ccf843Smisaki 			    " TCAM Multiple errors on port %d", portn));
200144961713Sgirish 		} else {
200244961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
2003*52ccf843Smisaki 			    " TCAM PIO error on port %d", portn));
200444961713Sgirish 		}
200544961713Sgirish 
200644961713Sgirish 		statsp->errlog.tcam = (uint32_t)tcam_err.value;
200744961713Sgirish 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
2008*52ccf843Smisaki 		    NXGE_FM_EREPORT_FFLP_TCAM_ERR);
200944961713Sgirish 		npi_fflp_tcam_error_clear(handle);
201044961713Sgirish 	}
201144961713Sgirish 
201244961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
201344961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
201444961713Sgirish 
2015678453a8Sspeer 	for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) {
2016678453a8Sspeer 		if (p_cfgp->grpids[rdc_grp]) {
2017678453a8Sspeer 			npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp);
2018678453a8Sspeer 			if (fcram_err.bits.ldw.pio_err) {
2019678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, FFLP_CTL,
2020*52ccf843Smisaki 				    " FCRAM PIO ECC error on port %d"
2021*52ccf843Smisaki 				    " rdc group: %d Hash Table addr: 0x%x"
2022*52ccf843Smisaki 				    " syndrome: 0x%x",
2023*52ccf843Smisaki 				    portn, rdc_grp,
2024*52ccf843Smisaki 				    fcram_err.bits.ldw.fcram_addr,
2025*52ccf843Smisaki 				    fcram_err.bits.ldw.syndrome));
2026678453a8Sspeer 				statsp->hash_pio_err[rdc_grp]++;
2027678453a8Sspeer 				statsp->errlog.hash_pio[rdc_grp] =
2028678453a8Sspeer 				    (uint32_t)fcram_err.value;
2029678453a8Sspeer 				NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
2030678453a8Sspeer 				    NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR);
2031678453a8Sspeer 				npi_fflp_fcram_error_clear(handle, rdc_grp);
2032678453a8Sspeer 			}
203344961713Sgirish 		}
203444961713Sgirish 	}
203544961713Sgirish 
203644961713Sgirish 	npi_fflp_fcram_error_log1_get(handle, &fcram1_err);
203744961713Sgirish 	if (fcram1_err.bits.ldw.ecc_err) {
203844961713Sgirish 		char *multi_str = "";
203944961713Sgirish 		char *multi_bit_str = "";
2040a3c5bd6dSspeer 
204144961713Sgirish 		npi_fflp_fcram_error_log2_get(handle, &fcram2_err);
204244961713Sgirish 		if (fcram1_err.bits.ldw.mult_lk) {
204344961713Sgirish 			multi_str = "multiple";
204444961713Sgirish 		}
204544961713Sgirish 		if (fcram1_err.bits.ldw.mult_bit) {
204644961713Sgirish 			multi_bit_str = "multiple bits";
204744961713Sgirish 		}
2048f6485eecSyc 		statsp->hash_lookup_err++;
204944961713Sgirish 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
2050*52ccf843Smisaki 		    " FCRAM %s lookup %s ECC error on port %d"
2051*52ccf843Smisaki 		    " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x",
2052*52ccf843Smisaki 		    multi_str, multi_bit_str, portn,
2053*52ccf843Smisaki 		    fcram2_err.bits.ldw.h1,
2054*52ccf843Smisaki 		    fcram2_err.bits.ldw.subarea,
2055*52ccf843Smisaki 		    fcram2_err.bits.ldw.syndrome));
205644961713Sgirish 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
2057*52ccf843Smisaki 		    NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR);
205844961713Sgirish 	}
205944961713Sgirish 	statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value;
206044961713Sgirish 	statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value;
206144961713Sgirish 	return (NXGE_OK);
206244961713Sgirish }
2063