xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_fflp.c (revision 4df55fde)
144961713Sgirish /*
244961713Sgirish  * CDDL HEADER START
344961713Sgirish  *
444961713Sgirish  * The contents of this file are subject to the terms of the
544961713Sgirish  * Common Development and Distribution License (the "License").
644961713Sgirish  * You may not use this file except in compliance with the License.
744961713Sgirish  *
844961713Sgirish  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
944961713Sgirish  * or http://www.opensolaris.org/os/licensing.
1044961713Sgirish  * See the License for the specific language governing permissions
1144961713Sgirish  * and limitations under the License.
1244961713Sgirish  *
1344961713Sgirish  * When distributing Covered Code, include this CDDL HEADER in each
1444961713Sgirish  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1544961713Sgirish  * If applicable, add the following below this CDDL HEADER, with the
1644961713Sgirish  * fields enclosed by brackets "[]" replaced with your own identifying
1744961713Sgirish  * information: Portions Copyright [yyyy] [name of copyright owner]
1844961713Sgirish  *
1944961713Sgirish  * CDDL HEADER END
2044961713Sgirish  */
2144961713Sgirish /*
22*4df55fdeSJanie Lu  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2344961713Sgirish  * Use is subject to license terms.
2444961713Sgirish  */
2544961713Sgirish 
2644961713Sgirish #include <npi_fflp.h>
2744961713Sgirish #include <npi_mac.h>
2844961713Sgirish #include <nxge_defs.h>
2944961713Sgirish #include <nxge_flow.h>
3044961713Sgirish #include <nxge_fflp.h>
3144961713Sgirish #include <nxge_impl.h>
3244961713Sgirish #include <nxge_fflp_hash.h>
3344961713Sgirish #include <nxge_common.h>
3444961713Sgirish 
3544961713Sgirish 
36a3c5bd6dSspeer /*
37a3c5bd6dSspeer  * Function prototypes
38a3c5bd6dSspeer  */
3944961713Sgirish static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t);
4044961713Sgirish static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t);
4144961713Sgirish static nxge_status_t nxge_fflp_tcam_init(p_nxge_t);
4244961713Sgirish static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t);
4344961713Sgirish static nxge_status_t nxge_fflp_fcram_init(p_nxge_t);
4444961713Sgirish static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *);
45a3c5bd6dSspeer static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
46a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
47a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
4844961713Sgirish static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *,
49a3c5bd6dSspeer 	tcam_entry_t *);
50a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *,
51a3c5bd6dSspeer 	tcam_entry_t *);
52a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *,
53a3c5bd6dSspeer 	tcam_entry_t *);
54*4df55fdeSJanie Lu static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t);
55*4df55fdeSJanie Lu static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t);
56*4df55fdeSJanie Lu static uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t);
57*4df55fdeSJanie Lu static uint32_t nxge_tcam_cls_to_flow(uint32_t);
58*4df55fdeSJanie Lu static uint8_t nxge_iptun_pkt_type_to_pid(uint8_t);
59*4df55fdeSJanie Lu static npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t,
60*4df55fdeSJanie Lu 					iptun_cfg_t *);
61*4df55fdeSJanie Lu static boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *);
6244961713Sgirish 
63a3c5bd6dSspeer /*
64a3c5bd6dSspeer  * functions used outside this file
65a3c5bd6dSspeer  */
6644961713Sgirish nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t);
6744961713Sgirish nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t);
6844961713Sgirish nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *);
6914ea4bb7Ssd static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t);
7044961713Sgirish nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *);
7144961713Sgirish nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *);
7244961713Sgirish nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *,
73a3c5bd6dSspeer 	uint32_t *, uint16_t *);
74*4df55fdeSJanie Lu int nxge_get_valid_tcam_cnt(p_nxge_t);
75*4df55fdeSJanie Lu void nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *);
76*4df55fdeSJanie Lu void nxge_get_tcam_entry(p_nxge_t, flow_resource_t *);
77*4df55fdeSJanie Lu void nxge_del_tcam_entry(p_nxge_t, uint32_t);
78*4df55fdeSJanie Lu void nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *);
79*4df55fdeSJanie Lu void nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t);
80*4df55fdeSJanie Lu void nxge_del_iptun_class(p_nxge_t, uint8_t);
81*4df55fdeSJanie Lu void nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t);
82*4df55fdeSJanie Lu void nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t);
83*4df55fdeSJanie Lu void nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *);
84*4df55fdeSJanie Lu 
8544961713Sgirish 
8644961713Sgirish nxge_status_t
8744961713Sgirish nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location)
8844961713Sgirish {
8944961713Sgirish 	tcam_entry_t tcam_rdptr;
9044961713Sgirish 	uint64_t asc_ram = 0;
9144961713Sgirish 	npi_handle_t handle;
9244961713Sgirish 	npi_status_t status;
9344961713Sgirish 
9444961713Sgirish 	handle = nxgep->npi_reg_handle;
9544961713Sgirish 
9644961713Sgirish 	bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry));
9744961713Sgirish 	status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location,
9852ccf843Smisaki 	    (struct tcam_entry *)&tcam_rdptr);
9944961713Sgirish 	if (status & NPI_FAILURE) {
10044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
10152ccf843Smisaki 		    " nxge_tcam_dump_entry:"
10252ccf843Smisaki 		    "  tcam read failed at location %d ", location));
10344961713Sgirish 		return (NXGE_ERROR);
10444961713Sgirish 	}
10544961713Sgirish 	status = npi_fflp_tcam_asc_ram_entry_read(handle,
10652ccf843Smisaki 	    (tcam_location_t)location, &asc_ram);
10744961713Sgirish 
10844961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n"
10952ccf843Smisaki 	    " key:  %llx %llx %llx %llx \n"
11052ccf843Smisaki 	    " mask: %llx %llx %llx %llx \n"
11152ccf843Smisaki 	    " ASC RAM %llx \n", location,
11252ccf843Smisaki 	    tcam_rdptr.key0, tcam_rdptr.key1,
11352ccf843Smisaki 	    tcam_rdptr.key2, tcam_rdptr.key3,
11452ccf843Smisaki 	    tcam_rdptr.mask0, tcam_rdptr.mask1,
11552ccf843Smisaki 	    tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram));
11644961713Sgirish 	return (NXGE_OK);
11744961713Sgirish }
11844961713Sgirish 
11944961713Sgirish void
12044961713Sgirish nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp)
12144961713Sgirish {
12244961713Sgirish 	uint32_t tcam_loc;
12344961713Sgirish 	int *lptr;
12444961713Sgirish 	int location;
12544961713Sgirish 
12644961713Sgirish 	uint32_t start_location = 0;
12744961713Sgirish 	uint32_t stop_location = nxgep->classifier.tcam_size;
12844961713Sgirish 	lptr = (int *)mp->b_rptr;
12944961713Sgirish 	location = *lptr;
13044961713Sgirish 
13144961713Sgirish 	if ((location >= nxgep->classifier.tcam_size) || (location < -1)) {
13244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13352ccf843Smisaki 		    "nxge_tcam_dump: Invalid location %d \n", location));
13444961713Sgirish 		return;
13544961713Sgirish 	}
13644961713Sgirish 	if (location == -1) {
13744961713Sgirish 		start_location = 0;
13844961713Sgirish 		stop_location = nxgep->classifier.tcam_size;
13944961713Sgirish 	} else {
14044961713Sgirish 		start_location = location;
141a3c5bd6dSspeer 		stop_location = location + 1;
14244961713Sgirish 	}
14344961713Sgirish 	for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++)
14444961713Sgirish 		(void) nxge_tcam_dump_entry(nxgep, tcam_loc);
14544961713Sgirish }
14644961713Sgirish 
14744961713Sgirish /*
14844961713Sgirish  * nxge_fflp_vlan_table_invalidate_all
14944961713Sgirish  * invalidates the vlan RDC table entries.
15044961713Sgirish  * INPUT
15144961713Sgirish  * nxge    soft state data structure
15244961713Sgirish  * Return
15344961713Sgirish  *      NXGE_OK
15444961713Sgirish  *      NXGE_ERROR
15544961713Sgirish  *
15644961713Sgirish  */
157a3c5bd6dSspeer 
15844961713Sgirish static nxge_status_t
15944961713Sgirish nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)
16044961713Sgirish {
16144961713Sgirish 	vlan_id_t vlan_id;
16244961713Sgirish 	npi_handle_t handle;
16344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
16444961713Sgirish 	vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
16544961713Sgirish 
16644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all "));
16744961713Sgirish 	handle = nxgep->npi_reg_handle;
16844961713Sgirish 	for (vlan_id = start; vlan_id < stop; vlan_id++) {
16944961713Sgirish 		rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id);
17044961713Sgirish 		if (rs != NPI_SUCCESS) {
17144961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17252ccf843Smisaki 			    "VLAN Table invalidate failed for vlan id %d ",
17352ccf843Smisaki 			    vlan_id));
17444961713Sgirish 			return (NXGE_ERROR | rs);
17544961713Sgirish 		}
17644961713Sgirish 	}
17744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all "));
17844961713Sgirish 	return (NXGE_OK);
17944961713Sgirish }
18044961713Sgirish 
18144961713Sgirish /*
18244961713Sgirish  * The following functions are used by other modules to init
18344961713Sgirish  * the fflp module.
18444961713Sgirish  * these functions are the basic API used to init
18544961713Sgirish  * the fflp modules (tcam, fcram etc ......)
18644961713Sgirish  *
18744961713Sgirish  * The TCAM search future would be disabled  by default.
18844961713Sgirish  */
18944961713Sgirish 
19044961713Sgirish static nxge_status_t
19144961713Sgirish nxge_fflp_tcam_init(p_nxge_t nxgep)
19244961713Sgirish {
19344961713Sgirish 	uint8_t access_ratio;
19444961713Sgirish 	tcam_class_t class;
19544961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
19644961713Sgirish 	npi_handle_t handle;
19744961713Sgirish 
19844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init"));
19944961713Sgirish 	handle = nxgep->npi_reg_handle;
20044961713Sgirish 
20144961713Sgirish 	rs = npi_fflp_cfg_tcam_disable(handle);
20244961713Sgirish 	if (rs != NPI_SUCCESS) {
20344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n"));
20444961713Sgirish 		return (NXGE_ERROR | rs);
20544961713Sgirish 	}
20644961713Sgirish 
20744961713Sgirish 	access_ratio = nxgep->param_arr[param_tcam_access_ratio].value;
20844961713Sgirish 	rs = npi_fflp_cfg_tcam_access(handle, access_ratio);
20944961713Sgirish 	if (rs != NPI_SUCCESS) {
21044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21152ccf843Smisaki 		    "failed TCAM Access cfg\n"));
21244961713Sgirish 		return (NXGE_ERROR | rs);
21344961713Sgirish 	}
21444961713Sgirish 
215a3c5bd6dSspeer 	/* disable configurable classes */
216a3c5bd6dSspeer 	/* disable the configurable ethernet classes; */
21744961713Sgirish 	for (class = TCAM_CLASS_ETYPE_1;
21852ccf843Smisaki 	    class <= TCAM_CLASS_ETYPE_2; class++) {
21944961713Sgirish 		rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class);
22044961713Sgirish 		if (rs != NPI_SUCCESS) {
22144961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
22252ccf843Smisaki 			    "TCAM USR Ether Class config failed."));
22344961713Sgirish 			return (NXGE_ERROR | rs);
22444961713Sgirish 		}
22544961713Sgirish 	}
22644961713Sgirish 
227a3c5bd6dSspeer 	/* disable the configurable ip classes; */
22844961713Sgirish 	for (class = TCAM_CLASS_IP_USER_4;
22952ccf843Smisaki 	    class <= TCAM_CLASS_IP_USER_7; class++) {
23044961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
23144961713Sgirish 		if (rs != NPI_SUCCESS) {
23244961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
23352ccf843Smisaki 			    "TCAM USR IP Class cnfg failed."));
23444961713Sgirish 			return (NXGE_ERROR | rs);
23544961713Sgirish 		}
23644961713Sgirish 	}
23744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init"));
23844961713Sgirish 	return (NXGE_OK);
23944961713Sgirish }
24044961713Sgirish 
24144961713Sgirish /*
24244961713Sgirish  * nxge_fflp_tcam_invalidate_all
24344961713Sgirish  * invalidates all the tcam entries.
24444961713Sgirish  * INPUT
24544961713Sgirish  * nxge    soft state data structure
24644961713Sgirish  * Return
24744961713Sgirish  *      NXGE_OK
24844961713Sgirish  *      NXGE_ERROR
24944961713Sgirish  *
25044961713Sgirish  */
251a3c5bd6dSspeer 
252a3c5bd6dSspeer 
25344961713Sgirish static nxge_status_t
25444961713Sgirish nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)
25544961713Sgirish {
25644961713Sgirish 	uint16_t location;
25744961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
25844961713Sgirish 	npi_handle_t handle;
25944961713Sgirish 	uint16_t start = 0, stop = nxgep->classifier.tcam_size;
260a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
26144961713Sgirish 
26244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
26352ccf843Smisaki 	    "==> nxge_fflp_tcam_invalidate_all"));
26444961713Sgirish 	handle = nxgep->npi_reg_handle;
26544961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
26644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
26752ccf843Smisaki 		    " nxge_fflp_tcam_invalidate_all:"
26852ccf843Smisaki 		    " common hardware not set", nxgep->niu_type));
26944961713Sgirish 		return (NXGE_ERROR);
27044961713Sgirish 	}
27144961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
27244961713Sgirish 	for (location = start; location < stop; location++) {
27344961713Sgirish 		rs = npi_fflp_tcam_entry_invalidate(handle, location);
27444961713Sgirish 		if (rs != NPI_SUCCESS) {
27544961713Sgirish 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
27644961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27752ccf843Smisaki 			    "TCAM invalidate failed at loc %d ", location));
27844961713Sgirish 			return (NXGE_ERROR | rs);
27944961713Sgirish 		}
28044961713Sgirish 	}
28144961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
28244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
28352ccf843Smisaki 	    "<== nxge_fflp_tcam_invalidate_all"));
28444961713Sgirish 	return (NXGE_OK);
28544961713Sgirish }
28644961713Sgirish 
28744961713Sgirish /*
28844961713Sgirish  * nxge_fflp_fcram_entry_invalidate_all
28944961713Sgirish  * invalidates all the FCRAM entries.
29044961713Sgirish  * INPUT
29144961713Sgirish  * nxge    soft state data structure
29244961713Sgirish  * Return
29344961713Sgirish  *      NXGE_OK
29444961713Sgirish  *      NXGE_ERROR
29544961713Sgirish  *
29644961713Sgirish  */
297a3c5bd6dSspeer 
29844961713Sgirish static nxge_status_t
29944961713Sgirish nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)
30044961713Sgirish {
301a3c5bd6dSspeer 	npi_handle_t handle;
302a3c5bd6dSspeer 	npi_status_t rs = NPI_SUCCESS;
303a3c5bd6dSspeer 	part_id_t pid = 0;
304a3c5bd6dSspeer 	uint8_t base_mask, base_reloc;
305a3c5bd6dSspeer 	fcram_entry_t fc;
306a3c5bd6dSspeer 	uint32_t location;
307a3c5bd6dSspeer 	uint32_t increment, last_location;
30844961713Sgirish 
309a3c5bd6dSspeer 	/*
310a3c5bd6dSspeer 	 * (1) configure and enable partition 0 with no relocation
311a3c5bd6dSspeer 	 * (2) Assume the FCRAM is used as IPv4 exact match entry cells
312a3c5bd6dSspeer 	 * (3) Invalidate these cells by clearing the valid bit in
313a3c5bd6dSspeer 	 * the subareas 0 and 4
314a3c5bd6dSspeer 	 * (4) disable the partition
315a3c5bd6dSspeer 	 *
316a3c5bd6dSspeer 	 */
31744961713Sgirish 
31844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all"));
31944961713Sgirish 
32044961713Sgirish 	base_mask = base_reloc = 0x0;
32144961713Sgirish 	handle = nxgep->npi_reg_handle;
322a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc);
32344961713Sgirish 
32444961713Sgirish 	if (rs != NPI_SUCCESS) {
325a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n"));
32644961713Sgirish 		return (NXGE_ERROR | rs);
32744961713Sgirish 	}
328a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_partition_disable(handle, pid);
32944961713Sgirish 
33044961713Sgirish 	if (rs != NPI_SUCCESS) {
33144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
33252ccf843Smisaki 		    "failed partition enable\n"));
33344961713Sgirish 		return (NXGE_ERROR | rs);
33444961713Sgirish 	}
335a3c5bd6dSspeer 	fc.dreg[0].value = 0;
336a3c5bd6dSspeer 	fc.hash_hdr_valid = 0;
337a3c5bd6dSspeer 	fc.hash_hdr_ext = 1;	/* specify as IPV4 exact match entry */
338a3c5bd6dSspeer 	increment = sizeof (hash_ipv4_t);
339a3c5bd6dSspeer 	last_location = FCRAM_SIZE * 0x40;
34044961713Sgirish 
341a3c5bd6dSspeer 	for (location = 0; location < last_location; location += increment) {
34244961713Sgirish 		rs = npi_fflp_fcram_subarea_write(handle, pid,
34352ccf843Smisaki 		    location, fc.value[0]);
34444961713Sgirish 		if (rs != NPI_SUCCESS) {
34544961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
34652ccf843Smisaki 			    "failed write at location %x ", location));
34744961713Sgirish 			return (NXGE_ERROR | rs);
34844961713Sgirish 		}
34944961713Sgirish 	}
35044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all"));
351a3c5bd6dSspeer 	return (NXGE_OK);
35244961713Sgirish }
35344961713Sgirish 
35444961713Sgirish static nxge_status_t
35544961713Sgirish nxge_fflp_fcram_init(p_nxge_t nxgep)
35644961713Sgirish {
35744961713Sgirish 	fflp_fcram_output_drive_t strength;
35844961713Sgirish 	fflp_fcram_qs_t qs;
35944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
36044961713Sgirish 	uint8_t access_ratio;
361a3c5bd6dSspeer 	int partition;
36244961713Sgirish 	npi_handle_t handle;
363a3c5bd6dSspeer 	uint32_t min_time, max_time, sys_time;
36444961713Sgirish 
36544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init"));
36644961713Sgirish 
367a3c5bd6dSspeer 	/*
368a3c5bd6dSspeer 	 * Recommended values are needed.
369a3c5bd6dSspeer 	 */
37044961713Sgirish 	min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME;
37144961713Sgirish 	max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME;
37244961713Sgirish 	sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME;
373a3c5bd6dSspeer 
37444961713Sgirish 	handle = nxgep->npi_reg_handle;
37544961713Sgirish 	strength = FCRAM_OUTDR_NORMAL;
37644961713Sgirish 	qs = FCRAM_QS_MODE_QS;
37744961713Sgirish 	rs = npi_fflp_cfg_fcram_reset(handle, strength, qs);
37844961713Sgirish 	if (rs != NPI_SUCCESS) {
37944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. "));
38044961713Sgirish 		return (NXGE_ERROR | rs);
38144961713Sgirish 	}
38244961713Sgirish 
383a3c5bd6dSspeer 	access_ratio = nxgep->param_arr[param_fcram_access_ratio].value;
384a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_access(handle, access_ratio);
385a3c5bd6dSspeer 	if (rs != NPI_SUCCESS) {
38644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio"
38752ccf843Smisaki 		    "configuration \n"));
38844961713Sgirish 		return (NXGE_ERROR | rs);
38944961713Sgirish 	}
39044961713Sgirish 	rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time,
39152ccf843Smisaki 	    max_time, sys_time);
39244961713Sgirish 	if (rs != NPI_SUCCESS) {
39344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
39452ccf843Smisaki 		    "failed FCRAM refresh cfg"));
39544961713Sgirish 		return (NXGE_ERROR);
39644961713Sgirish 	}
39744961713Sgirish 
39844961713Sgirish 	/* disable all the partitions until explicitly enabled */
39944961713Sgirish 	for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) {
400a3c5bd6dSspeer 		rs = npi_fflp_cfg_fcram_partition_disable(handle, partition);
40144961713Sgirish 		if (rs != NPI_SUCCESS) {
40244961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
40352ccf843Smisaki 			    "failed FCRAM partition"
40452ccf843Smisaki 			    " enable for partition %d ", partition));
40544961713Sgirish 			return (NXGE_ERROR | rs);
40644961713Sgirish 		}
40744961713Sgirish 	}
40844961713Sgirish 
40944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init"));
410a3c5bd6dSspeer 	return (NXGE_OK);
41144961713Sgirish }
41244961713Sgirish 
41344961713Sgirish nxge_status_t
41444961713Sgirish nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac)
41544961713Sgirish {
41644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
41744961713Sgirish 	hostinfo_t mac_rdc;
41844961713Sgirish 	npi_handle_t handle;
419a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
42044961713Sgirish 
421a3c5bd6dSspeer 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
42244961713Sgirish 	if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) {
423a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
42452ccf843Smisaki 		    " nxge_logical_mac_assign_rdc_table"
42552ccf843Smisaki 		    " unconfigured alt MAC addr %d ", alt_mac));
42644961713Sgirish 		return (NXGE_ERROR);
42744961713Sgirish 	}
42844961713Sgirish 	handle = nxgep->npi_reg_handle;
42944961713Sgirish 	mac_rdc.value = 0;
43044961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num =
43152ccf843Smisaki 	    p_class_cfgp->mac_host_info[alt_mac].rdctbl;
43244961713Sgirish 	mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr;
43344961713Sgirish 
43444961713Sgirish 	rs = npi_mac_hostinfo_entry(handle, OP_SET,
43552ccf843Smisaki 	    nxgep->function_num, alt_mac, &mac_rdc);
43644961713Sgirish 
43744961713Sgirish 	if (rs != NPI_SUCCESS) {
43844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
43952ccf843Smisaki 		    "failed Assign RDC table"));
44044961713Sgirish 		return (NXGE_ERROR | rs);
44144961713Sgirish 	}
44244961713Sgirish 	return (NXGE_OK);
44344961713Sgirish }
44444961713Sgirish 
44544961713Sgirish nxge_status_t
44644961713Sgirish nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)
44744961713Sgirish {
44844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
44944961713Sgirish 	hostinfo_t mac_rdc;
45044961713Sgirish 	npi_handle_t handle;
45144961713Sgirish 
45244961713Sgirish 	handle = nxgep->npi_reg_handle;
45344961713Sgirish 	mac_rdc.value = 0;
45444961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp;
45544961713Sgirish 	mac_rdc.bits.w0.mac_pref = 1;
45644961713Sgirish 	switch (nxgep->function_num) {
457a3c5bd6dSspeer 	case 0:
458a3c5bd6dSspeer 	case 1:
459a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
46052ccf843Smisaki 		    nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
461a3c5bd6dSspeer 		break;
462a3c5bd6dSspeer 	case 2:
463a3c5bd6dSspeer 	case 3:
464a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
46552ccf843Smisaki 		    nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
466a3c5bd6dSspeer 		break;
467a3c5bd6dSspeer 	default:
468a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
46952ccf843Smisaki 		    "failed Assign RDC table (invalid function #)"));
470a3c5bd6dSspeer 		return (NXGE_ERROR);
47144961713Sgirish 	}
47244961713Sgirish 
47344961713Sgirish 	if (rs != NPI_SUCCESS) {
47444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
47552ccf843Smisaki 		    "failed Assign RDC table"));
47644961713Sgirish 		return (NXGE_ERROR | rs);
47744961713Sgirish 	}
47844961713Sgirish 	return (NXGE_OK);
47944961713Sgirish }
48044961713Sgirish 
48158324dfcSspeer /*
48258324dfcSspeer  * Initialize hostinfo registers for alternate MAC addresses and
48358324dfcSspeer  * multicast MAC address.
48458324dfcSspeer  */
48544961713Sgirish nxge_status_t
48658324dfcSspeer nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)
48744961713Sgirish {
48844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
48944961713Sgirish 	hostinfo_t mac_rdc;
49044961713Sgirish 	npi_handle_t handle;
49158324dfcSspeer 	int i;
49244961713Sgirish 
49344961713Sgirish 	handle = nxgep->npi_reg_handle;
49444961713Sgirish 	mac_rdc.value = 0;
49544961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp;
49644961713Sgirish 	mac_rdc.bits.w0.mac_pref = 1;
49744961713Sgirish 	switch (nxgep->function_num) {
498a3c5bd6dSspeer 	case 0:
499a3c5bd6dSspeer 	case 1:
50058324dfcSspeer 		/*
50158324dfcSspeer 		 * Tests indicate that it is OK not to re-initialize the
50258324dfcSspeer 		 * hostinfo registers for the XMAC's alternate MAC
50358324dfcSspeer 		 * addresses. But that is necessary for BMAC (case 2
50458324dfcSspeer 		 * and case 3 below)
50558324dfcSspeer 		 */
506a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
50752ccf843Smisaki 		    nxgep->function_num,
50852ccf843Smisaki 		    XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
509a3c5bd6dSspeer 		break;
510a3c5bd6dSspeer 	case 2:
511a3c5bd6dSspeer 	case 3:
51258324dfcSspeer 		for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
51358324dfcSspeer 			rs |= npi_mac_hostinfo_entry(handle, OP_SET,
51452ccf843Smisaki 			    nxgep->function_num, i, &mac_rdc);
51558324dfcSspeer 
51658324dfcSspeer 		rs |= npi_mac_hostinfo_entry(handle, OP_SET,
51752ccf843Smisaki 		    nxgep->function_num,
51852ccf843Smisaki 		    BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
519a3c5bd6dSspeer 		break;
520a3c5bd6dSspeer 	default:
521a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52252ccf843Smisaki 		    "failed Assign RDC table (invalid function #)"));
523a3c5bd6dSspeer 		return (NXGE_ERROR);
52444961713Sgirish 	}
52544961713Sgirish 
52644961713Sgirish 	if (rs != NPI_SUCCESS) {
52744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52852ccf843Smisaki 		    "failed Assign RDC table"));
52944961713Sgirish 		return (NXGE_ERROR | rs);
53044961713Sgirish 	}
53144961713Sgirish 	return (NXGE_OK);
53244961713Sgirish }
53344961713Sgirish 
53444961713Sgirish nxge_status_t
53544961713Sgirish nxge_fflp_init_hostinfo(p_nxge_t nxgep)
53644961713Sgirish {
53744961713Sgirish 	nxge_status_t status = NXGE_OK;
538a3c5bd6dSspeer 
53958324dfcSspeer 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
54058324dfcSspeer 	status |= nxge_main_mac_assign_rdc_table(nxgep);
54144961713Sgirish 	return (status);
54244961713Sgirish }
54344961713Sgirish 
54444961713Sgirish nxge_status_t
54544961713Sgirish nxge_fflp_hw_reset(p_nxge_t nxgep)
54644961713Sgirish {
54744961713Sgirish 	npi_handle_t handle;
54844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
54944961713Sgirish 	nxge_status_t status = NXGE_OK;
55044961713Sgirish 
55144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
55244961713Sgirish 
5532e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
55444961713Sgirish 		status = nxge_fflp_fcram_init(nxgep);
555a3c5bd6dSspeer 		if (status != NXGE_OK) {
55644961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55752ccf843Smisaki 			    " failed FCRAM init. "));
55844961713Sgirish 			return (status);
55944961713Sgirish 		}
56044961713Sgirish 	}
56144961713Sgirish 
56244961713Sgirish 	status = nxge_fflp_tcam_init(nxgep);
56344961713Sgirish 	if (status != NXGE_OK) {
564a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
56552ccf843Smisaki 		    "failed TCAM init."));
566a3c5bd6dSspeer 		return (status);
56744961713Sgirish 	}
56844961713Sgirish 
56944961713Sgirish 	handle = nxgep->npi_reg_handle;
57044961713Sgirish 	rs = npi_fflp_cfg_llcsnap_enable(handle);
57144961713Sgirish 	if (rs != NPI_SUCCESS) {
572a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
57352ccf843Smisaki 		    "failed LLCSNAP enable. "));
574a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
57544961713Sgirish 	}
57644961713Sgirish 
57744961713Sgirish 	rs = npi_fflp_cfg_cam_errorcheck_disable(handle);
57844961713Sgirish 	if (rs != NPI_SUCCESS) {
57944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
58052ccf843Smisaki 		    "failed CAM Error Check enable. "));
58144961713Sgirish 		return (NXGE_ERROR | rs);
58244961713Sgirish 	}
58344961713Sgirish 
584a3c5bd6dSspeer 	/* init the hash generators */
58544961713Sgirish 	rs = npi_fflp_cfg_hash_h1poly(handle, 0);
58644961713Sgirish 	if (rs != NPI_SUCCESS) {
587a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
58852ccf843Smisaki 		    "failed H1 Poly Init. "));
589a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
59044961713Sgirish 	}
59144961713Sgirish 
59244961713Sgirish 	rs = npi_fflp_cfg_hash_h2poly(handle, 0);
59344961713Sgirish 	if (rs != NPI_SUCCESS) {
594a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
59552ccf843Smisaki 		    "failed H2 Poly Init. "));
596a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
59744961713Sgirish 	}
59844961713Sgirish 
599a3c5bd6dSspeer 	/* invalidate TCAM entries */
60044961713Sgirish 	status = nxge_fflp_tcam_invalidate_all(nxgep);
60144961713Sgirish 	if (status != NXGE_OK) {
60244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
60352ccf843Smisaki 		    "failed TCAM Entry Invalidate. "));
60444961713Sgirish 		return (status);
60544961713Sgirish 	}
60644961713Sgirish 
607a3c5bd6dSspeer 	/* invalidate FCRAM entries */
6082e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
60944961713Sgirish 		status = nxge_fflp_fcram_invalidate_all(nxgep);
61044961713Sgirish 		if (status != NXGE_OK) {
61144961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
61252ccf843Smisaki 			    "failed FCRAM Entry Invalidate."));
61344961713Sgirish 			return (status);
61444961713Sgirish 		}
61544961713Sgirish 	}
61644961713Sgirish 
617a3c5bd6dSspeer 	/* invalidate VLAN RDC tables */
61844961713Sgirish 	status = nxge_fflp_vlan_tbl_clear_all(nxgep);
61944961713Sgirish 	if (status != NXGE_OK) {
62044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
62152ccf843Smisaki 		    "failed VLAN Table Invalidate. "));
62244961713Sgirish 		return (status);
62344961713Sgirish 	}
62444961713Sgirish 	nxgep->classifier.state |= NXGE_FFLP_HW_RESET;
62544961713Sgirish 
62644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset"));
62744961713Sgirish 	return (NXGE_OK);
62844961713Sgirish }
62944961713Sgirish 
63044961713Sgirish nxge_status_t
63144961713Sgirish nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class,
632a3c5bd6dSspeer 	uint32_t class_config)
63344961713Sgirish {
63444961713Sgirish 	flow_key_cfg_t fcfg;
63544961713Sgirish 	npi_handle_t handle;
63644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
63744961713Sgirish 
63844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key"));
63944961713Sgirish 	handle = nxgep->npi_reg_handle;
64044961713Sgirish 	bzero(&fcfg, sizeof (flow_key_cfg_t));
64144961713Sgirish 
642a3c5bd6dSspeer 	if (class_config & NXGE_CLASS_FLOW_USE_PROTO)
64344961713Sgirish 		fcfg.use_proto = 1;
64444961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT)
64544961713Sgirish 		fcfg.use_dport = 1;
64644961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT)
64744961713Sgirish 		fcfg.use_sport = 1;
64844961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_IPDST)
64944961713Sgirish 		fcfg.use_daddr = 1;
65044961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_IPSRC)
65144961713Sgirish 		fcfg.use_saddr = 1;
65244961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_VLAN)
65344961713Sgirish 		fcfg.use_vlan = 1;
65444961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_L2DA)
65544961713Sgirish 		fcfg.use_l2da = 1;
65644961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM)
65744961713Sgirish 		fcfg.use_portnum = 1;
65844961713Sgirish 	fcfg.ip_opts_exist = 0;
65944961713Sgirish 
66044961713Sgirish 	rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg);
66144961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
66244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
66352ccf843Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
66444961713Sgirish 		return (NXGE_ERROR | rs);
66544961713Sgirish 	}
66644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key"));
66744961713Sgirish 	return (NXGE_OK);
66844961713Sgirish }
66944961713Sgirish 
67044961713Sgirish nxge_status_t
67144961713Sgirish nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class,
672a3c5bd6dSspeer 	uint32_t *class_config)
67344961713Sgirish {
67444961713Sgirish 	flow_key_cfg_t fcfg;
67544961713Sgirish 	npi_handle_t handle;
67644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
67744961713Sgirish 	uint32_t ccfg = 0;
678a3c5bd6dSspeer 
67944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get"));
68044961713Sgirish 	handle = nxgep->npi_reg_handle;
68144961713Sgirish 	bzero(&fcfg, sizeof (flow_key_cfg_t));
68244961713Sgirish 
68344961713Sgirish 	rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg);
68444961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
68544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
68652ccf843Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
68744961713Sgirish 		return (NXGE_ERROR | rs);
68844961713Sgirish 	}
68944961713Sgirish 
69044961713Sgirish 	if (fcfg.use_proto)
69144961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_PROTO;
69244961713Sgirish 	if (fcfg.use_dport)
69344961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT;
69444961713Sgirish 	if (fcfg.use_sport)
69544961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT;
69644961713Sgirish 	if (fcfg.use_daddr)
69744961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_IPDST;
69844961713Sgirish 	if (fcfg.use_saddr)
69944961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_IPSRC;
70044961713Sgirish 	if (fcfg.use_vlan)
70144961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_VLAN;
70244961713Sgirish 	if (fcfg.use_l2da)
70344961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_L2DA;
70444961713Sgirish 	if (fcfg.use_portnum)
705a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM;
70644961713Sgirish 
70744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
70852ccf843Smisaki 	    " nxge_cfg_ip_cls_flow_key_get %x", ccfg));
70944961713Sgirish 	*class_config = ccfg;
71044961713Sgirish 
71144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
71252ccf843Smisaki 	    " <== nxge_cfg_ip_cls_flow_key_get"));
71344961713Sgirish 	return (NXGE_OK);
71444961713Sgirish }
71544961713Sgirish 
71644961713Sgirish static nxge_status_t
71744961713Sgirish nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class,
718a3c5bd6dSspeer 	uint32_t *class_config)
71944961713Sgirish {
72044961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
72144961713Sgirish 	tcam_key_cfg_t cfg;
72244961713Sgirish 	npi_handle_t handle;
72344961713Sgirish 	uint32_t ccfg = 0;
72444961713Sgirish 
72544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
72644961713Sgirish 
72744961713Sgirish 	bzero(&cfg, sizeof (tcam_key_cfg_t));
72844961713Sgirish 	handle = nxgep->npi_reg_handle;
72944961713Sgirish 
73044961713Sgirish 	rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg);
73144961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
73244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
73352ccf843Smisaki 		    " opt %x for class %d failed ", class_config, class));
73444961713Sgirish 		return (NXGE_ERROR | rs);
73544961713Sgirish 	}
73644961713Sgirish 	if (cfg.discard)
737a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_DISCARD;
73844961713Sgirish 	if (cfg.lookup_enable)
73944961713Sgirish 		ccfg |= NXGE_CLASS_TCAM_LOOKUP;
74044961713Sgirish 	if (cfg.use_ip_daddr)
741a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR;
74244961713Sgirish 	*class_config = ccfg;
74344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
74452ccf843Smisaki 	    " ==> nxge_cfg_tcam_ip_class %x", ccfg));
74544961713Sgirish 	return (NXGE_OK);
74644961713Sgirish }
74744961713Sgirish 
74844961713Sgirish static nxge_status_t
74944961713Sgirish nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class,
750a3c5bd6dSspeer 	uint32_t class_config)
75144961713Sgirish {
75244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
75344961713Sgirish 	tcam_key_cfg_t cfg;
75444961713Sgirish 	npi_handle_t handle;
755a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
75644961713Sgirish 
75744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
758a3c5bd6dSspeer 
75944961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
76044961713Sgirish 	p_class_cfgp->class_cfg[class] = class_config;
76144961713Sgirish 
76244961713Sgirish 	bzero(&cfg, sizeof (tcam_key_cfg_t));
76344961713Sgirish 	handle = nxgep->npi_reg_handle;
76444961713Sgirish 	cfg.discard = 0;
76544961713Sgirish 	cfg.lookup_enable = 0;
76644961713Sgirish 	cfg.use_ip_daddr = 0;
76744961713Sgirish 	if (class_config & NXGE_CLASS_DISCARD)
76844961713Sgirish 		cfg.discard = 1;
76944961713Sgirish 	if (class_config & NXGE_CLASS_TCAM_LOOKUP)
77044961713Sgirish 		cfg.lookup_enable = 1;
771a3c5bd6dSspeer 	if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR)
77244961713Sgirish 		cfg.use_ip_daddr = 1;
77344961713Sgirish 
77444961713Sgirish 	rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg);
77544961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
77644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
77752ccf843Smisaki 		    " opt %x for class %d failed ", class_config, class));
77844961713Sgirish 		return (NXGE_ERROR | rs);
77944961713Sgirish 	}
78044961713Sgirish 	return (NXGE_OK);
78144961713Sgirish }
78244961713Sgirish 
78344961713Sgirish nxge_status_t
78444961713Sgirish nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1)
78544961713Sgirish {
78644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
78744961713Sgirish 	npi_handle_t handle;
788a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
78944961713Sgirish 
79044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1"));
79144961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
79244961713Sgirish 	p_class_cfgp->init_h1 = h1;
79344961713Sgirish 	handle = nxgep->npi_reg_handle;
79444961713Sgirish 	rs = npi_fflp_cfg_hash_h1poly(handle, h1);
79544961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
796a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
79752ccf843Smisaki 		    " nxge_fflp_init_h1 %x failed ", h1));
79844961713Sgirish 		return (NXGE_ERROR | rs);
79944961713Sgirish 	}
80044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1"));
80144961713Sgirish 	return (NXGE_OK);
80244961713Sgirish }
80344961713Sgirish 
80444961713Sgirish nxge_status_t
80544961713Sgirish nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2)
80644961713Sgirish {
80744961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
80844961713Sgirish 	npi_handle_t handle;
809a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
81044961713Sgirish 
81144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2"));
81244961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
81344961713Sgirish 	p_class_cfgp->init_h2 = h2;
81444961713Sgirish 
81544961713Sgirish 	handle = nxgep->npi_reg_handle;
81644961713Sgirish 	rs = npi_fflp_cfg_hash_h2poly(handle, h2);
81744961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
818a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
81952ccf843Smisaki 		    " nxge_fflp_init_h2 %x failed ", h2));
82044961713Sgirish 		return (NXGE_ERROR | rs);
82144961713Sgirish 	}
82244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2"));
82344961713Sgirish 	return (NXGE_OK);
82444961713Sgirish }
82544961713Sgirish 
82644961713Sgirish nxge_status_t
82744961713Sgirish nxge_classify_init_sw(p_nxge_t nxgep)
82844961713Sgirish {
82944961713Sgirish 	nxge_classify_t *classify_ptr;
83044961713Sgirish 
83144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw"));
83244961713Sgirish 	classify_ptr = &nxgep->classifier;
83344961713Sgirish 
83444961713Sgirish 	if (classify_ptr->state & NXGE_FFLP_SW_INIT) {
83544961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
83652ccf843Smisaki 		    "nxge_classify_init_sw already init"));
83744961713Sgirish 		return (NXGE_OK);
83844961713Sgirish 	}
839a3c5bd6dSspeer 
840*4df55fdeSJanie Lu 	classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports;
841*4df55fdeSJanie Lu 	classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam;
842*4df55fdeSJanie Lu 	classify_ptr->tcam_top = nxgep->function_num;
84344961713Sgirish 
844a3c5bd6dSspeer 	/* Init defaults */
845a3c5bd6dSspeer 	/*
846a3c5bd6dSspeer 	 * add hacks required for HW shortcomings for example, code to handle
847a3c5bd6dSspeer 	 * fragmented packets
848a3c5bd6dSspeer 	 */
84944961713Sgirish 	nxge_init_h1_table();
85044961713Sgirish 	nxge_crc_ccitt_init();
85144961713Sgirish 	nxgep->classifier.tcam_location = nxgep->function_num;
85244961713Sgirish 	nxgep->classifier.fragment_bug = 1;
85344961713Sgirish 	classify_ptr->state |= NXGE_FFLP_SW_INIT;
85444961713Sgirish 
85544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw"));
85644961713Sgirish 	return (NXGE_OK);
85744961713Sgirish }
85844961713Sgirish 
85944961713Sgirish nxge_status_t
86044961713Sgirish nxge_classify_exit_sw(p_nxge_t nxgep)
86144961713Sgirish {
86244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw"));
86344961713Sgirish 	nxgep->classifier.state = NULL;
86444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw"));
86544961713Sgirish 	return (NXGE_OK);
86644961713Sgirish }
86744961713Sgirish 
86844961713Sgirish /*
86944961713Sgirish  * Figures out the RDC Group for the entry
87044961713Sgirish  *
87144961713Sgirish  * The current implementation is just a place holder and it
87244961713Sgirish  * returns 0.
87344961713Sgirish  * The real location determining algorithm would consider
87444961713Sgirish  * the partition etc ... before deciding w
87544961713Sgirish  *
87644961713Sgirish  */
877a3c5bd6dSspeer 
8780a8e077aSspeer /* ARGSUSED */
87944961713Sgirish static uint8_t
880*4df55fdeSJanie Lu nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
88144961713Sgirish {
88244961713Sgirish 	int use_port_rdc_grp = 0;
88344961713Sgirish 	uint8_t rdc_grp = 0;
884a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
885a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
886a3c5bd6dSspeer 	p_nxge_rdc_grp_t rdc_grp_p;
887a3c5bd6dSspeer 
88844961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
88944961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
89044961713Sgirish 	rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp];
891678453a8Sspeer 	rdc_grp = p_cfgp->def_mac_rxdma_grpid;
892a3c5bd6dSspeer 
89344961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
89452ccf843Smisaki 	    "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
89552ccf843Smisaki 	    cookie, rdc_grp, rdc_grp_p));
89644961713Sgirish 	return (rdc_grp);
89744961713Sgirish }
89844961713Sgirish 
89944961713Sgirish /* ARGSUSED */
90044961713Sgirish static uint8_t
901*4df55fdeSJanie Lu nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
90244961713Sgirish {
90344961713Sgirish 	return ((uint8_t)cookie);
90444961713Sgirish }
90544961713Sgirish 
9060a8e077aSspeer /* ARGSUSED */
90744961713Sgirish static void
90844961713Sgirish nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec,
909a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
91044961713Sgirish {
91144961713Sgirish 	udpip4_spec_t *fspec_key;
91244961713Sgirish 	udpip4_spec_t *fspec_mask;
91344961713Sgirish 
91444961713Sgirish 	fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec;
91544961713Sgirish 	fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec;
91644961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
91744961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
91844961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
91944961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
92044961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
92152ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
92244961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
92352ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
92444961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
92552ccf843Smisaki 	    tcam_ptr->ip4_class_mask,
92652ccf843Smisaki 	    TCAM_CLASS_UDP_IPV4);
92744961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
92852ccf843Smisaki 	    tcam_ptr->ip4_proto_mask,
92952ccf843Smisaki 	    IPPROTO_UDP);
930*4df55fdeSJanie Lu 	tcam_ptr->ip4_tos_key = fspec_key->tos;
931*4df55fdeSJanie Lu 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
93244961713Sgirish }
93344961713Sgirish 
93444961713Sgirish static void
93544961713Sgirish nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
936a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
93744961713Sgirish {
93844961713Sgirish 	udpip6_spec_t *fspec_key;
93944961713Sgirish 	udpip6_spec_t *fspec_mask;
940a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
94144961713Sgirish 
94244961713Sgirish 	fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec;
94344961713Sgirish 	fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec;
94444961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
94544961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
94652ccf843Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
94744961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
94844961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
94944961713Sgirish 	} else {
95044961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
95144961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
95244961713Sgirish 	}
95344961713Sgirish 
95444961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
95552ccf843Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6);
95644961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
95752ccf843Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP);
95844961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
95952ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
96044961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
96152ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
962*4df55fdeSJanie Lu 	tcam_ptr->ip6_tos_key = fspec_key->tos;
963*4df55fdeSJanie Lu 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
96444961713Sgirish }
96544961713Sgirish 
9660a8e077aSspeer /* ARGSUSED */
96744961713Sgirish static void
96844961713Sgirish nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec,
969a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
97044961713Sgirish {
97144961713Sgirish 	tcpip4_spec_t *fspec_key;
97244961713Sgirish 	tcpip4_spec_t *fspec_mask;
97344961713Sgirish 
97444961713Sgirish 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
97544961713Sgirish 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
97644961713Sgirish 
97744961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
97844961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
97944961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
98044961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
98144961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
98252ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
98344961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
98452ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
98544961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
98652ccf843Smisaki 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4);
98744961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
98852ccf843Smisaki 	    tcam_ptr->ip4_proto_mask, IPPROTO_TCP);
989*4df55fdeSJanie Lu 	tcam_ptr->ip4_tos_key = fspec_key->tos;
990*4df55fdeSJanie Lu 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
99144961713Sgirish }
99244961713Sgirish 
9930a8e077aSspeer /* ARGSUSED */
99444961713Sgirish static void
99544961713Sgirish nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec,
996a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
99744961713Sgirish {
99844961713Sgirish 	tcpip4_spec_t *fspec_key;
99944961713Sgirish 	tcpip4_spec_t *fspec_mask;
100044961713Sgirish 
100144961713Sgirish 	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
100244961713Sgirish 	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
100344961713Sgirish 
100444961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
100544961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
100644961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
100744961713Sgirish 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
100844961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
100952ccf843Smisaki 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4);
101044961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
101152ccf843Smisaki 	    tcam_ptr->ip4_proto_mask, IPPROTO_SCTP);
101244961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
101352ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
101444961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
101552ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
1016*4df55fdeSJanie Lu 	tcam_ptr->ip4_tos_key = fspec_key->tos;
1017*4df55fdeSJanie Lu 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
101844961713Sgirish }
101944961713Sgirish 
102044961713Sgirish static void
102144961713Sgirish nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1022a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
102344961713Sgirish {
102444961713Sgirish 	tcpip6_spec_t *fspec_key;
102544961713Sgirish 	tcpip6_spec_t *fspec_mask;
1026a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1027a3c5bd6dSspeer 
102844961713Sgirish 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
102944961713Sgirish 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
103044961713Sgirish 
103144961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
103244961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
103352ccf843Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
103444961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
103544961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
103644961713Sgirish 	} else {
103744961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
103844961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
103944961713Sgirish 	}
104044961713Sgirish 
104144961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
104252ccf843Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6);
104344961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
104452ccf843Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP);
104544961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
104652ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
104744961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
104852ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
1049*4df55fdeSJanie Lu 	tcam_ptr->ip6_tos_key = fspec_key->tos;
1050*4df55fdeSJanie Lu 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
105144961713Sgirish }
105244961713Sgirish 
105344961713Sgirish static void
105444961713Sgirish nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1055a3c5bd6dSspeer 	tcam_entry_t *tcam_ptr)
105644961713Sgirish {
105744961713Sgirish 	tcpip6_spec_t *fspec_key;
105844961713Sgirish 	tcpip6_spec_t *fspec_mask;
1059a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
106044961713Sgirish 
106144961713Sgirish 	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
106244961713Sgirish 	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
106344961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
106444961713Sgirish 
106544961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
106652ccf843Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
106744961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
106844961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
106944961713Sgirish 	} else {
107044961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
107144961713Sgirish 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
107244961713Sgirish 	}
107344961713Sgirish 
107444961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
107552ccf843Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6);
107644961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
107752ccf843Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP);
107844961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
107952ccf843Smisaki 	    fspec_key->pdst, fspec_key->psrc);
108044961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
108152ccf843Smisaki 	    fspec_mask->pdst, fspec_mask->psrc);
1082*4df55fdeSJanie Lu 	tcam_ptr->ip6_tos_key = fspec_key->tos;
1083*4df55fdeSJanie Lu 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
1084*4df55fdeSJanie Lu }
1085*4df55fdeSJanie Lu 
1086*4df55fdeSJanie Lu /* ARGSUSED */
1087*4df55fdeSJanie Lu static void
1088*4df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec,
1089*4df55fdeSJanie Lu 	tcam_entry_t *tcam_ptr)
1090*4df55fdeSJanie Lu {
1091*4df55fdeSJanie Lu 	ahip4_spec_t *fspec_key;
1092*4df55fdeSJanie Lu 	ahip4_spec_t *fspec_mask;
1093*4df55fdeSJanie Lu 
1094*4df55fdeSJanie Lu 	fspec_key = (ahip4_spec_t *)&flow_spec->uh.ahip4spec;
1095*4df55fdeSJanie Lu 	fspec_mask = (ahip4_spec_t *)&flow_spec->um.ahip4spec;
1096*4df55fdeSJanie Lu 
1097*4df55fdeSJanie Lu 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
1098*4df55fdeSJanie Lu 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
1099*4df55fdeSJanie Lu 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
1100*4df55fdeSJanie Lu 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
1101*4df55fdeSJanie Lu 
1102*4df55fdeSJanie Lu 	tcam_ptr->ip4_port_key = fspec_key->spi;
1103*4df55fdeSJanie Lu 	tcam_ptr->ip4_port_mask = fspec_mask->spi;
1104*4df55fdeSJanie Lu 
1105*4df55fdeSJanie Lu 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
1106*4df55fdeSJanie Lu 	    tcam_ptr->ip4_class_mask,
1107*4df55fdeSJanie Lu 	    TCAM_CLASS_AH_ESP_IPV4);
1108*4df55fdeSJanie Lu 
1109*4df55fdeSJanie Lu 	if (flow_spec->flow_type == FSPEC_AHIP4) {
1110*4df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
1111*4df55fdeSJanie Lu 		    tcam_ptr->ip4_proto_mask, IPPROTO_AH);
1112*4df55fdeSJanie Lu 	} else {
1113*4df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
1114*4df55fdeSJanie Lu 		    tcam_ptr->ip4_proto_mask, IPPROTO_ESP);
1115*4df55fdeSJanie Lu 	}
1116*4df55fdeSJanie Lu 	tcam_ptr->ip4_tos_key = fspec_key->tos;
1117*4df55fdeSJanie Lu 	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
111844961713Sgirish }
111944961713Sgirish 
1120*4df55fdeSJanie Lu static void
1121*4df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1122*4df55fdeSJanie Lu 	tcam_entry_t *tcam_ptr)
1123*4df55fdeSJanie Lu {
1124*4df55fdeSJanie Lu 	ahip6_spec_t *fspec_key;
1125*4df55fdeSJanie Lu 	ahip6_spec_t *fspec_mask;
1126*4df55fdeSJanie Lu 	p_nxge_class_pt_cfg_t p_class_cfgp;
1127*4df55fdeSJanie Lu 
1128*4df55fdeSJanie Lu 	fspec_key = (ahip6_spec_t *)&flow_spec->uh.ahip6spec;
1129*4df55fdeSJanie Lu 	fspec_mask = (ahip6_spec_t *)&flow_spec->um.ahip6spec;
1130*4df55fdeSJanie Lu 
1131*4df55fdeSJanie Lu 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1132*4df55fdeSJanie Lu 	if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] &
1133*4df55fdeSJanie Lu 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
1134*4df55fdeSJanie Lu 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
1135*4df55fdeSJanie Lu 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
1136*4df55fdeSJanie Lu 	} else {
1137*4df55fdeSJanie Lu 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
1138*4df55fdeSJanie Lu 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
1139*4df55fdeSJanie Lu 	}
1140*4df55fdeSJanie Lu 
1141*4df55fdeSJanie Lu 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
1142*4df55fdeSJanie Lu 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6);
1143*4df55fdeSJanie Lu 
1144*4df55fdeSJanie Lu 	if (flow_spec->flow_type == FSPEC_AHIP6) {
1145*4df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
1146*4df55fdeSJanie Lu 		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH);
1147*4df55fdeSJanie Lu 	} else {
1148*4df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
1149*4df55fdeSJanie Lu 		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP);
1150*4df55fdeSJanie Lu 	}
1151*4df55fdeSJanie Lu 	tcam_ptr->ip6_port_key = fspec_key->spi;
1152*4df55fdeSJanie Lu 	tcam_ptr->ip6_port_mask = fspec_mask->spi;
1153*4df55fdeSJanie Lu 	tcam_ptr->ip6_tos_key = fspec_key->tos;
1154*4df55fdeSJanie Lu 	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
1155*4df55fdeSJanie Lu }
1156*4df55fdeSJanie Lu 
1157*4df55fdeSJanie Lu /* ARGSUSED */
1158*4df55fdeSJanie Lu static void
1159*4df55fdeSJanie Lu nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec,
1160*4df55fdeSJanie Lu 	tcam_entry_t *tcam_ptr, tcam_class_t class)
1161*4df55fdeSJanie Lu {
1162*4df55fdeSJanie Lu 	ip_user_spec_t *fspec_key;
1163*4df55fdeSJanie Lu 	ip_user_spec_t *fspec_mask;
1164*4df55fdeSJanie Lu 
1165*4df55fdeSJanie Lu 	fspec_key = (ip_user_spec_t *)&flow_spec->uh.ip_usr_spec;
1166*4df55fdeSJanie Lu 	fspec_mask = (ip_user_spec_t *)&flow_spec->um.ip_usr_spec;
1167*4df55fdeSJanie Lu 
1168*4df55fdeSJanie Lu 	if (fspec_key->ip_ver == FSPEC_IP4) {
1169*4df55fdeSJanie Lu 		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
1170*4df55fdeSJanie Lu 		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
1171*4df55fdeSJanie Lu 		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
1172*4df55fdeSJanie Lu 		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
1173*4df55fdeSJanie Lu 
1174*4df55fdeSJanie Lu 		tcam_ptr->ip4_port_key = fspec_key->l4_4_bytes;
1175*4df55fdeSJanie Lu 		tcam_ptr->ip4_port_mask = fspec_mask->l4_4_bytes;
1176*4df55fdeSJanie Lu 
1177*4df55fdeSJanie Lu 		TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
1178*4df55fdeSJanie Lu 		    tcam_ptr->ip4_class_mask, class);
1179*4df55fdeSJanie Lu 
1180*4df55fdeSJanie Lu 		tcam_ptr->ip4_proto_key = fspec_key->proto;
1181*4df55fdeSJanie Lu 		tcam_ptr->ip4_proto_mask = fspec_mask->proto;
1182*4df55fdeSJanie Lu 
1183*4df55fdeSJanie Lu 		tcam_ptr->ip4_tos_key = fspec_key->tos;
1184*4df55fdeSJanie Lu 		tcam_ptr->ip4_tos_mask = fspec_mask->tos;
1185*4df55fdeSJanie Lu 	}
1186*4df55fdeSJanie Lu }
1187*4df55fdeSJanie Lu 
1188*4df55fdeSJanie Lu 
118944961713Sgirish nxge_status_t
119044961713Sgirish nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res,
1191a3c5bd6dSspeer 	uint32_t *H1, uint16_t *H2)
119244961713Sgirish {
119344961713Sgirish 	flow_spec_t *flow_spec;
119444961713Sgirish 	uint32_t class_cfg;
119544961713Sgirish 	flow_template_t ft;
1196a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
119744961713Sgirish 
119844961713Sgirish 	int ft_size = sizeof (flow_template_t);
1199a3c5bd6dSspeer 
120044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash"));
120144961713Sgirish 
120244961713Sgirish 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
120344961713Sgirish 	bzero((char *)&ft, ft_size);
120444961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1205a3c5bd6dSspeer 
120644961713Sgirish 	switch (flow_spec->flow_type) {
1207a3c5bd6dSspeer 	case FSPEC_TCPIP4:
1208a3c5bd6dSspeer 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4];
1209a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1210a3c5bd6dSspeer 			ft.ip_proto = IPPROTO_TCP;
1211a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1212a3c5bd6dSspeer 			ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src;
1213a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1214a3c5bd6dSspeer 			ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst;
1215a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1216a3c5bd6dSspeer 			ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc;
1217a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1218a3c5bd6dSspeer 			ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst;
1219a3c5bd6dSspeer 		break;
1220a3c5bd6dSspeer 
1221a3c5bd6dSspeer 	case FSPEC_UDPIP4:
1222a3c5bd6dSspeer 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4];
1223a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1224a3c5bd6dSspeer 			ft.ip_proto = IPPROTO_UDP;
1225a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1226a3c5bd6dSspeer 			ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src;
1227a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1228a3c5bd6dSspeer 			ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst;
1229a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1230a3c5bd6dSspeer 			ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc;
1231a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1232a3c5bd6dSspeer 			ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst;
1233a3c5bd6dSspeer 		break;
1234a3c5bd6dSspeer 
1235a3c5bd6dSspeer 	default:
1236a3c5bd6dSspeer 		return (NXGE_ERROR);
123744961713Sgirish 	}
123844961713Sgirish 
123944961713Sgirish 	*H1 = nxge_compute_h1(p_class_cfgp->init_h1,
124052ccf843Smisaki 	    (uint32_t *)&ft, ft_size) & 0xfffff;
124144961713Sgirish 	*H2 = nxge_compute_h2(p_class_cfgp->init_h2,
124252ccf843Smisaki 	    (uint8_t *)&ft, ft_size);
124344961713Sgirish 
124444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash"));
124544961713Sgirish 	return (NXGE_OK);
124644961713Sgirish }
124744961713Sgirish 
124844961713Sgirish nxge_status_t
124944961713Sgirish nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
125044961713Sgirish {
125144961713Sgirish 	uint32_t H1;
125244961713Sgirish 	uint16_t H2;
125344961713Sgirish 	nxge_status_t status = NXGE_OK;
125444961713Sgirish 
125544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry"));
125644961713Sgirish 	status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2);
125744961713Sgirish 	if (status != NXGE_OK) {
125844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
125952ccf843Smisaki 		    " nxge_add_fcram_entry failed "));
126044961713Sgirish 		return (status);
126144961713Sgirish 	}
126244961713Sgirish 
126344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry"));
126444961713Sgirish 	return (NXGE_OK);
126544961713Sgirish }
126644961713Sgirish 
126744961713Sgirish /*
126844961713Sgirish  * Already decided this flow goes into the tcam
126944961713Sgirish  */
127044961713Sgirish 
127144961713Sgirish nxge_status_t
127244961713Sgirish nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
127344961713Sgirish {
127444961713Sgirish 	npi_handle_t handle;
1275*4df55fdeSJanie Lu 	uint64_t channel_cookie;
1276*4df55fdeSJanie Lu 	uint64_t flow_cookie;
127744961713Sgirish 	flow_spec_t *flow_spec;
127844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
127944961713Sgirish 	tcam_entry_t tcam_ptr;
1280*4df55fdeSJanie Lu 	tcam_location_t location;
128144961713Sgirish 	uint8_t offset, rdc_grp;
1282a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
1283*4df55fdeSJanie Lu 	uint64_t class;
128444961713Sgirish 
128544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry"));
128644961713Sgirish 	handle = nxgep->npi_reg_handle;
128744961713Sgirish 
1288a3c5bd6dSspeer 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
128944961713Sgirish 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
129044961713Sgirish 	flow_cookie = flow_res->flow_cookie;
129144961713Sgirish 	channel_cookie = flow_res->channel_cookie;
1292*4df55fdeSJanie Lu 	location = (tcam_location_t)nxge_tcam_get_index(nxgep,
1293*4df55fdeSJanie Lu 	    (uint16_t)flow_res->location);
1294*4df55fdeSJanie Lu 
1295*4df55fdeSJanie Lu 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
1296*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1297*4df55fdeSJanie Lu 		    " nxge_add_tcam_entry: common hardware not set",
1298*4df55fdeSJanie Lu 		    nxgep->niu_type));
1299*4df55fdeSJanie Lu 		return (NXGE_ERROR);
1300*4df55fdeSJanie Lu 	}
1301*4df55fdeSJanie Lu 
1302*4df55fdeSJanie Lu 	if (flow_spec->flow_type == FSPEC_IP_USR) {
1303*4df55fdeSJanie Lu 		int i;
1304*4df55fdeSJanie Lu 		int add_usr_cls = 0;
1305*4df55fdeSJanie Lu 		int ipv6 = 0;
1306*4df55fdeSJanie Lu 		ip_user_spec_t *uspec = &flow_spec->uh.ip_usr_spec;
1307*4df55fdeSJanie Lu 		ip_user_spec_t *umask = &flow_spec->um.ip_usr_spec;
1308*4df55fdeSJanie Lu 		nxge_usr_l3_cls_t *l3_ucls_p;
1309*4df55fdeSJanie Lu 
1310*4df55fdeSJanie Lu 		MUTEX_ENTER(&hw_p->nxge_tcam_lock);
1311*4df55fdeSJanie Lu 
1312*4df55fdeSJanie Lu 		for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
1313*4df55fdeSJanie Lu 			l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
1314*4df55fdeSJanie Lu 			if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) {
1315*4df55fdeSJanie Lu 				if (uspec->proto == l3_ucls_p->pid) {
1316*4df55fdeSJanie Lu 					class = l3_ucls_p->cls;
1317*4df55fdeSJanie Lu 					l3_ucls_p->tcam_ref_cnt++;
1318*4df55fdeSJanie Lu 					add_usr_cls = 1;
1319*4df55fdeSJanie Lu 					break;
1320*4df55fdeSJanie Lu 				}
1321*4df55fdeSJanie Lu 			} else if (l3_ucls_p->valid == 0) {
1322*4df55fdeSJanie Lu 				/* Program new user IP class */
1323*4df55fdeSJanie Lu 				switch (i) {
1324*4df55fdeSJanie Lu 				case 0:
1325*4df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_4;
1326*4df55fdeSJanie Lu 					break;
1327*4df55fdeSJanie Lu 				case 1:
1328*4df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_5;
1329*4df55fdeSJanie Lu 					break;
1330*4df55fdeSJanie Lu 				case 2:
1331*4df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_6;
1332*4df55fdeSJanie Lu 					break;
1333*4df55fdeSJanie Lu 				case 3:
1334*4df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_7;
1335*4df55fdeSJanie Lu 					break;
1336*4df55fdeSJanie Lu 				default:
1337*4df55fdeSJanie Lu 					break;
1338*4df55fdeSJanie Lu 				}
1339*4df55fdeSJanie Lu 				if (uspec->ip_ver == FSPEC_IP6)
1340*4df55fdeSJanie Lu 					ipv6 = 1;
1341*4df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
1342*4df55fdeSJanie Lu 				    (tcam_class_t)class, uspec->tos,
1343*4df55fdeSJanie Lu 				    umask->tos, uspec->proto, ipv6);
1344*4df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
1345*4df55fdeSJanie Lu 					goto fail;
1346*4df55fdeSJanie Lu 
1347*4df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
1348*4df55fdeSJanie Lu 				    (tcam_class_t)class);
1349*4df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
1350*4df55fdeSJanie Lu 					goto fail;
1351*4df55fdeSJanie Lu 
1352*4df55fdeSJanie Lu 				l3_ucls_p->cls = class;
1353*4df55fdeSJanie Lu 				l3_ucls_p->pid = uspec->proto;
1354*4df55fdeSJanie Lu 				l3_ucls_p->tcam_ref_cnt++;
1355*4df55fdeSJanie Lu 				l3_ucls_p->valid = 1;
1356*4df55fdeSJanie Lu 				add_usr_cls = 1;
1357*4df55fdeSJanie Lu 				break;
1358*4df55fdeSJanie Lu 			} else if (l3_ucls_p->tcam_ref_cnt == 0 &&
1359*4df55fdeSJanie Lu 			    uspec->proto == l3_ucls_p->pid) {
1360*4df55fdeSJanie Lu 				/*
1361*4df55fdeSJanie Lu 				 * The class has already been programmed,
1362*4df55fdeSJanie Lu 				 * probably for flow hash
1363*4df55fdeSJanie Lu 				 */
1364*4df55fdeSJanie Lu 				class = l3_ucls_p->cls;
1365*4df55fdeSJanie Lu 				if (uspec->ip_ver == FSPEC_IP6)
1366*4df55fdeSJanie Lu 					ipv6 = 1;
1367*4df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
1368*4df55fdeSJanie Lu 				    (tcam_class_t)class, uspec->tos,
1369*4df55fdeSJanie Lu 				    umask->tos, uspec->proto, ipv6);
1370*4df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
1371*4df55fdeSJanie Lu 					goto fail;
1372*4df55fdeSJanie Lu 
1373*4df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
1374*4df55fdeSJanie Lu 				    (tcam_class_t)class);
1375*4df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
1376*4df55fdeSJanie Lu 					goto fail;
1377*4df55fdeSJanie Lu 
1378*4df55fdeSJanie Lu 				l3_ucls_p->pid = uspec->proto;
1379*4df55fdeSJanie Lu 				l3_ucls_p->tcam_ref_cnt++;
1380*4df55fdeSJanie Lu 				add_usr_cls = 1;
1381*4df55fdeSJanie Lu 				break;
1382*4df55fdeSJanie Lu 			}
1383*4df55fdeSJanie Lu 		}
1384*4df55fdeSJanie Lu 		if (!add_usr_cls) {
1385*4df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1386*4df55fdeSJanie Lu 			    "nxge_add_tcam_entry: Could not find/insert class"
1387*4df55fdeSJanie Lu 			    "for pid %d", uspec->proto));
1388*4df55fdeSJanie Lu 			goto fail;
1389*4df55fdeSJanie Lu 		}
1390*4df55fdeSJanie Lu 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
1391*4df55fdeSJanie Lu 	}
139244961713Sgirish 
139344961713Sgirish 	switch (flow_spec->flow_type) {
1394a3c5bd6dSspeer 	case FSPEC_TCPIP4:
1395a3c5bd6dSspeer 		nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr);
1396a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4,
139752ccf843Smisaki 		    flow_cookie);
1398a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4,
139952ccf843Smisaki 		    channel_cookie);
1400a3c5bd6dSspeer 		break;
1401a3c5bd6dSspeer 
1402a3c5bd6dSspeer 	case FSPEC_UDPIP4:
1403a3c5bd6dSspeer 		nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr);
1404a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
140552ccf843Smisaki 		    TCAM_CLASS_UDP_IPV4,
140652ccf843Smisaki 		    flow_cookie);
1407a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
140852ccf843Smisaki 		    TCAM_CLASS_UDP_IPV4,
140952ccf843Smisaki 		    channel_cookie);
1410a3c5bd6dSspeer 		break;
1411a3c5bd6dSspeer 
1412a3c5bd6dSspeer 	case FSPEC_TCPIP6:
1413a3c5bd6dSspeer 		nxge_fill_tcam_entry_tcp_ipv6(nxgep,
141452ccf843Smisaki 		    flow_spec, &tcam_ptr);
1415a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6,
141652ccf843Smisaki 		    flow_cookie);
1417a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6,
141852ccf843Smisaki 		    channel_cookie);
1419a3c5bd6dSspeer 		break;
1420a3c5bd6dSspeer 
1421a3c5bd6dSspeer 	case FSPEC_UDPIP6:
1422a3c5bd6dSspeer 		nxge_fill_tcam_entry_udp_ipv6(nxgep,
142352ccf843Smisaki 		    flow_spec, &tcam_ptr);
1424a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
142552ccf843Smisaki 		    TCAM_CLASS_UDP_IPV6,
1426*4df55fdeSJanie Lu 		    flow_cookie);
1427a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
142852ccf843Smisaki 		    TCAM_CLASS_UDP_IPV6,
1429*4df55fdeSJanie Lu 		    channel_cookie);
1430a3c5bd6dSspeer 		break;
1431a3c5bd6dSspeer 
1432a3c5bd6dSspeer 	case FSPEC_SCTPIP4:
1433a3c5bd6dSspeer 		nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr);
1434a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
143552ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV4,
1436*4df55fdeSJanie Lu 		    flow_cookie);
1437a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
143852ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV4,
1439*4df55fdeSJanie Lu 		    channel_cookie);
1440a3c5bd6dSspeer 		break;
1441a3c5bd6dSspeer 
1442a3c5bd6dSspeer 	case FSPEC_SCTPIP6:
1443a3c5bd6dSspeer 		nxge_fill_tcam_entry_sctp_ipv6(nxgep,
144452ccf843Smisaki 		    flow_spec, &tcam_ptr);
1445a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
144652ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV6,
1447*4df55fdeSJanie Lu 		    flow_cookie);
1448a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
144952ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV6,
1450*4df55fdeSJanie Lu 		    channel_cookie);
1451*4df55fdeSJanie Lu 		break;
1452*4df55fdeSJanie Lu 
1453*4df55fdeSJanie Lu 	case FSPEC_AHIP4:
1454*4df55fdeSJanie Lu 	case FSPEC_ESPIP4:
1455*4df55fdeSJanie Lu 		nxge_fill_tcam_entry_ah_esp(nxgep, flow_spec, &tcam_ptr);
1456*4df55fdeSJanie Lu 		rdc_grp = nxge_get_rdc_group(nxgep,
1457*4df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV4,
145852ccf843Smisaki 		    flow_cookie);
1459*4df55fdeSJanie Lu 		offset = nxge_get_rdc_offset(nxgep,
1460*4df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV4,
1461*4df55fdeSJanie Lu 		    channel_cookie);
1462a3c5bd6dSspeer 		break;
1463a3c5bd6dSspeer 
1464*4df55fdeSJanie Lu 	case FSPEC_AHIP6:
1465*4df55fdeSJanie Lu 	case FSPEC_ESPIP6:
1466*4df55fdeSJanie Lu 		nxge_fill_tcam_entry_ah_esp_ipv6(nxgep,
1467*4df55fdeSJanie Lu 		    flow_spec, &tcam_ptr);
1468*4df55fdeSJanie Lu 		rdc_grp = nxge_get_rdc_group(nxgep,
1469*4df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV6,
1470*4df55fdeSJanie Lu 		    flow_cookie);
1471*4df55fdeSJanie Lu 		offset = nxge_get_rdc_offset(nxgep,
1472*4df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV6,
1473*4df55fdeSJanie Lu 		    channel_cookie);
1474*4df55fdeSJanie Lu 		break;
1475*4df55fdeSJanie Lu 
1476*4df55fdeSJanie Lu 	case FSPEC_IP_USR:
1477*4df55fdeSJanie Lu 		nxge_fill_tcam_entry_ip_usr(nxgep, flow_spec, &tcam_ptr,
1478*4df55fdeSJanie Lu 		    (tcam_class_t)class);
1479*4df55fdeSJanie Lu 		rdc_grp = nxge_get_rdc_group(nxgep,
1480*4df55fdeSJanie Lu 		    (tcam_class_t)class, flow_cookie);
1481*4df55fdeSJanie Lu 		offset = nxge_get_rdc_offset(nxgep,
1482*4df55fdeSJanie Lu 		    (tcam_class_t)class, channel_cookie);
1483*4df55fdeSJanie Lu 		break;
1484a3c5bd6dSspeer 	default:
1485*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1486*4df55fdeSJanie Lu 		    "nxge_add_tcam_entry: Unknown flow spec 0x%x",
1487*4df55fdeSJanie Lu 		    flow_spec->flow_type));
1488*4df55fdeSJanie Lu 		return (NXGE_ERROR);
148944961713Sgirish 	}
149044961713Sgirish 
149144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
149252ccf843Smisaki 	    " nxge_add_tcam_entry write"
149352ccf843Smisaki 	    " for location %d offset %d", location, offset));
149444961713Sgirish 
149544961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
1496a3c5bd6dSspeer 	rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr);
149744961713Sgirish 
149844961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
149944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
150052ccf843Smisaki 		    " nxge_add_tcam_entry write"
150152ccf843Smisaki 		    " failed for location %d", location));
1502*4df55fdeSJanie Lu 		goto fail;
150344961713Sgirish 	}
1504a3c5bd6dSspeer 
150544961713Sgirish 	tcam_ptr.match_action.value = 0;
150644961713Sgirish 	tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp;
150744961713Sgirish 	tcam_ptr.match_action.bits.ldw.offset = offset;
150844961713Sgirish 	tcam_ptr.match_action.bits.ldw.tres =
150952ccf843Smisaki 	    TRES_TERM_OVRD_L2RDC;
1510*4df55fdeSJanie Lu 	if (channel_cookie == NXGE_PKT_DISCARD)
151144961713Sgirish 		tcam_ptr.match_action.bits.ldw.disc = 1;
151244961713Sgirish 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
151352ccf843Smisaki 	    location, tcam_ptr.match_action.value);
151444961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
151544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
151652ccf843Smisaki 		    " nxge_add_tcam_entry write"
151752ccf843Smisaki 		    " failed for ASC RAM location %d", location));
1518*4df55fdeSJanie Lu 		goto fail;
151944961713Sgirish 	}
1520a3c5bd6dSspeer 	bcopy((void *) &tcam_ptr,
152152ccf843Smisaki 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
152252ccf843Smisaki 	    sizeof (tcam_entry_t));
1523*4df55fdeSJanie Lu 	nxgep->classifier.tcam_entry_cnt++;
1524*4df55fdeSJanie Lu 	nxgep->classifier.tcam_entries[location].valid = 1;
152544961713Sgirish 
152644961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
152744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry"));
152844961713Sgirish 	return (NXGE_OK);
1529*4df55fdeSJanie Lu fail:
1530*4df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
1531*4df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_tcam_entry FAILED"));
1532*4df55fdeSJanie Lu 	return (NXGE_ERROR);
153344961713Sgirish }
153444961713Sgirish 
153514ea4bb7Ssd static nxge_status_t
153614ea4bb7Ssd nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)
153744961713Sgirish {
153844961713Sgirish 	tcam_entry_t tcam_ptr;
153944961713Sgirish 	tcam_location_t location;
154044961713Sgirish 	uint8_t class;
154114ea4bb7Ssd 	uint32_t class_config;
154244961713Sgirish 	npi_handle_t handle;
154344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1544a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
154514ea4bb7Ssd 	nxge_status_t status = NXGE_OK;
154644961713Sgirish 
154744961713Sgirish 	handle = nxgep->npi_reg_handle;
154844961713Sgirish 	class = 0;
1549a3c5bd6dSspeer 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
155044961713Sgirish 	tcam_ptr.ip4_noport_key = 1;
155144961713Sgirish 	tcam_ptr.ip4_noport_mask = 1;
155214ea4bb7Ssd 	location = nxgep->function_num;
155344961713Sgirish 	nxgep->classifier.fragment_bug_location = location;
155444961713Sgirish 
155544961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
155644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
155752ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment: common hardware not set",
155852ccf843Smisaki 		    nxgep->niu_type));
155914ea4bb7Ssd 		return (NXGE_ERROR);
156044961713Sgirish 	}
156144961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
156244961713Sgirish 	rs = npi_fflp_tcam_entry_write(handle,
156352ccf843Smisaki 	    location, &tcam_ptr);
156444961713Sgirish 
156544961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
156644961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
156744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
156852ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment "
156952ccf843Smisaki 		    " tcam_entry write"
157052ccf843Smisaki 		    " failed for location %d", location));
157114ea4bb7Ssd 		return (NXGE_ERROR);
157244961713Sgirish 	}
157344961713Sgirish 	tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp;
1574a3c5bd6dSspeer 	tcam_ptr.match_action.bits.ldw.offset = 0;	/* use the default */
157544961713Sgirish 	tcam_ptr.match_action.bits.ldw.tres =
157652ccf843Smisaki 	    TRES_TERM_USE_OFFSET;
157744961713Sgirish 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
157852ccf843Smisaki 	    location, tcam_ptr.match_action.value);
157944961713Sgirish 
158044961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
158144961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
158244961713Sgirish 		NXGE_DEBUG_MSG((nxgep,
158352ccf843Smisaki 		    FFLP_CTL,
158452ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment "
158552ccf843Smisaki 		    " tcam_entry write"
158652ccf843Smisaki 		    " failed for ASC RAM location %d", location));
158714ea4bb7Ssd 		return (NXGE_ERROR);
158844961713Sgirish 	}
1589a3c5bd6dSspeer 	bcopy((void *) &tcam_ptr,
159052ccf843Smisaki 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
159152ccf843Smisaki 	    sizeof (tcam_entry_t));
1592*4df55fdeSJanie Lu 	nxgep->classifier.tcam_entry_cnt++;
1593*4df55fdeSJanie Lu 	nxgep->classifier.tcam_entries[location].valid = 1;
159414ea4bb7Ssd 	for (class = TCAM_CLASS_TCP_IPV4;
159552ccf843Smisaki 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
159614ea4bb7Ssd 		class_config = nxgep->class_config.class_cfg[class];
159714ea4bb7Ssd 		class_config |= NXGE_CLASS_TCAM_LOOKUP;
159814ea4bb7Ssd 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
159914ea4bb7Ssd 
160014ea4bb7Ssd 		if (status & NPI_FFLP_ERROR) {
160114ea4bb7Ssd 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
160214ea4bb7Ssd 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
160352ccf843Smisaki 			    "nxge_tcam_handle_ip_fragment "
160452ccf843Smisaki 			    "nxge_fflp_ip_class_config failed "
160552ccf843Smisaki 			    " class %d config %x ", class, class_config));
160614ea4bb7Ssd 			return (NXGE_ERROR);
160714ea4bb7Ssd 		}
160814ea4bb7Ssd 	}
160914ea4bb7Ssd 
161014ea4bb7Ssd 	rs = npi_fflp_cfg_tcam_enable(handle);
161114ea4bb7Ssd 	if (rs & NPI_FFLP_ERROR) {
161214ea4bb7Ssd 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
161314ea4bb7Ssd 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
161452ccf843Smisaki 		    "nxge_tcam_handle_ip_fragment "
161552ccf843Smisaki 		    " nxge_fflp_config_tcam_enable failed"));
161614ea4bb7Ssd 		return (NXGE_ERROR);
161714ea4bb7Ssd 	}
161844961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
161914ea4bb7Ssd 	return (NXGE_OK);
162044961713Sgirish }
162144961713Sgirish 
162244961713Sgirish /* ARGSUSED */
162344961713Sgirish static int
1624a3c5bd6dSspeer nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res)
162544961713Sgirish {
162644961713Sgirish 	return (0);
162744961713Sgirish }
162844961713Sgirish 
162944961713Sgirish nxge_status_t
163044961713Sgirish nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res)
163144961713Sgirish {
163244961713Sgirish 
163344961713Sgirish 	int insert_hash = 0;
163444961713Sgirish 	nxge_status_t status = NXGE_OK;
163544961713Sgirish 
16362e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
1637a3c5bd6dSspeer 		/* determine whether to do TCAM or Hash flow */
163844961713Sgirish 		insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res);
163944961713Sgirish 	}
164044961713Sgirish 	if (insert_hash) {
164144961713Sgirish 		status = nxge_add_fcram_entry(nxgep, flow_res);
164244961713Sgirish 	} else {
164344961713Sgirish 		status = nxge_add_tcam_entry(nxgep, flow_res);
164444961713Sgirish 	}
164544961713Sgirish 	return (status);
164644961713Sgirish }
164744961713Sgirish 
164844961713Sgirish void
164944961713Sgirish nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp)
165044961713Sgirish {
165144961713Sgirish 	flow_resource_t *fs;
165244961713Sgirish 
1653a3c5bd6dSspeer 	fs = (flow_resource_t *)mp->b_rptr;
165444961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
165552ccf843Smisaki 	    "nxge_put_tcam addr fs $%p  type %x offset %x",
165652ccf843Smisaki 	    fs, fs->flow_spec.flow_type, fs->channel_cookie));
165744961713Sgirish 	(void) nxge_add_tcam_entry(nxgep, fs);
165844961713Sgirish }
165944961713Sgirish 
166044961713Sgirish nxge_status_t
166144961713Sgirish nxge_fflp_config_tcam_enable(p_nxge_t nxgep)
166244961713Sgirish {
166344961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
166444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
166544961713Sgirish 
166644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable"));
166744961713Sgirish 	rs = npi_fflp_cfg_tcam_enable(handle);
166844961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
166944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
167052ccf843Smisaki 		    " nxge_fflp_config_tcam_enable failed"));
167144961713Sgirish 		return (NXGE_ERROR | rs);
167244961713Sgirish 	}
167344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable"));
167444961713Sgirish 	return (NXGE_OK);
167544961713Sgirish }
167644961713Sgirish 
167744961713Sgirish nxge_status_t
167844961713Sgirish nxge_fflp_config_tcam_disable(p_nxge_t nxgep)
167944961713Sgirish {
168044961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
168144961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
168244961713Sgirish 
168344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
168452ccf843Smisaki 	    " ==> nxge_fflp_config_tcam_disable"));
168544961713Sgirish 	rs = npi_fflp_cfg_tcam_disable(handle);
168644961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
168744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
168852ccf843Smisaki 		    " nxge_fflp_config_tcam_disable failed"));
168944961713Sgirish 		return (NXGE_ERROR | rs);
169044961713Sgirish 	}
169144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
169252ccf843Smisaki 	    " <== nxge_fflp_config_tcam_disable"));
169344961713Sgirish 	return (NXGE_OK);
169444961713Sgirish }
169544961713Sgirish 
169644961713Sgirish nxge_status_t
169744961713Sgirish nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)
169844961713Sgirish {
169944961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
170044961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1701a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1702a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1703a3c5bd6dSspeer 	uint8_t partition;
170444961713Sgirish 
170544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
170652ccf843Smisaki 	    " ==> nxge_fflp_config_hash_lookup_enable"));
170744961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
170844961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
170944961713Sgirish 
1710678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1711678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
1712678453a8Sspeer 			rs = npi_fflp_cfg_fcram_partition_enable(
171352ccf843Smisaki 			    handle, partition);
1714678453a8Sspeer 			if (rs != NPI_SUCCESS) {
1715678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1716678453a8Sspeer 				    " nxge_fflp_config_hash_lookup_enable"
1717678453a8Sspeer 				    "failed FCRAM partition"
1718678453a8Sspeer 				    " enable for partition %d ", partition));
1719678453a8Sspeer 				return (NXGE_ERROR | rs);
1720678453a8Sspeer 			}
172144961713Sgirish 		}
172244961713Sgirish 	}
172344961713Sgirish 
172444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
172552ccf843Smisaki 	    " <== nxge_fflp_config_hash_lookup_enable"));
172644961713Sgirish 	return (NXGE_OK);
172744961713Sgirish }
172844961713Sgirish 
172944961713Sgirish nxge_status_t
173044961713Sgirish nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)
173144961713Sgirish {
173244961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
173344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1734a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1735a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1736a3c5bd6dSspeer 	uint8_t partition;
173744961713Sgirish 
173844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
173952ccf843Smisaki 	    " ==> nxge_fflp_config_hash_lookup_disable"));
174044961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
174144961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
174244961713Sgirish 
1743678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1744678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
1745678453a8Sspeer 			rs = npi_fflp_cfg_fcram_partition_disable(handle,
1746678453a8Sspeer 			    partition);
1747678453a8Sspeer 			if (rs != NPI_SUCCESS) {
1748678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1749678453a8Sspeer 				    " nxge_fflp_config_hash_lookup_disable"
1750678453a8Sspeer 				    " failed FCRAM partition"
1751678453a8Sspeer 				    " disable for partition %d ", partition));
1752678453a8Sspeer 				return (NXGE_ERROR | rs);
1753678453a8Sspeer 			}
175444961713Sgirish 		}
175544961713Sgirish 	}
175644961713Sgirish 
175744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
175852ccf843Smisaki 	    " <== nxge_fflp_config_hash_lookup_disable"));
175944961713Sgirish 	return (NXGE_OK);
176044961713Sgirish }
176144961713Sgirish 
176244961713Sgirish nxge_status_t
176344961713Sgirish nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)
176444961713Sgirish {
176544961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
176644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
176744961713Sgirish 
176844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
176952ccf843Smisaki 	    " ==> nxge_fflp_config_llc_snap_enable"));
177044961713Sgirish 	rs = npi_fflp_cfg_llcsnap_enable(handle);
177144961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
177244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
177352ccf843Smisaki 		    " nxge_fflp_config_llc_snap_enable failed"));
177444961713Sgirish 		return (NXGE_ERROR | rs);
177544961713Sgirish 	}
177644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
177752ccf843Smisaki 	    " <== nxge_fflp_config_llc_snap_enable"));
177844961713Sgirish 	return (NXGE_OK);
177944961713Sgirish }
178044961713Sgirish 
178144961713Sgirish nxge_status_t
178244961713Sgirish nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)
178344961713Sgirish {
178444961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
178544961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1786a3c5bd6dSspeer 
178744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
178852ccf843Smisaki 	    " ==> nxge_fflp_config_llc_snap_disable"));
178944961713Sgirish 	rs = npi_fflp_cfg_llcsnap_disable(handle);
179044961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
179144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
179252ccf843Smisaki 		    " nxge_fflp_config_llc_snap_disable failed"));
179344961713Sgirish 		return (NXGE_ERROR | rs);
179444961713Sgirish 	}
179544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
179652ccf843Smisaki 	    " <== nxge_fflp_config_llc_snap_disable"));
179744961713Sgirish 	return (NXGE_OK);
179844961713Sgirish }
179944961713Sgirish 
180044961713Sgirish nxge_status_t
180144961713Sgirish nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class,
1802a3c5bd6dSspeer 	uint32_t config)
180344961713Sgirish {
180444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
180544961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
180644961713Sgirish 	uint8_t tos, tos_mask, proto, ver = 0;
180744961713Sgirish 	uint8_t class_enable = 0;
180844961713Sgirish 
180944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config"));
181044961713Sgirish 
181144961713Sgirish 	tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >>
181252ccf843Smisaki 	    NXGE_CLASS_CFG_IP_TOS_SHIFT;
181344961713Sgirish 	tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >>
181452ccf843Smisaki 	    NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT;
181544961713Sgirish 	proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >>
181652ccf843Smisaki 	    NXGE_CLASS_CFG_IP_PROTO_SHIFT;
181744961713Sgirish 	if (config & NXGE_CLASS_CFG_IP_IPV6_MASK)
181844961713Sgirish 		ver = 1;
181944961713Sgirish 	if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK)
182044961713Sgirish 		class_enable = 1;
182144961713Sgirish 	rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask,
182252ccf843Smisaki 	    proto, ver);
182344961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
182444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
182552ccf843Smisaki 		    " nxge_fflp_ip_usr_class_config"
182652ccf843Smisaki 		    " for class %d failed ", class));
182744961713Sgirish 		return (NXGE_ERROR | rs);
182844961713Sgirish 	}
182944961713Sgirish 	if (class_enable)
183044961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class);
183144961713Sgirish 	else
183244961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
183344961713Sgirish 
183444961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
183544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
183652ccf843Smisaki 		    " nxge_fflp_ip_usr_class_config"
183752ccf843Smisaki 		    " TCAM enable/disable for class %d failed ", class));
183844961713Sgirish 		return (NXGE_ERROR | rs);
183944961713Sgirish 	}
184044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config"));
184144961713Sgirish 	return (NXGE_OK);
184244961713Sgirish }
184344961713Sgirish 
184444961713Sgirish nxge_status_t
1845a3c5bd6dSspeer nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config)
184644961713Sgirish {
184744961713Sgirish 	uint32_t class_config;
184844961713Sgirish 	nxge_status_t t_status = NXGE_OK;
184944961713Sgirish 	nxge_status_t f_status = NXGE_OK;
1850a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
185144961713Sgirish 
185244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
1853a3c5bd6dSspeer 
185444961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
185544961713Sgirish 	class_config = p_class_cfgp->class_cfg[class];
185644961713Sgirish 
185744961713Sgirish 	if (class_config != config) {
185844961713Sgirish 		p_class_cfgp->class_cfg[class] = config;
185944961713Sgirish 		class_config = config;
186044961713Sgirish 	}
186144961713Sgirish 
186244961713Sgirish 	t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config);
186344961713Sgirish 	f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config);
186444961713Sgirish 
186544961713Sgirish 	if (t_status & NPI_FFLP_ERROR) {
186644961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
186752ccf843Smisaki 		    " nxge_fflp_ip_class_config %x"
186852ccf843Smisaki 		    " for class %d tcam failed", config, class));
186944961713Sgirish 		return (t_status);
187044961713Sgirish 	}
187144961713Sgirish 	if (f_status & NPI_FFLP_ERROR) {
187244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
187352ccf843Smisaki 		    " nxge_fflp_ip_class_config %x"
187452ccf843Smisaki 		    " for class %d flow key failed", config, class));
187544961713Sgirish 		return (f_status);
187644961713Sgirish 	}
187744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
187844961713Sgirish 	return (NXGE_OK);
187944961713Sgirish }
188044961713Sgirish 
188144961713Sgirish nxge_status_t
188244961713Sgirish nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class,
1883a3c5bd6dSspeer 	uint32_t *config)
188444961713Sgirish {
188544961713Sgirish 	uint32_t t_class_config, f_class_config;
188644961713Sgirish 	int t_status = NXGE_OK;
188744961713Sgirish 	int f_status = NXGE_OK;
188844961713Sgirish 
188944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
1890a3c5bd6dSspeer 
189144961713Sgirish 	t_class_config = f_class_config = 0;
189244961713Sgirish 	t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config);
189344961713Sgirish 	f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config);
189444961713Sgirish 
189544961713Sgirish 	if (t_status & NPI_FFLP_ERROR) {
189644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
189752ccf843Smisaki 		    " nxge_fflp_ip_class_config_get  "
189852ccf843Smisaki 		    " for class %d tcam failed", class));
189944961713Sgirish 		return (t_status);
190044961713Sgirish 	}
190144961713Sgirish 
190244961713Sgirish 	if (f_status & NPI_FFLP_ERROR) {
190344961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
190452ccf843Smisaki 		    " nxge_fflp_ip_class_config_get  "
190552ccf843Smisaki 		    " for class %d flow key failed", class));
190644961713Sgirish 		return (f_status);
190744961713Sgirish 	}
190844961713Sgirish 
190944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
191052ccf843Smisaki 	    " nxge_fflp_ip_class_config tcam %x flow %x",
191152ccf843Smisaki 	    t_class_config, f_class_config));
191244961713Sgirish 
191344961713Sgirish 	*config = t_class_config | f_class_config;
191444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get"));
191544961713Sgirish 	return (NXGE_OK);
191644961713Sgirish }
191744961713Sgirish 
191844961713Sgirish nxge_status_t
191944961713Sgirish nxge_fflp_ip_class_config_all(p_nxge_t nxgep)
192044961713Sgirish {
192144961713Sgirish 	uint32_t class_config;
192244961713Sgirish 	tcam_class_t class;
192344961713Sgirish 
192444961713Sgirish #ifdef	NXGE_DEBUG
192544961713Sgirish 	int status = NXGE_OK;
192644961713Sgirish #endif
192744961713Sgirish 
192844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config"));
192944961713Sgirish 	for (class = TCAM_CLASS_TCP_IPV4;
193052ccf843Smisaki 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
193144961713Sgirish 		class_config = nxgep->class_config.class_cfg[class];
193244961713Sgirish #ifndef	NXGE_DEBUG
193344961713Sgirish 		(void) nxge_fflp_ip_class_config(nxgep, class, class_config);
193444961713Sgirish #else
193544961713Sgirish 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
193644961713Sgirish 		if (status & NPI_FFLP_ERROR) {
193744961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
193852ccf843Smisaki 			    "nxge_fflp_ip_class_config failed "
193952ccf843Smisaki 			    " class %d config %x ",
194052ccf843Smisaki 			    class, class_config));
194144961713Sgirish 		}
194244961713Sgirish #endif
194344961713Sgirish 	}
194444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
194544961713Sgirish 	return (NXGE_OK);
194644961713Sgirish }
194744961713Sgirish 
194844961713Sgirish nxge_status_t
194944961713Sgirish nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id)
195044961713Sgirish {
195144961713Sgirish 	uint8_t port, rdc_grp;
195244961713Sgirish 	npi_handle_t handle;
195344961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
195444961713Sgirish 	uint8_t priority = 1;
195544961713Sgirish 	p_nxge_mv_cfg_t vlan_table;
1956a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1957a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
195844961713Sgirish 
195944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table"));
196044961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
196144961713Sgirish 	handle = nxgep->npi_reg_handle;
196244961713Sgirish 	vlan_table = p_class_cfgp->vlan_tbl;
196344961713Sgirish 	port = nxgep->function_num;
196444961713Sgirish 
196544961713Sgirish 	if (vlan_table[vlan_id].flag == 0) {
196644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
196752ccf843Smisaki 		    " nxge_fflp_config_vlan_table"
196852ccf843Smisaki 		    " vlan id is not configured %d", vlan_id));
196944961713Sgirish 		return (NXGE_ERROR);
197044961713Sgirish 	}
197144961713Sgirish 
197244961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
197344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
197452ccf843Smisaki 		    " nxge_fflp_config_vlan_table:"
197552ccf843Smisaki 		    " common hardware not set", nxgep->niu_type));
197644961713Sgirish 		return (NXGE_ERROR);
197744961713Sgirish 	}
197844961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_vlan_lock);
197944961713Sgirish 	rdc_grp = vlan_table[vlan_id].rdctbl;
198044961713Sgirish 	rs = npi_fflp_cfg_enet_vlan_table_assoc(handle,
198152ccf843Smisaki 	    port, vlan_id,
198252ccf843Smisaki 	    rdc_grp, priority);
198344961713Sgirish 
198444961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_vlan_lock);
198544961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
198644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
198752ccf843Smisaki 		    "nxge_fflp_config_vlan_table failed "
198852ccf843Smisaki 		    " Port %d vlan_id %d rdc_grp %d",
198952ccf843Smisaki 		    port, vlan_id, rdc_grp));
199044961713Sgirish 		return (NXGE_ERROR | rs);
199144961713Sgirish 	}
1992a3c5bd6dSspeer 
199344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table"));
199444961713Sgirish 	return (NXGE_OK);
199544961713Sgirish }
199644961713Sgirish 
199744961713Sgirish nxge_status_t
199844961713Sgirish nxge_fflp_update_hw(p_nxge_t nxgep)
199944961713Sgirish {
200044961713Sgirish 	nxge_status_t status = NXGE_OK;
200144961713Sgirish 	p_nxge_param_t pa;
200244961713Sgirish 	uint64_t cfgd_vlans;
200344961713Sgirish 	uint64_t *val_ptr;
200444961713Sgirish 	int i;
200544961713Sgirish 	int num_macs;
200644961713Sgirish 	uint8_t alt_mac;
200744961713Sgirish 	nxge_param_map_t *p_map;
200844961713Sgirish 	p_nxge_mv_cfg_t vlan_table;
2009a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
2010a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_all_cfgp;
2011a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
201244961713Sgirish 
201344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw"));
2014a3c5bd6dSspeer 
201544961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
201644961713Sgirish 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
201744961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
201844961713Sgirish 
201944961713Sgirish 	status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1);
202044961713Sgirish 	if (status != NXGE_OK) {
202144961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
202252ccf843Smisaki 		    "nxge_fflp_set_hash1 Failed"));
202344961713Sgirish 		return (NXGE_ERROR);
202444961713Sgirish 	}
202544961713Sgirish 
202644961713Sgirish 	status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2);
202744961713Sgirish 	if (status != NXGE_OK) {
202844961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
202952ccf843Smisaki 		    "nxge_fflp_set_hash2 Failed"));
203044961713Sgirish 		return (NXGE_ERROR);
203144961713Sgirish 	}
203244961713Sgirish 	vlan_table = p_class_cfgp->vlan_tbl;
203344961713Sgirish 
2034a3c5bd6dSspeer 	/* configure vlan tables */
203544961713Sgirish 	pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp];
2036adfcba55Sjoycey #if defined(__i386)
2037adfcba55Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
2038adfcba55Sjoycey #else
203944961713Sgirish 	val_ptr = (uint64_t *)pa->value;
2040adfcba55Sjoycey #endif
2041a3c5bd6dSspeer 	cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >>
204252ccf843Smisaki 	    NXGE_PARAM_ARRAY_CNT_SHIFT);
204344961713Sgirish 
204444961713Sgirish 	for (i = 0; i < cfgd_vlans; i++) {
204544961713Sgirish 		p_map = (nxge_param_map_t *)&val_ptr[i];
204644961713Sgirish 		if (vlan_table[p_map->param_id].flag) {
204744961713Sgirish 			status = nxge_fflp_config_vlan_table(nxgep,
204852ccf843Smisaki 			    p_map->param_id);
204944961713Sgirish 			if (status != NXGE_OK) {
205044961713Sgirish 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
205152ccf843Smisaki 				    "nxge_fflp_config_vlan_table Failed"));
205244961713Sgirish 				return (NXGE_ERROR);
205344961713Sgirish 			}
205444961713Sgirish 		}
205544961713Sgirish 	}
2056a3c5bd6dSspeer 
2057a3c5bd6dSspeer 	/* config MAC addresses */
205844961713Sgirish 	num_macs = p_cfgp->max_macs;
205944961713Sgirish 	pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp];
2060adfcba55Sjoycey #if defined(__i386)
2061adfcba55Sjoycey 	val_ptr = (uint64_t *)(uint32_t)pa->value;
2062adfcba55Sjoycey #else
206344961713Sgirish 	val_ptr = (uint64_t *)pa->value;
2064adfcba55Sjoycey #endif
206544961713Sgirish 
206644961713Sgirish 	for (alt_mac = 0; alt_mac < num_macs; alt_mac++) {
206744961713Sgirish 		if (p_class_cfgp->mac_host_info[alt_mac].flag) {
206844961713Sgirish 			status = nxge_logical_mac_assign_rdc_table(nxgep,
206952ccf843Smisaki 			    alt_mac);
207044961713Sgirish 			if (status != NXGE_OK) {
207144961713Sgirish 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
207252ccf843Smisaki 				    "nxge_logical_mac_assign_rdc_table"
207352ccf843Smisaki 				    " Failed"));
207444961713Sgirish 				return (NXGE_ERROR);
207544961713Sgirish 			}
207644961713Sgirish 		}
207744961713Sgirish 	}
2078a3c5bd6dSspeer 
2079a3c5bd6dSspeer 	/* Config Hash values */
2080f6485eecSyc 	/* config classes */
208144961713Sgirish 	status = nxge_fflp_ip_class_config_all(nxgep);
208244961713Sgirish 	if (status != NXGE_OK) {
208344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
208452ccf843Smisaki 		    "nxge_fflp_ip_class_config_all Failed"));
208544961713Sgirish 		return (NXGE_ERROR);
208644961713Sgirish 	}
208744961713Sgirish 	return (NXGE_OK);
208844961713Sgirish }
208944961713Sgirish 
209044961713Sgirish nxge_status_t
209144961713Sgirish nxge_classify_init_hw(p_nxge_t nxgep)
209244961713Sgirish {
209344961713Sgirish 	nxge_status_t status = NXGE_OK;
209444961713Sgirish 
209544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw"));
209644961713Sgirish 
209744961713Sgirish 	if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) {
209844961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
209952ccf843Smisaki 		    "nxge_classify_init_hw already init"));
210044961713Sgirish 		return (NXGE_OK);
210144961713Sgirish 	}
210244961713Sgirish 
2103a3c5bd6dSspeer 	/* Now do a real configuration */
210444961713Sgirish 	status = nxge_fflp_update_hw(nxgep);
210544961713Sgirish 	if (status != NXGE_OK) {
210644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
210752ccf843Smisaki 		    "nxge_fflp_update_hw failed"));
210844961713Sgirish 		return (NXGE_ERROR);
210944961713Sgirish 	}
2110a3c5bd6dSspeer 
2111a3c5bd6dSspeer 	/* Init RDC tables? ? who should do that? rxdma or fflp ? */
2112a3c5bd6dSspeer 	/* attach rdc table to the MAC port. */
211344961713Sgirish 	status = nxge_main_mac_assign_rdc_table(nxgep);
211444961713Sgirish 	if (status != NXGE_OK) {
211544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
211652ccf843Smisaki 		    "nxge_main_mac_assign_rdc_table failed"));
211744961713Sgirish 		return (NXGE_ERROR);
211844961713Sgirish 	}
2119a3c5bd6dSspeer 
212058324dfcSspeer 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
212144961713Sgirish 	if (status != NXGE_OK) {
212244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
212352ccf843Smisaki 		    "nxge_multicast_mac_assign_rdc_table failed"));
212444961713Sgirish 		return (NXGE_ERROR);
212544961713Sgirish 	}
212614ea4bb7Ssd 
2127*4df55fdeSJanie Lu 	if (nxgep->classifier.fragment_bug == 1) {
2128*4df55fdeSJanie Lu 		status = nxge_tcam_handle_ip_fragment(nxgep);
2129*4df55fdeSJanie Lu 		if (status != NXGE_OK) {
2130*4df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2131*4df55fdeSJanie Lu 			    "nxge_tcam_handle_ip_fragment failed"));
2132*4df55fdeSJanie Lu 			return (NXGE_ERROR);
2133*4df55fdeSJanie Lu 		}
213414ea4bb7Ssd 	}
213544961713Sgirish 
213644961713Sgirish 	nxgep->classifier.state |= NXGE_FFLP_HW_INIT;
213744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw"));
213844961713Sgirish 	return (NXGE_OK);
213944961713Sgirish }
214044961713Sgirish 
214144961713Sgirish nxge_status_t
214244961713Sgirish nxge_fflp_handle_sys_errors(p_nxge_t nxgep)
214344961713Sgirish {
2144a3c5bd6dSspeer 	npi_handle_t handle;
2145a3c5bd6dSspeer 	p_nxge_fflp_stats_t statsp;
2146a3c5bd6dSspeer 	uint8_t portn, rdc_grp;
2147a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
2148a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
2149a3c5bd6dSspeer 	vlan_par_err_t vlan_err;
2150a3c5bd6dSspeer 	tcam_err_t tcam_err;
2151a3c5bd6dSspeer 	hash_lookup_err_log1_t fcram1_err;
2152a3c5bd6dSspeer 	hash_lookup_err_log2_t fcram2_err;
2153a3c5bd6dSspeer 	hash_tbl_data_log_t fcram_err;
215444961713Sgirish 
215544961713Sgirish 	handle = nxgep->npi_handle;
215644961713Sgirish 	statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats;
215744961713Sgirish 	portn = nxgep->mac.portnum;
215844961713Sgirish 
215944961713Sgirish 	/*
2160a3c5bd6dSspeer 	 * need to read the fflp error registers to figure out what the error
2161a3c5bd6dSspeer 	 * is
216244961713Sgirish 	 */
216344961713Sgirish 	npi_fflp_vlan_error_get(handle, &vlan_err);
216444961713Sgirish 	npi_fflp_tcam_error_get(handle, &tcam_err);
216544961713Sgirish 
216644961713Sgirish 	if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) {
216744961713Sgirish 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
216852ccf843Smisaki 		    " vlan table parity error on port %d"
216952ccf843Smisaki 		    " addr: 0x%x data: 0x%x",
217052ccf843Smisaki 		    portn, vlan_err.bits.ldw.addr,
217152ccf843Smisaki 		    vlan_err.bits.ldw.data));
217244961713Sgirish 		statsp->vlan_parity_err++;
217344961713Sgirish 
217444961713Sgirish 		if (vlan_err.bits.ldw.m_err) {
217544961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
217652ccf843Smisaki 			    " vlan table multiple errors on port %d",
217752ccf843Smisaki 			    portn));
217844961713Sgirish 		}
217944961713Sgirish 		statsp->errlog.vlan = (uint32_t)vlan_err.value;
218044961713Sgirish 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
218152ccf843Smisaki 		    NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR);
218244961713Sgirish 		npi_fflp_vlan_error_clear(handle);
218344961713Sgirish 	}
218444961713Sgirish 
218544961713Sgirish 	if (tcam_err.bits.ldw.err) {
218644961713Sgirish 		if (tcam_err.bits.ldw.p_ecc != 0) {
218744961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
218852ccf843Smisaki 			    " TCAM ECC error on port %d"
218952ccf843Smisaki 			    " TCAM entry: 0x%x syndrome: 0x%x",
219052ccf843Smisaki 			    portn, tcam_err.bits.ldw.addr,
219152ccf843Smisaki 			    tcam_err.bits.ldw.syndrome));
219244961713Sgirish 			statsp->tcam_ecc_err++;
219344961713Sgirish 		} else {
219444961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
219552ccf843Smisaki 			    " TCAM Parity error on port %d"
219652ccf843Smisaki 			    " addr: 0x%x parity value: 0x%x",
219752ccf843Smisaki 			    portn, tcam_err.bits.ldw.addr,
219852ccf843Smisaki 			    tcam_err.bits.ldw.syndrome));
219944961713Sgirish 			statsp->tcam_parity_err++;
220044961713Sgirish 		}
220144961713Sgirish 
220244961713Sgirish 		if (tcam_err.bits.ldw.mult) {
220344961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
220452ccf843Smisaki 			    " TCAM Multiple errors on port %d", portn));
220544961713Sgirish 		} else {
220644961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
220752ccf843Smisaki 			    " TCAM PIO error on port %d", portn));
220844961713Sgirish 		}
220944961713Sgirish 
221044961713Sgirish 		statsp->errlog.tcam = (uint32_t)tcam_err.value;
221144961713Sgirish 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
221252ccf843Smisaki 		    NXGE_FM_EREPORT_FFLP_TCAM_ERR);
221344961713Sgirish 		npi_fflp_tcam_error_clear(handle);
221444961713Sgirish 	}
221544961713Sgirish 
221644961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
221744961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
221844961713Sgirish 
2219678453a8Sspeer 	for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) {
2220678453a8Sspeer 		if (p_cfgp->grpids[rdc_grp]) {
2221678453a8Sspeer 			npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp);
2222678453a8Sspeer 			if (fcram_err.bits.ldw.pio_err) {
2223678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, FFLP_CTL,
222452ccf843Smisaki 				    " FCRAM PIO ECC error on port %d"
222552ccf843Smisaki 				    " rdc group: %d Hash Table addr: 0x%x"
222652ccf843Smisaki 				    " syndrome: 0x%x",
222752ccf843Smisaki 				    portn, rdc_grp,
222852ccf843Smisaki 				    fcram_err.bits.ldw.fcram_addr,
222952ccf843Smisaki 				    fcram_err.bits.ldw.syndrome));
2230678453a8Sspeer 				statsp->hash_pio_err[rdc_grp]++;
2231678453a8Sspeer 				statsp->errlog.hash_pio[rdc_grp] =
2232678453a8Sspeer 				    (uint32_t)fcram_err.value;
2233678453a8Sspeer 				NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
2234678453a8Sspeer 				    NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR);
2235678453a8Sspeer 				npi_fflp_fcram_error_clear(handle, rdc_grp);
2236678453a8Sspeer 			}
223744961713Sgirish 		}
223844961713Sgirish 	}
223944961713Sgirish 
224044961713Sgirish 	npi_fflp_fcram_error_log1_get(handle, &fcram1_err);
224144961713Sgirish 	if (fcram1_err.bits.ldw.ecc_err) {
224244961713Sgirish 		char *multi_str = "";
224344961713Sgirish 		char *multi_bit_str = "";
2244a3c5bd6dSspeer 
224544961713Sgirish 		npi_fflp_fcram_error_log2_get(handle, &fcram2_err);
224644961713Sgirish 		if (fcram1_err.bits.ldw.mult_lk) {
224744961713Sgirish 			multi_str = "multiple";
224844961713Sgirish 		}
224944961713Sgirish 		if (fcram1_err.bits.ldw.mult_bit) {
225044961713Sgirish 			multi_bit_str = "multiple bits";
225144961713Sgirish 		}
2252f6485eecSyc 		statsp->hash_lookup_err++;
225344961713Sgirish 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
225452ccf843Smisaki 		    " FCRAM %s lookup %s ECC error on port %d"
225552ccf843Smisaki 		    " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x",
225652ccf843Smisaki 		    multi_str, multi_bit_str, portn,
225752ccf843Smisaki 		    fcram2_err.bits.ldw.h1,
225852ccf843Smisaki 		    fcram2_err.bits.ldw.subarea,
225952ccf843Smisaki 		    fcram2_err.bits.ldw.syndrome));
226044961713Sgirish 		NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
226152ccf843Smisaki 		    NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR);
226244961713Sgirish 	}
226344961713Sgirish 	statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value;
226444961713Sgirish 	statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value;
226544961713Sgirish 	return (NXGE_OK);
226644961713Sgirish }
2267*4df55fdeSJanie Lu 
2268*4df55fdeSJanie Lu int
2269*4df55fdeSJanie Lu nxge_get_valid_tcam_cnt(p_nxge_t nxgep) {
2270*4df55fdeSJanie Lu 	return ((nxgep->classifier.fragment_bug == 1) ?
2271*4df55fdeSJanie Lu 		nxgep->classifier.tcam_entry_cnt - 1 :
2272*4df55fdeSJanie Lu 		nxgep->classifier.tcam_entry_cnt);
2273*4df55fdeSJanie Lu }
2274*4df55fdeSJanie Lu 
2275*4df55fdeSJanie Lu int
2276*4df55fdeSJanie Lu nxge_rxdma_channel_cnt(p_nxge_t nxgep)
2277*4df55fdeSJanie Lu {
2278*4df55fdeSJanie Lu 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
2279*4df55fdeSJanie Lu 	p_nxge_hw_pt_cfg_t p_cfgp;
2280*4df55fdeSJanie Lu 
2281*4df55fdeSJanie Lu 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
2282*4df55fdeSJanie Lu 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
2283*4df55fdeSJanie Lu 	return (p_cfgp->max_rdcs);
2284*4df55fdeSJanie Lu }
2285*4df55fdeSJanie Lu 
2286*4df55fdeSJanie Lu /* ARGSUSED */
2287*4df55fdeSJanie Lu int
2288*4df55fdeSJanie Lu nxge_rxclass_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
2289*4df55fdeSJanie Lu {
2290*4df55fdeSJanie Lu 	uint32_t cmd;
2291*4df55fdeSJanie Lu 	rx_class_cfg_t *cfg_info = (rx_class_cfg_t *)mp->b_rptr;
2292*4df55fdeSJanie Lu 
2293*4df55fdeSJanie Lu 	if (nxgep == NULL) {
2294*4df55fdeSJanie Lu 		return (-1);
2295*4df55fdeSJanie Lu 	}
2296*4df55fdeSJanie Lu 	cmd = cfg_info->cmd;
2297*4df55fdeSJanie Lu 	switch (cmd) {
2298*4df55fdeSJanie Lu 	default:
2299*4df55fdeSJanie Lu 		return (-1);
2300*4df55fdeSJanie Lu 
2301*4df55fdeSJanie Lu 	case NXGE_RX_CLASS_GCHAN:
2302*4df55fdeSJanie Lu 		cfg_info->data = nxge_rxdma_channel_cnt(nxgep);
2303*4df55fdeSJanie Lu 		break;
2304*4df55fdeSJanie Lu 	case NXGE_RX_CLASS_GRULE_CNT:
2305*4df55fdeSJanie Lu 		MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
2306*4df55fdeSJanie Lu 		cfg_info->rule_cnt = nxge_get_valid_tcam_cnt(nxgep);
2307*4df55fdeSJanie Lu 		MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
2308*4df55fdeSJanie Lu 		break;
2309*4df55fdeSJanie Lu 	case NXGE_RX_CLASS_GRULE:
2310*4df55fdeSJanie Lu 		nxge_get_tcam_entry(nxgep, &cfg_info->fs);
2311*4df55fdeSJanie Lu 		break;
2312*4df55fdeSJanie Lu 	case NXGE_RX_CLASS_GRULE_ALL:
2313*4df55fdeSJanie Lu 		nxge_get_tcam_entry_all(nxgep, cfg_info);
2314*4df55fdeSJanie Lu 		break;
2315*4df55fdeSJanie Lu 	case NXGE_RX_CLASS_RULE_DEL:
2316*4df55fdeSJanie Lu 		nxge_del_tcam_entry(nxgep, cfg_info->fs.location);
2317*4df55fdeSJanie Lu 		break;
2318*4df55fdeSJanie Lu 	case NXGE_RX_CLASS_RULE_INS:
2319*4df55fdeSJanie Lu 		(void) nxge_add_tcam_entry(nxgep, &cfg_info->fs);
2320*4df55fdeSJanie Lu 		break;
2321*4df55fdeSJanie Lu 	}
2322*4df55fdeSJanie Lu 	return (0);
2323*4df55fdeSJanie Lu }
2324*4df55fdeSJanie Lu /* ARGSUSED */
2325*4df55fdeSJanie Lu int
2326*4df55fdeSJanie Lu nxge_rxhash_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
2327*4df55fdeSJanie Lu {
2328*4df55fdeSJanie Lu 	uint32_t cmd;
2329*4df55fdeSJanie Lu 	cfg_cmd_t	*cfg_info = (cfg_cmd_t *)mp->b_rptr;
2330*4df55fdeSJanie Lu 
2331*4df55fdeSJanie Lu 	if (nxgep == NULL) {
2332*4df55fdeSJanie Lu 		return (-1);
2333*4df55fdeSJanie Lu 	}
2334*4df55fdeSJanie Lu 	cmd = cfg_info->cmd;
2335*4df55fdeSJanie Lu 
2336*4df55fdeSJanie Lu 	switch (cmd) {
2337*4df55fdeSJanie Lu 	default:
2338*4df55fdeSJanie Lu 		return (-1);
2339*4df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_ADD_CLS:
2340*4df55fdeSJanie Lu 		nxge_add_iptun_class(nxgep, &cfg_info->iptun_cfg,
2341*4df55fdeSJanie Lu 		    &cfg_info->class_id);
2342*4df55fdeSJanie Lu 		break;
2343*4df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_SET_HASH:
2344*4df55fdeSJanie Lu 		nxge_cfg_iptun_hash(nxgep, &cfg_info->iptun_cfg,
2345*4df55fdeSJanie Lu 		    cfg_info->class_id);
2346*4df55fdeSJanie Lu 		break;
2347*4df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_DEL_CLS:
2348*4df55fdeSJanie Lu 		nxge_del_iptun_class(nxgep, cfg_info->class_id);
2349*4df55fdeSJanie Lu 		break;
2350*4df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_GET_CLS:
2351*4df55fdeSJanie Lu 		nxge_get_iptun_class(nxgep, &cfg_info->iptun_cfg,
2352*4df55fdeSJanie Lu 		    cfg_info->class_id);
2353*4df55fdeSJanie Lu 		break;
2354*4df55fdeSJanie Lu 	case NXGE_CLS_CFG_SET_SYM:
2355*4df55fdeSJanie Lu 		nxge_set_ip_cls_sym(nxgep, cfg_info->class_id, cfg_info->sym);
2356*4df55fdeSJanie Lu 		break;
2357*4df55fdeSJanie Lu 	case NXGE_CLS_CFG_GET_SYM:
2358*4df55fdeSJanie Lu 		nxge_get_ip_cls_sym(nxgep, cfg_info->class_id, &cfg_info->sym);
2359*4df55fdeSJanie Lu 		break;
2360*4df55fdeSJanie Lu 	}
2361*4df55fdeSJanie Lu 	return (0);
2362*4df55fdeSJanie Lu }
2363*4df55fdeSJanie Lu 
2364*4df55fdeSJanie Lu void
2365*4df55fdeSJanie Lu nxge_get_tcam_entry_all(p_nxge_t nxgep, rx_class_cfg_t *cfgp)
2366*4df55fdeSJanie Lu {
2367*4df55fdeSJanie Lu 	nxge_classify_t *clasp = &nxgep->classifier;
2368*4df55fdeSJanie Lu 	uint16_t	n_entries;
2369*4df55fdeSJanie Lu 	int		i, j, k;
2370*4df55fdeSJanie Lu 	tcam_flow_spec_t	*tcam_entryp;
2371*4df55fdeSJanie Lu 
2372*4df55fdeSJanie Lu 	cfgp->data = clasp->tcam_size;
2373*4df55fdeSJanie Lu 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
2374*4df55fdeSJanie Lu 	n_entries = cfgp->rule_cnt;
2375*4df55fdeSJanie Lu 
2376*4df55fdeSJanie Lu 	for (i = 0, j = 0; j < cfgp->data; j++) {
2377*4df55fdeSJanie Lu 		k = nxge_tcam_get_index(nxgep, j);
2378*4df55fdeSJanie Lu 		tcam_entryp = &clasp->tcam_entries[k];
2379*4df55fdeSJanie Lu 		if (tcam_entryp->valid != 1)
2380*4df55fdeSJanie Lu 			continue;
2381*4df55fdeSJanie Lu 		cfgp->rule_locs[i] = j;
2382*4df55fdeSJanie Lu 		i++;
2383*4df55fdeSJanie Lu 	};
2384*4df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
2385*4df55fdeSJanie Lu 
2386*4df55fdeSJanie Lu 	if (n_entries != i) {
2387*4df55fdeSJanie Lu 		/* print warning, this should not happen */
2388*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry_all"
2389*4df55fdeSJanie Lu 		    "n_entries[%d] != i[%d]!!!", n_entries, i));
2390*4df55fdeSJanie Lu 	}
2391*4df55fdeSJanie Lu }
2392*4df55fdeSJanie Lu 
2393*4df55fdeSJanie Lu 
2394*4df55fdeSJanie Lu /* Entries for the ports are interleaved in the TCAM */
2395*4df55fdeSJanie Lu static uint16_t
2396*4df55fdeSJanie Lu nxge_tcam_get_index(p_nxge_t nxgep, uint16_t index)
2397*4df55fdeSJanie Lu {
2398*4df55fdeSJanie Lu 	/* One entry reserved for IP fragment rule */
2399*4df55fdeSJanie Lu 	if (index >= (nxgep->classifier.tcam_size - 1))
2400*4df55fdeSJanie Lu 		index = 0;
2401*4df55fdeSJanie Lu 	if (nxgep->classifier.fragment_bug == 1)
2402*4df55fdeSJanie Lu 		index++;
2403*4df55fdeSJanie Lu 	return (nxgep->classifier.tcam_top + (index * nxgep->nports));
2404*4df55fdeSJanie Lu }
2405*4df55fdeSJanie Lu 
2406*4df55fdeSJanie Lu static uint32_t
2407*4df55fdeSJanie Lu nxge_tcam_cls_to_flow(uint32_t class_code) {
2408*4df55fdeSJanie Lu 	switch (class_code) {
2409*4df55fdeSJanie Lu 	case TCAM_CLASS_TCP_IPV4:
2410*4df55fdeSJanie Lu 		return (FSPEC_TCPIP4);
2411*4df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV4:
2412*4df55fdeSJanie Lu 		return (FSPEC_UDPIP4);
2413*4df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV4:
2414*4df55fdeSJanie Lu 		return (FSPEC_AHIP4);
2415*4df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV4:
2416*4df55fdeSJanie Lu 		return (FSPEC_SCTPIP4);
2417*4df55fdeSJanie Lu 	case  TCAM_CLASS_TCP_IPV6:
2418*4df55fdeSJanie Lu 		return (FSPEC_TCPIP6);
2419*4df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV6:
2420*4df55fdeSJanie Lu 		return (FSPEC_UDPIP6);
2421*4df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV6:
2422*4df55fdeSJanie Lu 		return (FSPEC_AHIP6);
2423*4df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV6:
2424*4df55fdeSJanie Lu 		return (FSPEC_SCTPIP6);
2425*4df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_4:
2426*4df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_5:
2427*4df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_6:
2428*4df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_7:
2429*4df55fdeSJanie Lu 		return (FSPEC_IP_USR);
2430*4df55fdeSJanie Lu 	default:
2431*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "nxge_tcam_cls_to_flow"
2432*4df55fdeSJanie Lu 		    ": Unknown class code [0x%x]", class_code));
2433*4df55fdeSJanie Lu 		break;
2434*4df55fdeSJanie Lu 	}
2435*4df55fdeSJanie Lu 	return (0);
2436*4df55fdeSJanie Lu }
2437*4df55fdeSJanie Lu 
2438*4df55fdeSJanie Lu void
2439*4df55fdeSJanie Lu nxge_get_tcam_entry(p_nxge_t nxgep, flow_resource_t *fs)
2440*4df55fdeSJanie Lu {
2441*4df55fdeSJanie Lu 	uint16_t 	index;
2442*4df55fdeSJanie Lu 	tcam_flow_spec_t *tcam_ep;
2443*4df55fdeSJanie Lu 	tcam_entry_t	*tp;
2444*4df55fdeSJanie Lu 	flow_spec_t	*fspec;
2445*4df55fdeSJanie Lu 	tcpip4_spec_t 	*fspec_key;
2446*4df55fdeSJanie Lu 	tcpip4_spec_t 	*fspec_mask;
2447*4df55fdeSJanie Lu 
2448*4df55fdeSJanie Lu 	index = nxge_tcam_get_index(nxgep, (uint16_t)fs->location);
2449*4df55fdeSJanie Lu 	tcam_ep = &nxgep->classifier.tcam_entries[index];
2450*4df55fdeSJanie Lu 	if (tcam_ep->valid != 1) {
2451*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry: :"
2452*4df55fdeSJanie Lu 		    "Entry [%d] invalid for index [%d]", fs->location, index));
2453*4df55fdeSJanie Lu 		return;
2454*4df55fdeSJanie Lu 	}
2455*4df55fdeSJanie Lu 
2456*4df55fdeSJanie Lu 	/* Fill the flow spec entry */
2457*4df55fdeSJanie Lu 	tp = &tcam_ep->tce;
2458*4df55fdeSJanie Lu 	fspec = &fs->flow_spec;
2459*4df55fdeSJanie Lu 	fspec->flow_type = nxge_tcam_cls_to_flow(tp->ip4_class_key);
2460*4df55fdeSJanie Lu 
2461*4df55fdeSJanie Lu 	/* TODO - look at proto field to differentiate between AH and ESP */
2462*4df55fdeSJanie Lu 	if (fspec->flow_type == FSPEC_AHIP4) {
2463*4df55fdeSJanie Lu 		if (tp->ip4_proto_key == IPPROTO_ESP)
2464*4df55fdeSJanie Lu 			fspec->flow_type = FSPEC_ESPIP4;
2465*4df55fdeSJanie Lu 	}
2466*4df55fdeSJanie Lu 
2467*4df55fdeSJanie Lu 	switch (tp->ip4_class_key) {
2468*4df55fdeSJanie Lu 	case TCAM_CLASS_TCP_IPV4:
2469*4df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV4:
2470*4df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV4:
2471*4df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV4:
2472*4df55fdeSJanie Lu 		fspec_key = (tcpip4_spec_t *)&fspec->uh.tcpip4spec;
2473*4df55fdeSJanie Lu 		fspec_mask = (tcpip4_spec_t *)&fspec->um.tcpip4spec;
2474*4df55fdeSJanie Lu 		FSPEC_IPV4_ADDR(fspec_key->ip4dst, tp->ip4_dest_key);
2475*4df55fdeSJanie Lu 		FSPEC_IPV4_ADDR(fspec_mask->ip4dst, tp->ip4_dest_mask);
2476*4df55fdeSJanie Lu 		FSPEC_IPV4_ADDR(fspec_key->ip4src, tp->ip4_src_key);
2477*4df55fdeSJanie Lu 		FSPEC_IPV4_ADDR(fspec_mask->ip4src, tp->ip4_src_mask);
2478*4df55fdeSJanie Lu 		fspec_key->tos = tp->ip4_tos_key;
2479*4df55fdeSJanie Lu 		fspec_mask->tos = tp->ip4_tos_mask;
2480*4df55fdeSJanie Lu 		break;
2481*4df55fdeSJanie Lu 	default:
2482*4df55fdeSJanie Lu 		break;
2483*4df55fdeSJanie Lu 	}
2484*4df55fdeSJanie Lu 
2485*4df55fdeSJanie Lu 	switch (tp->ip4_class_key) {
2486*4df55fdeSJanie Lu 	case TCAM_CLASS_TCP_IPV4:
2487*4df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV4:
2488*4df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV4:
2489*4df55fdeSJanie Lu 		FSPEC_IP_PORTS(fspec_key->pdst, fspec_key->psrc,
2490*4df55fdeSJanie Lu 		    tp->ip4_port_key);
2491*4df55fdeSJanie Lu 		FSPEC_IP_PORTS(fspec_mask->pdst, fspec_mask->psrc,
2492*4df55fdeSJanie Lu 		    tp->ip4_port_mask);
2493*4df55fdeSJanie Lu 		break;
2494*4df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV4:
2495*4df55fdeSJanie Lu 		fspec->uh.ahip4spec.spi = tp->ip4_port_key;
2496*4df55fdeSJanie Lu 		fspec->um.ahip4spec.spi = tp->ip4_port_mask;
2497*4df55fdeSJanie Lu 		break;
2498*4df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_4:
2499*4df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_5:
2500*4df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_6:
2501*4df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_7:
2502*4df55fdeSJanie Lu 		fspec->uh.ip_usr_spec.l4_4_bytes = tp->ip4_port_key;
2503*4df55fdeSJanie Lu 		fspec->um.ip_usr_spec.l4_4_bytes = tp->ip4_port_mask;
2504*4df55fdeSJanie Lu 		fspec->uh.ip_usr_spec.ip_ver = FSPEC_IP4;
2505*4df55fdeSJanie Lu 		fspec->uh.ip_usr_spec.proto = tp->ip4_proto_key;
2506*4df55fdeSJanie Lu 		fspec->um.ip_usr_spec.proto = tp->ip4_proto_mask;
2507*4df55fdeSJanie Lu 		break;
2508*4df55fdeSJanie Lu 	default:
2509*4df55fdeSJanie Lu 		break;
2510*4df55fdeSJanie Lu 	}
2511*4df55fdeSJanie Lu 
2512*4df55fdeSJanie Lu 	if (tp->match_action.bits.ldw.disc == 1) {
2513*4df55fdeSJanie Lu 		fs->channel_cookie = NXGE_PKT_DISCARD;
2514*4df55fdeSJanie Lu 	} else {
2515*4df55fdeSJanie Lu 		fs->channel_cookie = tp->match_action.bits.ldw.offset;
2516*4df55fdeSJanie Lu 	}
2517*4df55fdeSJanie Lu }
2518*4df55fdeSJanie Lu 
2519*4df55fdeSJanie Lu void
2520*4df55fdeSJanie Lu nxge_del_tcam_entry(p_nxge_t nxgep, uint32_t location)
2521*4df55fdeSJanie Lu {
2522*4df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
2523*4df55fdeSJanie Lu 	uint16_t 	index;
2524*4df55fdeSJanie Lu 	tcam_flow_spec_t *tcam_ep;
2525*4df55fdeSJanie Lu 	tcam_entry_t	*tp;
2526*4df55fdeSJanie Lu 	tcam_class_t	class;
2527*4df55fdeSJanie Lu 
2528*4df55fdeSJanie Lu 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
2529*4df55fdeSJanie Lu 	index = nxge_tcam_get_index(nxgep, (uint16_t)location);
2530*4df55fdeSJanie Lu 	tcam_ep = &nxgep->classifier.tcam_entries[index];
2531*4df55fdeSJanie Lu 	if (tcam_ep->valid != 1) {
2532*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_tcam_entry: :"
2533*4df55fdeSJanie Lu 		    "Entry [%d] invalid for index [%d]", location, index));
2534*4df55fdeSJanie Lu 		goto fail;
2535*4df55fdeSJanie Lu 	}
2536*4df55fdeSJanie Lu 
2537*4df55fdeSJanie Lu 	/* Fill the flow spec entry */
2538*4df55fdeSJanie Lu 	tp = &tcam_ep->tce;
2539*4df55fdeSJanie Lu 	class = tp->ip4_class_key;
2540*4df55fdeSJanie Lu 	if (class >= TCAM_CLASS_IP_USER_4 && class <= TCAM_CLASS_IP_USER_7) {
2541*4df55fdeSJanie Lu 		int i;
2542*4df55fdeSJanie Lu 		nxge_usr_l3_cls_t *l3_ucls_p;
2543*4df55fdeSJanie Lu 		p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
2544*4df55fdeSJanie Lu 
2545*4df55fdeSJanie Lu 		for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
2546*4df55fdeSJanie Lu 			l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
2547*4df55fdeSJanie Lu 			if (l3_ucls_p->valid) {
2548*4df55fdeSJanie Lu 				if (l3_ucls_p->cls == class &&
2549*4df55fdeSJanie Lu 				    l3_ucls_p->tcam_ref_cnt) {
2550*4df55fdeSJanie Lu 					l3_ucls_p->tcam_ref_cnt--;
2551*4df55fdeSJanie Lu 					if (l3_ucls_p->tcam_ref_cnt > 0)
2552*4df55fdeSJanie Lu 						continue;
2553*4df55fdeSJanie Lu 					/* disable class */
2554*4df55fdeSJanie Lu 					rs = npi_fflp_cfg_ip_usr_cls_disable(
2555*4df55fdeSJanie Lu 					    nxgep->npi_reg_handle,
2556*4df55fdeSJanie Lu 					    (tcam_class_t)class);
2557*4df55fdeSJanie Lu 					if (rs != NPI_SUCCESS)
2558*4df55fdeSJanie Lu 						goto fail;
2559*4df55fdeSJanie Lu 					l3_ucls_p->cls = 0;
2560*4df55fdeSJanie Lu 					l3_ucls_p->pid = 0;
2561*4df55fdeSJanie Lu 					l3_ucls_p->valid = 0;
2562*4df55fdeSJanie Lu 					break;
2563*4df55fdeSJanie Lu 				}
2564*4df55fdeSJanie Lu 			}
2565*4df55fdeSJanie Lu 		}
2566*4df55fdeSJanie Lu 		if (i == NXGE_L3_PROG_CLS) {
2567*4df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2568*4df55fdeSJanie Lu 			    "nxge_del_tcam_entry: Usr class "
2569*4df55fdeSJanie Lu 			    "0x%llx not found", (unsigned long long) class));
2570*4df55fdeSJanie Lu 			goto fail;
2571*4df55fdeSJanie Lu 		}
2572*4df55fdeSJanie Lu 	}
2573*4df55fdeSJanie Lu 
2574*4df55fdeSJanie Lu 	rs = npi_fflp_tcam_entry_invalidate(nxgep->npi_reg_handle, index);
2575*4df55fdeSJanie Lu 	if (rs != NPI_SUCCESS) {
2576*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2577*4df55fdeSJanie Lu 		    "nxge_del_tcam_entry: TCAM invalidate failed "
2578*4df55fdeSJanie Lu 		    "at loc %d ", location));
2579*4df55fdeSJanie Lu 		goto fail;
2580*4df55fdeSJanie Lu 	}
2581*4df55fdeSJanie Lu 
2582*4df55fdeSJanie Lu 	nxgep->classifier.tcam_entries[index].valid = 0;
2583*4df55fdeSJanie Lu 	nxgep->classifier.tcam_entry_cnt--;
2584*4df55fdeSJanie Lu 
2585*4df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
2586*4df55fdeSJanie Lu 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_del_tcam_entry"));
2587*4df55fdeSJanie Lu 	return;
2588*4df55fdeSJanie Lu fail:
2589*4df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
2590*4df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2591*4df55fdeSJanie Lu 	    "<== nxge_del_tcam_entry FAILED"));
2592*4df55fdeSJanie Lu }
2593*4df55fdeSJanie Lu 
2594*4df55fdeSJanie Lu static uint8_t
2595*4df55fdeSJanie Lu nxge_iptun_pkt_type_to_pid(uint8_t pkt_type)
2596*4df55fdeSJanie Lu {
2597*4df55fdeSJanie Lu 	uint8_t pid = 0;
2598*4df55fdeSJanie Lu 
2599*4df55fdeSJanie Lu 	switch (pkt_type) {
2600*4df55fdeSJanie Lu 	case IPTUN_PKT_IPV4:
2601*4df55fdeSJanie Lu 		pid = 4;
2602*4df55fdeSJanie Lu 		break;
2603*4df55fdeSJanie Lu 	case IPTUN_PKT_IPV6:
2604*4df55fdeSJanie Lu 		pid = 41;
2605*4df55fdeSJanie Lu 		break;
2606*4df55fdeSJanie Lu 	case IPTUN_PKT_GRE:
2607*4df55fdeSJanie Lu 		pid = 47;
2608*4df55fdeSJanie Lu 		break;
2609*4df55fdeSJanie Lu 	case IPTUN_PKT_GTP:
2610*4df55fdeSJanie Lu 		pid = 17;
2611*4df55fdeSJanie Lu 		break;
2612*4df55fdeSJanie Lu 	default:
2613*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
2614*4df55fdeSJanie Lu 		    "nxge_iptun_pkt_type_to_pid: Unknown pkt type 0x%x",
2615*4df55fdeSJanie Lu 		    pkt_type));
2616*4df55fdeSJanie Lu 		break;
2617*4df55fdeSJanie Lu 	}
2618*4df55fdeSJanie Lu 
2619*4df55fdeSJanie Lu 	return (pid);
2620*4df55fdeSJanie Lu }
2621*4df55fdeSJanie Lu 
2622*4df55fdeSJanie Lu static npi_status_t
2623*4df55fdeSJanie Lu nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep, uint64_t class,
2624*4df55fdeSJanie Lu 		iptun_cfg_t *iptunp)
2625*4df55fdeSJanie Lu {
2626*4df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
2627*4df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
2628*4df55fdeSJanie Lu 
2629*4df55fdeSJanie Lu 	switch (iptunp->in_pkt_type) {
2630*4df55fdeSJanie Lu 	case IPTUN_PKT_IPV4:
2631*4df55fdeSJanie Lu 	case IPTUN_PKT_IPV6:
2632*4df55fdeSJanie Lu 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
2633*4df55fdeSJanie Lu 		    (tcam_class_t)class, 0, 0, 0, 0);
2634*4df55fdeSJanie Lu 		break;
2635*4df55fdeSJanie Lu 	case IPTUN_PKT_GRE:
2636*4df55fdeSJanie Lu 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
2637*4df55fdeSJanie Lu 		    (tcam_class_t)class, iptunp->l4b0_val,
2638*4df55fdeSJanie Lu 		    iptunp->l4b0_mask, 0, 0);
2639*4df55fdeSJanie Lu 		break;
2640*4df55fdeSJanie Lu 	case IPTUN_PKT_GTP:
2641*4df55fdeSJanie Lu 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
2642*4df55fdeSJanie Lu 		    (tcam_class_t)class, 0, 0, iptunp->l4b23_val,
2643*4df55fdeSJanie Lu 		    (iptunp->l4b23_sel & 0x01));
2644*4df55fdeSJanie Lu 		break;
2645*4df55fdeSJanie Lu 	default:
2646*4df55fdeSJanie Lu 		rs = NPI_FFLP_TCAM_CLASS_INVALID;
2647*4df55fdeSJanie Lu 		break;
2648*4df55fdeSJanie Lu 	}
2649*4df55fdeSJanie Lu 	return (rs);
2650*4df55fdeSJanie Lu }
2651*4df55fdeSJanie Lu 
2652*4df55fdeSJanie Lu void
2653*4df55fdeSJanie Lu nxge_add_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp,
2654*4df55fdeSJanie Lu 		uint8_t *cls_idp)
2655*4df55fdeSJanie Lu {
2656*4df55fdeSJanie Lu 	int i, add_cls;
2657*4df55fdeSJanie Lu 	uint8_t pid;
2658*4df55fdeSJanie Lu 	uint64_t class;
2659*4df55fdeSJanie Lu 	p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
2660*4df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
2661*4df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
2662*4df55fdeSJanie Lu 
2663*4df55fdeSJanie Lu 	pid = nxge_iptun_pkt_type_to_pid(iptunp->in_pkt_type);
2664*4df55fdeSJanie Lu 	if (pid == 0)
2665*4df55fdeSJanie Lu 		return;
2666*4df55fdeSJanie Lu 
2667*4df55fdeSJanie Lu 	add_cls = 0;
2668*4df55fdeSJanie Lu 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
2669*4df55fdeSJanie Lu 
2670*4df55fdeSJanie Lu 	/* Get an user programmable class ID */
2671*4df55fdeSJanie Lu 	for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
2672*4df55fdeSJanie Lu 		if (hw_p->tcam_l3_prog_cls[i].valid == 0) {
2673*4df55fdeSJanie Lu 			/* todo add new usr class reg */
2674*4df55fdeSJanie Lu 			switch (i) {
2675*4df55fdeSJanie Lu 			case 0:
2676*4df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_4;
2677*4df55fdeSJanie Lu 				break;
2678*4df55fdeSJanie Lu 			case 1:
2679*4df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_5;
2680*4df55fdeSJanie Lu 				break;
2681*4df55fdeSJanie Lu 			case 2:
2682*4df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_6;
2683*4df55fdeSJanie Lu 				break;
2684*4df55fdeSJanie Lu 			case 3:
2685*4df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_7;
2686*4df55fdeSJanie Lu 				break;
2687*4df55fdeSJanie Lu 			default:
2688*4df55fdeSJanie Lu 				break;
2689*4df55fdeSJanie Lu 			}
2690*4df55fdeSJanie Lu 			rs = npi_fflp_cfg_ip_usr_cls_set(handle,
2691*4df55fdeSJanie Lu 			    (tcam_class_t)class, 0, 0, pid, 0);
2692*4df55fdeSJanie Lu 			if (rs != NPI_SUCCESS)
2693*4df55fdeSJanie Lu 				goto fail;
2694*4df55fdeSJanie Lu 
2695*4df55fdeSJanie Lu 			rs = nxge_set_iptun_usr_cls_reg(nxgep, class, iptunp);
2696*4df55fdeSJanie Lu 
2697*4df55fdeSJanie Lu 			if (rs != NPI_SUCCESS)
2698*4df55fdeSJanie Lu 				goto fail;
2699*4df55fdeSJanie Lu 
2700*4df55fdeSJanie Lu 			rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
2701*4df55fdeSJanie Lu 			    (tcam_class_t)class);
2702*4df55fdeSJanie Lu 			if (rs != NPI_SUCCESS)
2703*4df55fdeSJanie Lu 				goto fail;
2704*4df55fdeSJanie Lu 
2705*4df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].cls = class;
2706*4df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].pid = pid;
2707*4df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
2708*4df55fdeSJanie Lu 			    iptunp->in_pkt_type;
2709*4df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].valid = 1;
2710*4df55fdeSJanie Lu 			*cls_idp = (uint8_t)class;
2711*4df55fdeSJanie Lu 			add_cls = 1;
2712*4df55fdeSJanie Lu 			break;
2713*4df55fdeSJanie Lu 		} else if (hw_p->tcam_l3_prog_cls[i].pid == pid) {
2714*4df55fdeSJanie Lu 			if (hw_p->tcam_l3_prog_cls[i].flow_pkt_type == 0) {
2715*4df55fdeSJanie Lu 				/* there is no flow key */
2716*4df55fdeSJanie Lu 				/* todo program the existing usr class reg */
2717*4df55fdeSJanie Lu 
2718*4df55fdeSJanie Lu 				rs = nxge_set_iptun_usr_cls_reg(nxgep, class,
2719*4df55fdeSJanie Lu 				    iptunp);
2720*4df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
2721*4df55fdeSJanie Lu 					goto fail;
2722*4df55fdeSJanie Lu 
2723*4df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
2724*4df55fdeSJanie Lu 				    (tcam_class_t)class);
2725*4df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
2726*4df55fdeSJanie Lu 					goto fail;
2727*4df55fdeSJanie Lu 
2728*4df55fdeSJanie Lu 				hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
2729*4df55fdeSJanie Lu 				    iptunp->in_pkt_type;
2730*4df55fdeSJanie Lu 				*cls_idp = (uint8_t)class;
2731*4df55fdeSJanie Lu 				add_cls = 1;
2732*4df55fdeSJanie Lu 			} else {
2733*4df55fdeSJanie Lu 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2734*4df55fdeSJanie Lu 				    "nxge_add_iptun_class: L3 usr "
2735*4df55fdeSJanie Lu 				    "programmable class with pid %d "
2736*4df55fdeSJanie Lu 				    "already exists", pid));
2737*4df55fdeSJanie Lu 			}
2738*4df55fdeSJanie Lu 			break;
2739*4df55fdeSJanie Lu 		}
2740*4df55fdeSJanie Lu 	}
2741*4df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2742*4df55fdeSJanie Lu 
2743*4df55fdeSJanie Lu 	if (add_cls != 1) {
2744*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2745*4df55fdeSJanie Lu 		    "nxge_add_iptun_class: Could not add IP tunneling class"));
2746*4df55fdeSJanie Lu 	}
2747*4df55fdeSJanie Lu 	return;
2748*4df55fdeSJanie Lu fail:
2749*4df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2750*4df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_iptun_class: FAILED"));
2751*4df55fdeSJanie Lu }
2752*4df55fdeSJanie Lu 
2753*4df55fdeSJanie Lu static boolean_t
2754*4df55fdeSJanie Lu nxge_is_iptun_cls_present(p_nxge_t nxgep, uint8_t cls_id, int *idx)
2755*4df55fdeSJanie Lu {
2756*4df55fdeSJanie Lu 	int i;
2757*4df55fdeSJanie Lu 	p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
2758*4df55fdeSJanie Lu 
2759*4df55fdeSJanie Lu 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
2760*4df55fdeSJanie Lu 	for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
2761*4df55fdeSJanie Lu 		if (hw_p->tcam_l3_prog_cls[i].valid &&
2762*4df55fdeSJanie Lu 		    hw_p->tcam_l3_prog_cls[i].flow_pkt_type != 0) {
2763*4df55fdeSJanie Lu 			if (hw_p->tcam_l3_prog_cls[i].cls == cls_id)
2764*4df55fdeSJanie Lu 				break;
2765*4df55fdeSJanie Lu 		}
2766*4df55fdeSJanie Lu 	}
2767*4df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2768*4df55fdeSJanie Lu 
2769*4df55fdeSJanie Lu 	if (i == NXGE_L3_PROG_CLS) {
2770*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2771*4df55fdeSJanie Lu 		    "nxge_is_iptun_cls_present: Invalid class %d", cls_id));
2772*4df55fdeSJanie Lu 		return (B_FALSE);
2773*4df55fdeSJanie Lu 	} else {
2774*4df55fdeSJanie Lu 		*idx = i;
2775*4df55fdeSJanie Lu 		return (B_TRUE);
2776*4df55fdeSJanie Lu 	}
2777*4df55fdeSJanie Lu }
2778*4df55fdeSJanie Lu 
2779*4df55fdeSJanie Lu void
2780*4df55fdeSJanie Lu nxge_cfg_iptun_hash(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
2781*4df55fdeSJanie Lu {
2782*4df55fdeSJanie Lu 	int idx;
2783*4df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
2784*4df55fdeSJanie Lu 	flow_key_cfg_t cfg;
2785*4df55fdeSJanie Lu 
2786*4df55fdeSJanie Lu 	/* check to see that this is a valid class ID */
2787*4df55fdeSJanie Lu 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &idx)) {
2788*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2789*4df55fdeSJanie Lu 		    "nxge_cfg_iptun_hash: nxge_is_iptun_cls_present "
2790*4df55fdeSJanie Lu 		    "failed for cls_id %d", cls_id));
2791*4df55fdeSJanie Lu 		return;
2792*4df55fdeSJanie Lu 	}
2793*4df55fdeSJanie Lu 
2794*4df55fdeSJanie Lu 	bzero((void *)&cfg, sizeof (flow_key_cfg_t));
2795*4df55fdeSJanie Lu 
2796*4df55fdeSJanie Lu 	/*
2797*4df55fdeSJanie Lu 	 * This ensures that all 4 bytes of the XOR value are loaded to the
2798*4df55fdeSJanie Lu 	 * hash key.
2799*4df55fdeSJanie Lu 	 */
2800*4df55fdeSJanie Lu 	cfg.use_dport = cfg.use_sport = cfg.ip_opts_exist = 1;
2801*4df55fdeSJanie Lu 
2802*4df55fdeSJanie Lu 	cfg.l4_xor_sel = (iptunp->l4xor_sel & FL_KEY_USR_L4XOR_MSK);
2803*4df55fdeSJanie Lu 	cfg.use_l4_md = 1;
2804*4df55fdeSJanie Lu 
2805*4df55fdeSJanie Lu 	if (iptunp->hash_flags & HASH_L3PROTO)
2806*4df55fdeSJanie Lu 		cfg.use_proto = 1;
2807*4df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_IPDA)
2808*4df55fdeSJanie Lu 		cfg.use_daddr = 1;
2809*4df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_IPSA)
2810*4df55fdeSJanie Lu 		cfg.use_saddr = 1;
2811*4df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_VLAN)
2812*4df55fdeSJanie Lu 		cfg.use_vlan = 1;
2813*4df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_L2DA)
2814*4df55fdeSJanie Lu 		cfg.use_l2da = 1;
2815*4df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_IFPORT)
2816*4df55fdeSJanie Lu 		cfg.use_portnum = 1;
2817*4df55fdeSJanie Lu 
2818*4df55fdeSJanie Lu 	(void) npi_fflp_cfg_ip_cls_flow_key_rfnl(handle, (tcam_class_t)cls_id,
2819*4df55fdeSJanie Lu 	    &cfg);
2820*4df55fdeSJanie Lu }
2821*4df55fdeSJanie Lu 
2822*4df55fdeSJanie Lu void
2823*4df55fdeSJanie Lu nxge_del_iptun_class(p_nxge_t nxgep, uint8_t cls_id)
2824*4df55fdeSJanie Lu {
2825*4df55fdeSJanie Lu 	int i;
2826*4df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
2827*4df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
2828*4df55fdeSJanie Lu 
2829*4df55fdeSJanie Lu 
2830*4df55fdeSJanie Lu 	/* check to see that this is a valid class ID */
2831*4df55fdeSJanie Lu 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) {
2832*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2833*4df55fdeSJanie Lu 		    "nxge_del_iptun_class: Invalid class ID 0x%x", cls_id));
2834*4df55fdeSJanie Lu 		return;
2835*4df55fdeSJanie Lu 	}
2836*4df55fdeSJanie Lu 
2837*4df55fdeSJanie Lu 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
2838*4df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_usr_cls_disable(handle, (tcam_class_t)cls_id);
2839*4df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
2840*4df55fdeSJanie Lu 		goto fail;
2841*4df55fdeSJanie Lu 	nxgep->nxge_hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 0;
2842*4df55fdeSJanie Lu 	if (nxgep->nxge_hw_p->tcam_l3_prog_cls[i].tcam_ref_cnt == 0)
2843*4df55fdeSJanie Lu 		nxgep->nxge_hw_p->tcam_l3_prog_cls[i].valid = 0;
2844*4df55fdeSJanie Lu 
2845*4df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
2846*4df55fdeSJanie Lu 	return;
2847*4df55fdeSJanie Lu fail:
2848*4df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
2849*4df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_iptun_class: FAILED"));
2850*4df55fdeSJanie Lu }
2851*4df55fdeSJanie Lu 
2852*4df55fdeSJanie Lu void
2853*4df55fdeSJanie Lu nxge_get_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
2854*4df55fdeSJanie Lu {
2855*4df55fdeSJanie Lu 	int i;
2856*4df55fdeSJanie Lu 	uint8_t pid;
2857*4df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
2858*4df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
2859*4df55fdeSJanie Lu 	flow_key_cfg_t cfg;
2860*4df55fdeSJanie Lu 
2861*4df55fdeSJanie Lu 
2862*4df55fdeSJanie Lu 	/* check to see that this is a valid class ID */
2863*4df55fdeSJanie Lu 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i))
2864*4df55fdeSJanie Lu 		return;
2865*4df55fdeSJanie Lu 
2866*4df55fdeSJanie Lu 	bzero((void *)iptunp, sizeof (iptun_cfg_t));
2867*4df55fdeSJanie Lu 
2868*4df55fdeSJanie Lu 	pid = nxgep->nxge_hw_p->tcam_l3_prog_cls[i].pid;
2869*4df55fdeSJanie Lu 
2870*4df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_usr_cls_get_iptun(handle, (tcam_class_t)cls_id,
2871*4df55fdeSJanie Lu 	    &iptunp->l4b0_val, &iptunp->l4b0_mask, &iptunp->l4b23_val,
2872*4df55fdeSJanie Lu 	    &iptunp->l4b23_sel);
2873*4df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
2874*4df55fdeSJanie Lu 		goto fail;
2875*4df55fdeSJanie Lu 
2876*4df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
2877*4df55fdeSJanie Lu 	    (tcam_class_t)cls_id, &cfg);
2878*4df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
2879*4df55fdeSJanie Lu 		goto fail;
2880*4df55fdeSJanie Lu 
2881*4df55fdeSJanie Lu 	iptunp->l4xor_sel = cfg.l4_xor_sel;
2882*4df55fdeSJanie Lu 	if (cfg.use_proto)
2883*4df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_L3PROTO;
2884*4df55fdeSJanie Lu 	else if (cfg.use_daddr)
2885*4df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_IPDA;
2886*4df55fdeSJanie Lu 	else if (cfg.use_saddr)
2887*4df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_IPSA;
2888*4df55fdeSJanie Lu 	else if (cfg.use_vlan)
2889*4df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_VLAN;
2890*4df55fdeSJanie Lu 	else if (cfg.use_l2da)
2891*4df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_L2DA;
2892*4df55fdeSJanie Lu 	else if (cfg.use_portnum)
2893*4df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_IFPORT;
2894*4df55fdeSJanie Lu 
2895*4df55fdeSJanie Lu 	switch (pid) {
2896*4df55fdeSJanie Lu 	case 4:
2897*4df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_IPV4;
2898*4df55fdeSJanie Lu 		break;
2899*4df55fdeSJanie Lu 	case 41:
2900*4df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_IPV6;
2901*4df55fdeSJanie Lu 		break;
2902*4df55fdeSJanie Lu 	case 47:
2903*4df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_GRE;
2904*4df55fdeSJanie Lu 		break;
2905*4df55fdeSJanie Lu 	case 17:
2906*4df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_GTP;
2907*4df55fdeSJanie Lu 		break;
2908*4df55fdeSJanie Lu 	default:
2909*4df55fdeSJanie Lu 		iptunp->in_pkt_type = 0;
2910*4df55fdeSJanie Lu 		break;
2911*4df55fdeSJanie Lu 	}
2912*4df55fdeSJanie Lu 
2913*4df55fdeSJanie Lu 	return;
2914*4df55fdeSJanie Lu fail:
2915*4df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_iptun_class: FAILED"));
2916*4df55fdeSJanie Lu }
2917*4df55fdeSJanie Lu 
2918*4df55fdeSJanie Lu void
2919*4df55fdeSJanie Lu nxge_set_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t sym)
2920*4df55fdeSJanie Lu {
2921*4df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
2922*4df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
2923*4df55fdeSJanie Lu 	boolean_t sym_en = (sym == 1) ? B_TRUE : B_FALSE;
2924*4df55fdeSJanie Lu 
2925*4df55fdeSJanie Lu 	rs = npi_fflp_cfg_sym_ip_cls_flow_key(handle, (tcam_class_t)cls_id,
2926*4df55fdeSJanie Lu 	    sym_en);
2927*4df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
2928*4df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2929*4df55fdeSJanie Lu 		    "nxge_set_ip_cls_sym: FAILED"));
2930*4df55fdeSJanie Lu }
2931*4df55fdeSJanie Lu 
2932*4df55fdeSJanie Lu void
2933*4df55fdeSJanie Lu nxge_get_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t *sym)
2934*4df55fdeSJanie Lu {
2935*4df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
2936*4df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
2937*4df55fdeSJanie Lu 	flow_key_cfg_t cfg;
2938*4df55fdeSJanie Lu 
2939*4df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
2940*4df55fdeSJanie Lu 	    (tcam_class_t)cls_id, &cfg);
2941*4df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
2942*4df55fdeSJanie Lu 		goto fail;
2943*4df55fdeSJanie Lu 
2944*4df55fdeSJanie Lu 	if (cfg.use_sym)
2945*4df55fdeSJanie Lu 		*sym = 1;
2946*4df55fdeSJanie Lu 	else
2947*4df55fdeSJanie Lu 		*sym = 0;
2948*4df55fdeSJanie Lu 	return;
2949*4df55fdeSJanie Lu fail:
2950*4df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_ip_cls_sym: FAILED"));
2951*4df55fdeSJanie Lu }
2952