xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_fflp.c (revision 86ef0a63)
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  */
210dc2366fSVenugopal Iyer 
2244961713Sgirish /*
230dc2366fSVenugopal Iyer  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
2444961713Sgirish  * Use is subject to license terms.
2544961713Sgirish  */
2644961713Sgirish 
2744961713Sgirish #include <npi_fflp.h>
2844961713Sgirish #include <npi_mac.h>
2944961713Sgirish #include <nxge_defs.h>
3044961713Sgirish #include <nxge_flow.h>
3144961713Sgirish #include <nxge_fflp.h>
3244961713Sgirish #include <nxge_impl.h>
3344961713Sgirish #include <nxge_fflp_hash.h>
3444961713Sgirish #include <nxge_common.h>
3544961713Sgirish 
3644961713Sgirish 
37a3c5bd6dSspeer /*
38a3c5bd6dSspeer  * Function prototypes
39a3c5bd6dSspeer  */
4044961713Sgirish static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t);
4144961713Sgirish static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t);
4244961713Sgirish static nxge_status_t nxge_fflp_tcam_init(p_nxge_t);
4344961713Sgirish static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t);
4444961713Sgirish static nxge_status_t nxge_fflp_fcram_init(p_nxge_t);
4544961713Sgirish static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *);
46a3c5bd6dSspeer static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
47a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
48a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
4944961713Sgirish static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *,
50a3c5bd6dSspeer 	tcam_entry_t *);
51a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *,
52a3c5bd6dSspeer 	tcam_entry_t *);
53a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *,
54a3c5bd6dSspeer 	tcam_entry_t *);
554df55fdeSJanie Lu static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t);
564df55fdeSJanie Lu static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t);
574df55fdeSJanie Lu static uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t);
584df55fdeSJanie Lu static uint32_t nxge_tcam_cls_to_flow(uint32_t);
594df55fdeSJanie Lu static uint8_t nxge_iptun_pkt_type_to_pid(uint8_t);
604df55fdeSJanie Lu static npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t,
614df55fdeSJanie Lu 					iptun_cfg_t *);
624df55fdeSJanie Lu static boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *);
6344961713Sgirish 
64a3c5bd6dSspeer /*
65a3c5bd6dSspeer  * functions used outside this file
66a3c5bd6dSspeer  */
6744961713Sgirish nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t);
6844961713Sgirish nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t);
6944961713Sgirish nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *);
7014ea4bb7Ssd static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t);
7144961713Sgirish nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *);
7244961713Sgirish nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *);
7344961713Sgirish nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *,
74a3c5bd6dSspeer 	uint32_t *, uint16_t *);
754df55fdeSJanie Lu int nxge_get_valid_tcam_cnt(p_nxge_t);
764df55fdeSJanie Lu void nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *);
774df55fdeSJanie Lu void nxge_get_tcam_entry(p_nxge_t, flow_resource_t *);
784df55fdeSJanie Lu void nxge_del_tcam_entry(p_nxge_t, uint32_t);
794df55fdeSJanie Lu void nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *);
804df55fdeSJanie Lu void nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t);
814df55fdeSJanie Lu void nxge_del_iptun_class(p_nxge_t, uint8_t);
824df55fdeSJanie Lu void nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t);
834df55fdeSJanie Lu void nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t);
844df55fdeSJanie Lu void nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *);
854df55fdeSJanie Lu 
8644961713Sgirish 
8744961713Sgirish nxge_status_t
nxge_tcam_dump_entry(p_nxge_t nxgep,uint32_t location)8844961713Sgirish nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location)
8944961713Sgirish {
9044961713Sgirish 	tcam_entry_t tcam_rdptr;
9144961713Sgirish 	uint64_t asc_ram = 0;
9244961713Sgirish 	npi_handle_t handle;
9344961713Sgirish 	npi_status_t status;
9444961713Sgirish 
9544961713Sgirish 	handle = nxgep->npi_reg_handle;
9644961713Sgirish 
9744961713Sgirish 	bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry));
9844961713Sgirish 	status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location,
9952ccf843Smisaki 	    (struct tcam_entry *)&tcam_rdptr);
10044961713Sgirish 	if (status & NPI_FAILURE) {
10144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
10252ccf843Smisaki 		    " nxge_tcam_dump_entry:"
10352ccf843Smisaki 		    "  tcam read failed at location %d ", location));
10444961713Sgirish 		return (NXGE_ERROR);
10544961713Sgirish 	}
10644961713Sgirish 	status = npi_fflp_tcam_asc_ram_entry_read(handle,
10752ccf843Smisaki 	    (tcam_location_t)location, &asc_ram);
10844961713Sgirish 
10944961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n"
11052ccf843Smisaki 	    " key:  %llx %llx %llx %llx \n"
11152ccf843Smisaki 	    " mask: %llx %llx %llx %llx \n"
11252ccf843Smisaki 	    " ASC RAM %llx \n", location,
11352ccf843Smisaki 	    tcam_rdptr.key0, tcam_rdptr.key1,
11452ccf843Smisaki 	    tcam_rdptr.key2, tcam_rdptr.key3,
11552ccf843Smisaki 	    tcam_rdptr.mask0, tcam_rdptr.mask1,
11652ccf843Smisaki 	    tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram));
11744961713Sgirish 	return (NXGE_OK);
11844961713Sgirish }
11944961713Sgirish 
12044961713Sgirish void
nxge_get_tcam(p_nxge_t nxgep,p_mblk_t mp)12144961713Sgirish nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp)
12244961713Sgirish {
12344961713Sgirish 	uint32_t tcam_loc;
12444961713Sgirish 	int *lptr;
12544961713Sgirish 	int location;
12644961713Sgirish 
12744961713Sgirish 	uint32_t start_location = 0;
12844961713Sgirish 	uint32_t stop_location = nxgep->classifier.tcam_size;
12944961713Sgirish 	lptr = (int *)mp->b_rptr;
13044961713Sgirish 	location = *lptr;
13144961713Sgirish 
13244961713Sgirish 	if ((location >= nxgep->classifier.tcam_size) || (location < -1)) {
13344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13452ccf843Smisaki 		    "nxge_tcam_dump: Invalid location %d \n", location));
13544961713Sgirish 		return;
13644961713Sgirish 	}
13744961713Sgirish 	if (location == -1) {
13844961713Sgirish 		start_location = 0;
13944961713Sgirish 		stop_location = nxgep->classifier.tcam_size;
14044961713Sgirish 	} else {
14144961713Sgirish 		start_location = location;
142a3c5bd6dSspeer 		stop_location = location + 1;
14344961713Sgirish 	}
14444961713Sgirish 	for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++)
14544961713Sgirish 		(void) nxge_tcam_dump_entry(nxgep, tcam_loc);
14644961713Sgirish }
14744961713Sgirish 
14844961713Sgirish /*
14944961713Sgirish  * nxge_fflp_vlan_table_invalidate_all
15044961713Sgirish  * invalidates the vlan RDC table entries.
15144961713Sgirish  * INPUT
15244961713Sgirish  * nxge    soft state data structure
15344961713Sgirish  * Return
15444961713Sgirish  *      NXGE_OK
15544961713Sgirish  *      NXGE_ERROR
15644961713Sgirish  *
15744961713Sgirish  */
158a3c5bd6dSspeer 
15944961713Sgirish static nxge_status_t
nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)16044961713Sgirish nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)
16144961713Sgirish {
16244961713Sgirish 	vlan_id_t vlan_id;
16344961713Sgirish 	npi_handle_t handle;
16444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
16544961713Sgirish 	vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
16644961713Sgirish 
16744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all "));
16844961713Sgirish 	handle = nxgep->npi_reg_handle;
16944961713Sgirish 	for (vlan_id = start; vlan_id < stop; vlan_id++) {
17044961713Sgirish 		rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id);
17144961713Sgirish 		if (rs != NPI_SUCCESS) {
17244961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17352ccf843Smisaki 			    "VLAN Table invalidate failed for vlan id %d ",
17452ccf843Smisaki 			    vlan_id));
17544961713Sgirish 			return (NXGE_ERROR | rs);
17644961713Sgirish 		}
17744961713Sgirish 	}
17844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all "));
17944961713Sgirish 	return (NXGE_OK);
18044961713Sgirish }
18144961713Sgirish 
18244961713Sgirish /*
18344961713Sgirish  * The following functions are used by other modules to init
18444961713Sgirish  * the fflp module.
18544961713Sgirish  * these functions are the basic API used to init
18644961713Sgirish  * the fflp modules (tcam, fcram etc ......)
18744961713Sgirish  *
18844961713Sgirish  * The TCAM search future would be disabled  by default.
18944961713Sgirish  */
19044961713Sgirish 
19144961713Sgirish static nxge_status_t
nxge_fflp_tcam_init(p_nxge_t nxgep)19244961713Sgirish nxge_fflp_tcam_init(p_nxge_t nxgep)
19344961713Sgirish {
19444961713Sgirish 	uint8_t access_ratio;
19544961713Sgirish 	tcam_class_t class;
19644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
19744961713Sgirish 	npi_handle_t handle;
19844961713Sgirish 
19944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init"));
20044961713Sgirish 	handle = nxgep->npi_reg_handle;
20144961713Sgirish 
20244961713Sgirish 	rs = npi_fflp_cfg_tcam_disable(handle);
20344961713Sgirish 	if (rs != NPI_SUCCESS) {
20444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n"));
20544961713Sgirish 		return (NXGE_ERROR | rs);
20644961713Sgirish 	}
20744961713Sgirish 
20844961713Sgirish 	access_ratio = nxgep->param_arr[param_tcam_access_ratio].value;
20944961713Sgirish 	rs = npi_fflp_cfg_tcam_access(handle, access_ratio);
21044961713Sgirish 	if (rs != NPI_SUCCESS) {
21144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21252ccf843Smisaki 		    "failed TCAM Access cfg\n"));
21344961713Sgirish 		return (NXGE_ERROR | rs);
21444961713Sgirish 	}
21544961713Sgirish 
216a3c5bd6dSspeer 	/* disable configurable classes */
217a3c5bd6dSspeer 	/* disable the configurable ethernet classes; */
21844961713Sgirish 	for (class = TCAM_CLASS_ETYPE_1;
21952ccf843Smisaki 	    class <= TCAM_CLASS_ETYPE_2; class++) {
22044961713Sgirish 		rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class);
22144961713Sgirish 		if (rs != NPI_SUCCESS) {
22244961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
22352ccf843Smisaki 			    "TCAM USR Ether Class config failed."));
22444961713Sgirish 			return (NXGE_ERROR | rs);
22544961713Sgirish 		}
22644961713Sgirish 	}
22744961713Sgirish 
228a3c5bd6dSspeer 	/* disable the configurable ip classes; */
22944961713Sgirish 	for (class = TCAM_CLASS_IP_USER_4;
23052ccf843Smisaki 	    class <= TCAM_CLASS_IP_USER_7; class++) {
23144961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
23244961713Sgirish 		if (rs != NPI_SUCCESS) {
23344961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
23452ccf843Smisaki 			    "TCAM USR IP Class cnfg failed."));
23544961713Sgirish 			return (NXGE_ERROR | rs);
23644961713Sgirish 		}
23744961713Sgirish 	}
23844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init"));
23944961713Sgirish 	return (NXGE_OK);
24044961713Sgirish }
24144961713Sgirish 
24244961713Sgirish /*
24344961713Sgirish  * nxge_fflp_tcam_invalidate_all
24444961713Sgirish  * invalidates all the tcam entries.
24544961713Sgirish  * INPUT
24644961713Sgirish  * nxge    soft state data structure
24744961713Sgirish  * Return
24844961713Sgirish  *      NXGE_OK
24944961713Sgirish  *      NXGE_ERROR
25044961713Sgirish  *
25144961713Sgirish  */
252a3c5bd6dSspeer 
253a3c5bd6dSspeer 
25444961713Sgirish static nxge_status_t
nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)25544961713Sgirish nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)
25644961713Sgirish {
25744961713Sgirish 	uint16_t location;
25844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
25944961713Sgirish 	npi_handle_t handle;
26044961713Sgirish 	uint16_t start = 0, stop = nxgep->classifier.tcam_size;
261a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
26244961713Sgirish 
26344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
26452ccf843Smisaki 	    "==> nxge_fflp_tcam_invalidate_all"));
26544961713Sgirish 	handle = nxgep->npi_reg_handle;
26644961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
26744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
26852ccf843Smisaki 		    " nxge_fflp_tcam_invalidate_all:"
26952ccf843Smisaki 		    " common hardware not set", nxgep->niu_type));
27044961713Sgirish 		return (NXGE_ERROR);
27144961713Sgirish 	}
27244961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
27344961713Sgirish 	for (location = start; location < stop; location++) {
27444961713Sgirish 		rs = npi_fflp_tcam_entry_invalidate(handle, location);
27544961713Sgirish 		if (rs != NPI_SUCCESS) {
27644961713Sgirish 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
27744961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27852ccf843Smisaki 			    "TCAM invalidate failed at loc %d ", location));
27944961713Sgirish 			return (NXGE_ERROR | rs);
28044961713Sgirish 		}
28144961713Sgirish 	}
28244961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
28344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
28452ccf843Smisaki 	    "<== nxge_fflp_tcam_invalidate_all"));
28544961713Sgirish 	return (NXGE_OK);
28644961713Sgirish }
28744961713Sgirish 
28844961713Sgirish /*
28944961713Sgirish  * nxge_fflp_fcram_entry_invalidate_all
29044961713Sgirish  * invalidates all the FCRAM entries.
29144961713Sgirish  * INPUT
29244961713Sgirish  * nxge    soft state data structure
29344961713Sgirish  * Return
29444961713Sgirish  *      NXGE_OK
29544961713Sgirish  *      NXGE_ERROR
29644961713Sgirish  *
29744961713Sgirish  */
298a3c5bd6dSspeer 
29944961713Sgirish static nxge_status_t
nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)30044961713Sgirish nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)
30144961713Sgirish {
302a3c5bd6dSspeer 	npi_handle_t handle;
303a3c5bd6dSspeer 	npi_status_t rs = NPI_SUCCESS;
304a3c5bd6dSspeer 	part_id_t pid = 0;
305a3c5bd6dSspeer 	uint8_t base_mask, base_reloc;
306a3c5bd6dSspeer 	fcram_entry_t fc;
307a3c5bd6dSspeer 	uint32_t location;
308a3c5bd6dSspeer 	uint32_t increment, last_location;
30944961713Sgirish 
310a3c5bd6dSspeer 	/*
311a3c5bd6dSspeer 	 * (1) configure and enable partition 0 with no relocation
312a3c5bd6dSspeer 	 * (2) Assume the FCRAM is used as IPv4 exact match entry cells
313a3c5bd6dSspeer 	 * (3) Invalidate these cells by clearing the valid bit in
314a3c5bd6dSspeer 	 * the subareas 0 and 4
315a3c5bd6dSspeer 	 * (4) disable the partition
316a3c5bd6dSspeer 	 *
317a3c5bd6dSspeer 	 */
31844961713Sgirish 
31944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all"));
32044961713Sgirish 
32144961713Sgirish 	base_mask = base_reloc = 0x0;
32244961713Sgirish 	handle = nxgep->npi_reg_handle;
323a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc);
32444961713Sgirish 
32544961713Sgirish 	if (rs != NPI_SUCCESS) {
326a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n"));
32744961713Sgirish 		return (NXGE_ERROR | rs);
32844961713Sgirish 	}
329a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_partition_disable(handle, pid);
33044961713Sgirish 
33144961713Sgirish 	if (rs != NPI_SUCCESS) {
33244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
33352ccf843Smisaki 		    "failed partition enable\n"));
33444961713Sgirish 		return (NXGE_ERROR | rs);
33544961713Sgirish 	}
336a3c5bd6dSspeer 	fc.dreg[0].value = 0;
337a3c5bd6dSspeer 	fc.hash_hdr_valid = 0;
338a3c5bd6dSspeer 	fc.hash_hdr_ext = 1;	/* specify as IPV4 exact match entry */
339a3c5bd6dSspeer 	increment = sizeof (hash_ipv4_t);
340a3c5bd6dSspeer 	last_location = FCRAM_SIZE * 0x40;
34144961713Sgirish 
342a3c5bd6dSspeer 	for (location = 0; location < last_location; location += increment) {
34344961713Sgirish 		rs = npi_fflp_fcram_subarea_write(handle, pid,
34452ccf843Smisaki 		    location, fc.value[0]);
34544961713Sgirish 		if (rs != NPI_SUCCESS) {
34644961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
34752ccf843Smisaki 			    "failed write at location %x ", location));
34844961713Sgirish 			return (NXGE_ERROR | rs);
34944961713Sgirish 		}
35044961713Sgirish 	}
35144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all"));
352a3c5bd6dSspeer 	return (NXGE_OK);
35344961713Sgirish }
35444961713Sgirish 
35544961713Sgirish static nxge_status_t
nxge_fflp_fcram_init(p_nxge_t nxgep)35644961713Sgirish nxge_fflp_fcram_init(p_nxge_t nxgep)
35744961713Sgirish {
35844961713Sgirish 	fflp_fcram_output_drive_t strength;
35944961713Sgirish 	fflp_fcram_qs_t qs;
36044961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
36144961713Sgirish 	uint8_t access_ratio;
362a3c5bd6dSspeer 	int partition;
36344961713Sgirish 	npi_handle_t handle;
364a3c5bd6dSspeer 	uint32_t min_time, max_time, sys_time;
36544961713Sgirish 
36644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init"));
36744961713Sgirish 
368a3c5bd6dSspeer 	/*
369a3c5bd6dSspeer 	 * Recommended values are needed.
370a3c5bd6dSspeer 	 */
37144961713Sgirish 	min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME;
37244961713Sgirish 	max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME;
37344961713Sgirish 	sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME;
374a3c5bd6dSspeer 
37544961713Sgirish 	handle = nxgep->npi_reg_handle;
37644961713Sgirish 	strength = FCRAM_OUTDR_NORMAL;
37744961713Sgirish 	qs = FCRAM_QS_MODE_QS;
37844961713Sgirish 	rs = npi_fflp_cfg_fcram_reset(handle, strength, qs);
37944961713Sgirish 	if (rs != NPI_SUCCESS) {
38044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. "));
38144961713Sgirish 		return (NXGE_ERROR | rs);
38244961713Sgirish 	}
38344961713Sgirish 
384a3c5bd6dSspeer 	access_ratio = nxgep->param_arr[param_fcram_access_ratio].value;
385a3c5bd6dSspeer 	rs = npi_fflp_cfg_fcram_access(handle, access_ratio);
386a3c5bd6dSspeer 	if (rs != NPI_SUCCESS) {
38744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio"
38852ccf843Smisaki 		    "configuration \n"));
38944961713Sgirish 		return (NXGE_ERROR | rs);
39044961713Sgirish 	}
39144961713Sgirish 	rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time,
39252ccf843Smisaki 	    max_time, sys_time);
39344961713Sgirish 	if (rs != NPI_SUCCESS) {
39444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
39552ccf843Smisaki 		    "failed FCRAM refresh cfg"));
39644961713Sgirish 		return (NXGE_ERROR);
39744961713Sgirish 	}
39844961713Sgirish 
39944961713Sgirish 	/* disable all the partitions until explicitly enabled */
40044961713Sgirish 	for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) {
401a3c5bd6dSspeer 		rs = npi_fflp_cfg_fcram_partition_disable(handle, partition);
40244961713Sgirish 		if (rs != NPI_SUCCESS) {
40344961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
40452ccf843Smisaki 			    "failed FCRAM partition"
40552ccf843Smisaki 			    " enable for partition %d ", partition));
40644961713Sgirish 			return (NXGE_ERROR | rs);
40744961713Sgirish 		}
40844961713Sgirish 	}
40944961713Sgirish 
41044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init"));
411a3c5bd6dSspeer 	return (NXGE_OK);
41244961713Sgirish }
41344961713Sgirish 
41444961713Sgirish nxge_status_t
nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep,uint8_t alt_mac)41544961713Sgirish nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac)
41644961713Sgirish {
41744961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
41844961713Sgirish 	hostinfo_t mac_rdc;
41944961713Sgirish 	npi_handle_t handle;
420a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
42144961713Sgirish 
422a3c5bd6dSspeer 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
42344961713Sgirish 	if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) {
424a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
42552ccf843Smisaki 		    " nxge_logical_mac_assign_rdc_table"
42652ccf843Smisaki 		    " unconfigured alt MAC addr %d ", alt_mac));
42744961713Sgirish 		return (NXGE_ERROR);
42844961713Sgirish 	}
42944961713Sgirish 	handle = nxgep->npi_reg_handle;
43044961713Sgirish 	mac_rdc.value = 0;
43144961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num =
43252ccf843Smisaki 	    p_class_cfgp->mac_host_info[alt_mac].rdctbl;
43344961713Sgirish 	mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr;
43444961713Sgirish 
43544961713Sgirish 	rs = npi_mac_hostinfo_entry(handle, OP_SET,
43652ccf843Smisaki 	    nxgep->function_num, alt_mac, &mac_rdc);
43744961713Sgirish 
43844961713Sgirish 	if (rs != NPI_SUCCESS) {
43944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44052ccf843Smisaki 		    "failed Assign RDC table"));
44144961713Sgirish 		return (NXGE_ERROR | rs);
44244961713Sgirish 	}
44344961713Sgirish 	return (NXGE_OK);
44444961713Sgirish }
44544961713Sgirish 
44644961713Sgirish nxge_status_t
nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)44744961713Sgirish nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)
44844961713Sgirish {
44944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
45044961713Sgirish 	hostinfo_t mac_rdc;
45144961713Sgirish 	npi_handle_t handle;
4520dc2366fSVenugopal Iyer 	int i;
45344961713Sgirish 
45444961713Sgirish 	handle = nxgep->npi_reg_handle;
45544961713Sgirish 	mac_rdc.value = 0;
45644961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp;
45744961713Sgirish 	mac_rdc.bits.w0.mac_pref = 1;
45844961713Sgirish 	switch (nxgep->function_num) {
459a3c5bd6dSspeer 	case 0:
460a3c5bd6dSspeer 	case 1:
4610dc2366fSVenugopal Iyer 		/*
4620dc2366fSVenugopal Iyer 		 * Tests indicate that it is OK not to re-initialize the
4630dc2366fSVenugopal Iyer 		 * hostinfo registers for the XMAC's alternate MAC
4640dc2366fSVenugopal Iyer 		 * addresses. But that is necessary for BMAC (case 2
4650dc2366fSVenugopal Iyer 		 * and case 3 below)
4660dc2366fSVenugopal Iyer 		 */
467a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
46852ccf843Smisaki 		    nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
469a3c5bd6dSspeer 		break;
470a3c5bd6dSspeer 	case 2:
471a3c5bd6dSspeer 	case 3:
472a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
47352ccf843Smisaki 		    nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
4740dc2366fSVenugopal Iyer 		for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
4750dc2366fSVenugopal Iyer 			rs |= npi_mac_hostinfo_entry(handle, OP_SET,
4760dc2366fSVenugopal Iyer 			    nxgep->function_num, i, &mac_rdc);
477a3c5bd6dSspeer 		break;
478a3c5bd6dSspeer 	default:
479a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
48052ccf843Smisaki 		    "failed Assign RDC table (invalid function #)"));
481a3c5bd6dSspeer 		return (NXGE_ERROR);
48244961713Sgirish 	}
48344961713Sgirish 
48444961713Sgirish 	if (rs != NPI_SUCCESS) {
48544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
48652ccf843Smisaki 		    "failed Assign RDC table"));
48744961713Sgirish 		return (NXGE_ERROR | rs);
48844961713Sgirish 	}
48944961713Sgirish 	return (NXGE_OK);
49044961713Sgirish }
49144961713Sgirish 
49258324dfcSspeer /*
49358324dfcSspeer  * Initialize hostinfo registers for alternate MAC addresses and
49458324dfcSspeer  * multicast MAC address.
49558324dfcSspeer  */
49644961713Sgirish nxge_status_t
nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)49758324dfcSspeer nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)
49844961713Sgirish {
49944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
50044961713Sgirish 	hostinfo_t mac_rdc;
50144961713Sgirish 	npi_handle_t handle;
50244961713Sgirish 
50344961713Sgirish 	handle = nxgep->npi_reg_handle;
50444961713Sgirish 	mac_rdc.value = 0;
50544961713Sgirish 	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp;
50644961713Sgirish 	mac_rdc.bits.w0.mac_pref = 1;
50744961713Sgirish 	switch (nxgep->function_num) {
508a3c5bd6dSspeer 	case 0:
509a3c5bd6dSspeer 	case 1:
510a3c5bd6dSspeer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
5110dc2366fSVenugopal Iyer 		    nxgep->function_num, XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
512a3c5bd6dSspeer 		break;
513a3c5bd6dSspeer 	case 2:
514a3c5bd6dSspeer 	case 3:
5150dc2366fSVenugopal Iyer 		rs = npi_mac_hostinfo_entry(handle, OP_SET,
5160dc2366fSVenugopal Iyer 		    nxgep->function_num, BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
517a3c5bd6dSspeer 		break;
518a3c5bd6dSspeer 	default:
519a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52052ccf843Smisaki 		    "failed Assign RDC table (invalid function #)"));
521a3c5bd6dSspeer 		return (NXGE_ERROR);
52244961713Sgirish 	}
52344961713Sgirish 
52444961713Sgirish 	if (rs != NPI_SUCCESS) {
52544961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52652ccf843Smisaki 		    "failed Assign RDC table"));
52744961713Sgirish 		return (NXGE_ERROR | rs);
52844961713Sgirish 	}
52944961713Sgirish 	return (NXGE_OK);
53044961713Sgirish }
53144961713Sgirish 
53244961713Sgirish nxge_status_t
nxge_fflp_init_hostinfo(p_nxge_t nxgep)53344961713Sgirish nxge_fflp_init_hostinfo(p_nxge_t nxgep)
53444961713Sgirish {
53544961713Sgirish 	nxge_status_t status = NXGE_OK;
536a3c5bd6dSspeer 
53758324dfcSspeer 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
53858324dfcSspeer 	status |= nxge_main_mac_assign_rdc_table(nxgep);
53944961713Sgirish 	return (status);
54044961713Sgirish }
54144961713Sgirish 
54244961713Sgirish nxge_status_t
nxge_fflp_hw_reset(p_nxge_t nxgep)54344961713Sgirish nxge_fflp_hw_reset(p_nxge_t nxgep)
54444961713Sgirish {
54544961713Sgirish 	npi_handle_t handle;
54644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
54744961713Sgirish 	nxge_status_t status = NXGE_OK;
54844961713Sgirish 
54944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
55044961713Sgirish 
5512e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
55244961713Sgirish 		status = nxge_fflp_fcram_init(nxgep);
553a3c5bd6dSspeer 		if (status != NXGE_OK) {
55444961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55552ccf843Smisaki 			    " failed FCRAM init. "));
55644961713Sgirish 			return (status);
55744961713Sgirish 		}
55844961713Sgirish 	}
55944961713Sgirish 
56044961713Sgirish 	status = nxge_fflp_tcam_init(nxgep);
56144961713Sgirish 	if (status != NXGE_OK) {
562a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
56352ccf843Smisaki 		    "failed TCAM init."));
564a3c5bd6dSspeer 		return (status);
56544961713Sgirish 	}
56644961713Sgirish 
56744961713Sgirish 	handle = nxgep->npi_reg_handle;
56844961713Sgirish 	rs = npi_fflp_cfg_llcsnap_enable(handle);
56944961713Sgirish 	if (rs != NPI_SUCCESS) {
570a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
57152ccf843Smisaki 		    "failed LLCSNAP enable. "));
572a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
57344961713Sgirish 	}
57444961713Sgirish 
57544961713Sgirish 	rs = npi_fflp_cfg_cam_errorcheck_disable(handle);
57644961713Sgirish 	if (rs != NPI_SUCCESS) {
57744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
57852ccf843Smisaki 		    "failed CAM Error Check enable. "));
57944961713Sgirish 		return (NXGE_ERROR | rs);
58044961713Sgirish 	}
58144961713Sgirish 
582a3c5bd6dSspeer 	/* init the hash generators */
58344961713Sgirish 	rs = npi_fflp_cfg_hash_h1poly(handle, 0);
58444961713Sgirish 	if (rs != NPI_SUCCESS) {
585a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
58652ccf843Smisaki 		    "failed H1 Poly Init. "));
587a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
58844961713Sgirish 	}
58944961713Sgirish 
59044961713Sgirish 	rs = npi_fflp_cfg_hash_h2poly(handle, 0);
59144961713Sgirish 	if (rs != NPI_SUCCESS) {
592a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
59352ccf843Smisaki 		    "failed H2 Poly Init. "));
594a3c5bd6dSspeer 		return (NXGE_ERROR | rs);
59544961713Sgirish 	}
59644961713Sgirish 
597a3c5bd6dSspeer 	/* invalidate TCAM entries */
59844961713Sgirish 	status = nxge_fflp_tcam_invalidate_all(nxgep);
59944961713Sgirish 	if (status != NXGE_OK) {
60044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
60152ccf843Smisaki 		    "failed TCAM Entry Invalidate. "));
60244961713Sgirish 		return (status);
60344961713Sgirish 	}
60444961713Sgirish 
605a3c5bd6dSspeer 	/* invalidate FCRAM entries */
6062e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
60744961713Sgirish 		status = nxge_fflp_fcram_invalidate_all(nxgep);
60844961713Sgirish 		if (status != NXGE_OK) {
60944961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
61052ccf843Smisaki 			    "failed FCRAM Entry Invalidate."));
61144961713Sgirish 			return (status);
61244961713Sgirish 		}
61344961713Sgirish 	}
61444961713Sgirish 
615a3c5bd6dSspeer 	/* invalidate VLAN RDC tables */
61644961713Sgirish 	status = nxge_fflp_vlan_tbl_clear_all(nxgep);
61744961713Sgirish 	if (status != NXGE_OK) {
61844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
61952ccf843Smisaki 		    "failed VLAN Table Invalidate. "));
62044961713Sgirish 		return (status);
62144961713Sgirish 	}
62244961713Sgirish 	nxgep->classifier.state |= NXGE_FFLP_HW_RESET;
62344961713Sgirish 
62444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset"));
62544961713Sgirish 	return (NXGE_OK);
62644961713Sgirish }
62744961713Sgirish 
62844961713Sgirish nxge_status_t
nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep,tcam_class_t l3_class,uint32_t class_config)62944961713Sgirish nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class,
630*86ef0a63SRichard Lowe     uint32_t class_config)
63144961713Sgirish {
63244961713Sgirish 	flow_key_cfg_t fcfg;
63344961713Sgirish 	npi_handle_t handle;
63444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
63544961713Sgirish 
63644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key"));
63744961713Sgirish 	handle = nxgep->npi_reg_handle;
63844961713Sgirish 	bzero(&fcfg, sizeof (flow_key_cfg_t));
63944961713Sgirish 
640a3c5bd6dSspeer 	if (class_config & NXGE_CLASS_FLOW_USE_PROTO)
64144961713Sgirish 		fcfg.use_proto = 1;
64244961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT)
64344961713Sgirish 		fcfg.use_dport = 1;
64444961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT)
64544961713Sgirish 		fcfg.use_sport = 1;
64644961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_IPDST)
64744961713Sgirish 		fcfg.use_daddr = 1;
64844961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_IPSRC)
64944961713Sgirish 		fcfg.use_saddr = 1;
65044961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_VLAN)
65144961713Sgirish 		fcfg.use_vlan = 1;
65244961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_L2DA)
65344961713Sgirish 		fcfg.use_l2da = 1;
65444961713Sgirish 	if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM)
65544961713Sgirish 		fcfg.use_portnum = 1;
65644961713Sgirish 	fcfg.ip_opts_exist = 0;
65744961713Sgirish 
65844961713Sgirish 	rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg);
65944961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
66044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
66152ccf843Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
66244961713Sgirish 		return (NXGE_ERROR | rs);
66344961713Sgirish 	}
66444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key"));
66544961713Sgirish 	return (NXGE_OK);
66644961713Sgirish }
66744961713Sgirish 
66844961713Sgirish nxge_status_t
nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep,tcam_class_t l3_class,uint32_t * class_config)66944961713Sgirish nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class,
670*86ef0a63SRichard Lowe     uint32_t *class_config)
67144961713Sgirish {
67244961713Sgirish 	flow_key_cfg_t fcfg;
67344961713Sgirish 	npi_handle_t handle;
67444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
67544961713Sgirish 	uint32_t ccfg = 0;
676a3c5bd6dSspeer 
67744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get"));
67844961713Sgirish 	handle = nxgep->npi_reg_handle;
67944961713Sgirish 	bzero(&fcfg, sizeof (flow_key_cfg_t));
68044961713Sgirish 
68144961713Sgirish 	rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg);
68244961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
68344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
68452ccf843Smisaki 		    " opt %x for class %d failed ", class_config, l3_class));
68544961713Sgirish 		return (NXGE_ERROR | rs);
68644961713Sgirish 	}
68744961713Sgirish 
68844961713Sgirish 	if (fcfg.use_proto)
68944961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_PROTO;
69044961713Sgirish 	if (fcfg.use_dport)
69144961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT;
69244961713Sgirish 	if (fcfg.use_sport)
69344961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT;
69444961713Sgirish 	if (fcfg.use_daddr)
69544961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_IPDST;
69644961713Sgirish 	if (fcfg.use_saddr)
69744961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_IPSRC;
69844961713Sgirish 	if (fcfg.use_vlan)
69944961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_VLAN;
70044961713Sgirish 	if (fcfg.use_l2da)
70144961713Sgirish 		ccfg |= NXGE_CLASS_FLOW_USE_L2DA;
70244961713Sgirish 	if (fcfg.use_portnum)
703a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM;
70444961713Sgirish 
70544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
70652ccf843Smisaki 	    " nxge_cfg_ip_cls_flow_key_get %x", ccfg));
70744961713Sgirish 	*class_config = ccfg;
70844961713Sgirish 
70944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
71052ccf843Smisaki 	    " <== nxge_cfg_ip_cls_flow_key_get"));
71144961713Sgirish 	return (NXGE_OK);
71244961713Sgirish }
71344961713Sgirish 
71444961713Sgirish static nxge_status_t
nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep,tcam_class_t class,uint32_t * class_config)71544961713Sgirish nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class,
716*86ef0a63SRichard Lowe     uint32_t *class_config)
71744961713Sgirish {
71844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
71944961713Sgirish 	tcam_key_cfg_t cfg;
72044961713Sgirish 	npi_handle_t handle;
72144961713Sgirish 	uint32_t ccfg = 0;
72244961713Sgirish 
72344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
72444961713Sgirish 
72544961713Sgirish 	bzero(&cfg, sizeof (tcam_key_cfg_t));
72644961713Sgirish 	handle = nxgep->npi_reg_handle;
72744961713Sgirish 
72844961713Sgirish 	rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg);
72944961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
73044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
73152ccf843Smisaki 		    " opt %x for class %d failed ", class_config, class));
73244961713Sgirish 		return (NXGE_ERROR | rs);
73344961713Sgirish 	}
73444961713Sgirish 	if (cfg.discard)
735a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_DISCARD;
73644961713Sgirish 	if (cfg.lookup_enable)
73744961713Sgirish 		ccfg |= NXGE_CLASS_TCAM_LOOKUP;
73844961713Sgirish 	if (cfg.use_ip_daddr)
739a3c5bd6dSspeer 		ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR;
74044961713Sgirish 	*class_config = ccfg;
74144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
74252ccf843Smisaki 	    " ==> nxge_cfg_tcam_ip_class %x", ccfg));
74344961713Sgirish 	return (NXGE_OK);
74444961713Sgirish }
74544961713Sgirish 
74644961713Sgirish static nxge_status_t
nxge_cfg_tcam_ip_class(p_nxge_t nxgep,tcam_class_t class,uint32_t class_config)74744961713Sgirish nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class,
748*86ef0a63SRichard Lowe     uint32_t class_config)
74944961713Sgirish {
75044961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
75144961713Sgirish 	tcam_key_cfg_t cfg;
75244961713Sgirish 	npi_handle_t handle;
753a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
75444961713Sgirish 
75544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
756a3c5bd6dSspeer 
75744961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
75844961713Sgirish 	p_class_cfgp->class_cfg[class] = class_config;
75944961713Sgirish 
76044961713Sgirish 	bzero(&cfg, sizeof (tcam_key_cfg_t));
76144961713Sgirish 	handle = nxgep->npi_reg_handle;
76244961713Sgirish 	cfg.discard = 0;
76344961713Sgirish 	cfg.lookup_enable = 0;
76444961713Sgirish 	cfg.use_ip_daddr = 0;
76544961713Sgirish 	if (class_config & NXGE_CLASS_DISCARD)
76644961713Sgirish 		cfg.discard = 1;
76744961713Sgirish 	if (class_config & NXGE_CLASS_TCAM_LOOKUP)
76844961713Sgirish 		cfg.lookup_enable = 1;
769a3c5bd6dSspeer 	if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR)
77044961713Sgirish 		cfg.use_ip_daddr = 1;
77144961713Sgirish 
77244961713Sgirish 	rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg);
77344961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
77444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
77552ccf843Smisaki 		    " opt %x for class %d failed ", class_config, class));
77644961713Sgirish 		return (NXGE_ERROR | rs);
77744961713Sgirish 	}
77844961713Sgirish 	return (NXGE_OK);
77944961713Sgirish }
78044961713Sgirish 
78144961713Sgirish nxge_status_t
nxge_fflp_set_hash1(p_nxge_t nxgep,uint32_t h1)78244961713Sgirish nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1)
78344961713Sgirish {
78444961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
78544961713Sgirish 	npi_handle_t handle;
786a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
78744961713Sgirish 
78844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1"));
78944961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
79044961713Sgirish 	p_class_cfgp->init_h1 = h1;
79144961713Sgirish 	handle = nxgep->npi_reg_handle;
79244961713Sgirish 	rs = npi_fflp_cfg_hash_h1poly(handle, h1);
79344961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
794a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
79552ccf843Smisaki 		    " nxge_fflp_init_h1 %x failed ", h1));
79644961713Sgirish 		return (NXGE_ERROR | rs);
79744961713Sgirish 	}
79844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1"));
79944961713Sgirish 	return (NXGE_OK);
80044961713Sgirish }
80144961713Sgirish 
80244961713Sgirish nxge_status_t
nxge_fflp_set_hash2(p_nxge_t nxgep,uint16_t h2)80344961713Sgirish nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2)
80444961713Sgirish {
80544961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
80644961713Sgirish 	npi_handle_t handle;
807a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
80844961713Sgirish 
80944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2"));
81044961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
81144961713Sgirish 	p_class_cfgp->init_h2 = h2;
81244961713Sgirish 
81344961713Sgirish 	handle = nxgep->npi_reg_handle;
81444961713Sgirish 	rs = npi_fflp_cfg_hash_h2poly(handle, h2);
81544961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
816a3c5bd6dSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
81752ccf843Smisaki 		    " nxge_fflp_init_h2 %x failed ", h2));
81844961713Sgirish 		return (NXGE_ERROR | rs);
81944961713Sgirish 	}
82044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2"));
82144961713Sgirish 	return (NXGE_OK);
82244961713Sgirish }
82344961713Sgirish 
82444961713Sgirish nxge_status_t
nxge_classify_init_sw(p_nxge_t nxgep)82544961713Sgirish nxge_classify_init_sw(p_nxge_t nxgep)
82644961713Sgirish {
82744961713Sgirish 	nxge_classify_t *classify_ptr;
82844961713Sgirish 
82944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw"));
83044961713Sgirish 	classify_ptr = &nxgep->classifier;
83144961713Sgirish 
83244961713Sgirish 	if (classify_ptr->state & NXGE_FFLP_SW_INIT) {
83344961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
83452ccf843Smisaki 		    "nxge_classify_init_sw already init"));
83544961713Sgirish 		return (NXGE_OK);
83644961713Sgirish 	}
837a3c5bd6dSspeer 
8384df55fdeSJanie Lu 	classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports;
8394df55fdeSJanie Lu 	classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam;
8404df55fdeSJanie Lu 	classify_ptr->tcam_top = nxgep->function_num;
84144961713Sgirish 
842a3c5bd6dSspeer 	/* Init defaults */
843a3c5bd6dSspeer 	/*
844a3c5bd6dSspeer 	 * add hacks required for HW shortcomings for example, code to handle
845a3c5bd6dSspeer 	 * fragmented packets
846a3c5bd6dSspeer 	 */
84744961713Sgirish 	nxge_init_h1_table();
84844961713Sgirish 	nxge_crc_ccitt_init();
84944961713Sgirish 	nxgep->classifier.tcam_location = nxgep->function_num;
85044961713Sgirish 	nxgep->classifier.fragment_bug = 1;
85144961713Sgirish 	classify_ptr->state |= NXGE_FFLP_SW_INIT;
85244961713Sgirish 
85344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw"));
85444961713Sgirish 	return (NXGE_OK);
85544961713Sgirish }
85644961713Sgirish 
85744961713Sgirish nxge_status_t
nxge_classify_exit_sw(p_nxge_t nxgep)85844961713Sgirish nxge_classify_exit_sw(p_nxge_t nxgep)
85944961713Sgirish {
86044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw"));
861b37cc459SToomas Soome 	nxgep->classifier.state = 0;
86244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw"));
86344961713Sgirish 	return (NXGE_OK);
86444961713Sgirish }
86544961713Sgirish 
86644961713Sgirish /*
86744961713Sgirish  * Figures out the RDC Group for the entry
86844961713Sgirish  *
86944961713Sgirish  * The current implementation is just a place holder and it
87044961713Sgirish  * returns 0.
87144961713Sgirish  * The real location determining algorithm would consider
87244961713Sgirish  * the partition etc ... before deciding w
87344961713Sgirish  *
87444961713Sgirish  */
875a3c5bd6dSspeer 
8760a8e077aSspeer /* ARGSUSED */
87744961713Sgirish static uint8_t
nxge_get_rdc_group(p_nxge_t nxgep,uint8_t class,uint64_t cookie)8784df55fdeSJanie Lu nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
87944961713Sgirish {
88044961713Sgirish 	int use_port_rdc_grp = 0;
88144961713Sgirish 	uint8_t rdc_grp = 0;
882a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
883a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
884a3c5bd6dSspeer 	p_nxge_rdc_grp_t rdc_grp_p;
885a3c5bd6dSspeer 
88644961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
88744961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
88844961713Sgirish 	rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp];
889678453a8Sspeer 	rdc_grp = p_cfgp->def_mac_rxdma_grpid;
890a3c5bd6dSspeer 
89144961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
89252ccf843Smisaki 	    "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
89352ccf843Smisaki 	    cookie, rdc_grp, rdc_grp_p));
89444961713Sgirish 	return (rdc_grp);
89544961713Sgirish }
89644961713Sgirish 
89744961713Sgirish /* ARGSUSED */
89844961713Sgirish static uint8_t
nxge_get_rdc_offset(p_nxge_t nxgep,uint8_t class,uint64_t cookie)8994df55fdeSJanie Lu nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
90044961713Sgirish {
90144961713Sgirish 	return ((uint8_t)cookie);
90244961713Sgirish }
90344961713Sgirish 
9040a8e077aSspeer /* ARGSUSED */
90544961713Sgirish static void
nxge_fill_tcam_entry_udp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)90644961713Sgirish nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec,
907*86ef0a63SRichard Lowe     tcam_entry_t *tcam_ptr)
90844961713Sgirish {
909e3d11eeeSToomas Soome #define	fspec_key (flow_spec->uh.udpip4spec)
910e3d11eeeSToomas Soome #define	fspec_mask (flow_spec->um.udpip4spec)
911e3d11eeeSToomas Soome 
912e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key.ip4dst);
913e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask.ip4dst);
914e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key.ip4src);
915e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask.ip4src);
91644961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
917e3d11eeeSToomas Soome 	    fspec_key.pdst, fspec_key.psrc);
91844961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
919e3d11eeeSToomas Soome 	    fspec_mask.pdst, fspec_mask.psrc);
92044961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
92152ccf843Smisaki 	    tcam_ptr->ip4_class_mask,
92252ccf843Smisaki 	    TCAM_CLASS_UDP_IPV4);
92344961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
92452ccf843Smisaki 	    tcam_ptr->ip4_proto_mask,
92552ccf843Smisaki 	    IPPROTO_UDP);
926e3d11eeeSToomas Soome 	tcam_ptr->ip4_tos_key = fspec_key.tos;
927e3d11eeeSToomas Soome 	tcam_ptr->ip4_tos_mask = fspec_mask.tos;
928e3d11eeeSToomas Soome #undef fspec_key
929e3d11eeeSToomas Soome #undef fspec_mask
93044961713Sgirish }
93144961713Sgirish 
93244961713Sgirish static void
nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)93344961713Sgirish nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
934*86ef0a63SRichard Lowe     tcam_entry_t *tcam_ptr)
93544961713Sgirish {
936a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
937e3d11eeeSToomas Soome #define	fspec_key (flow_spec->uh.udpip6spec)
938e3d11eeeSToomas Soome #define	fspec_mask (flow_spec->um.udpip6spec)
93944961713Sgirish 
94044961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
94144961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
94252ccf843Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
943e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key.ip6src);
944e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask.ip6src);
94544961713Sgirish 	} else {
946e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key.ip6dst);
947e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask.ip6dst);
94844961713Sgirish 	}
94944961713Sgirish 
95044961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
95152ccf843Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6);
95244961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
95352ccf843Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP);
95444961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
955e3d11eeeSToomas Soome 	    fspec_key.pdst, fspec_key.psrc);
95644961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
957e3d11eeeSToomas Soome 	    fspec_mask.pdst, fspec_mask.psrc);
958e3d11eeeSToomas Soome 	tcam_ptr->ip6_tos_key = fspec_key.tos;
959e3d11eeeSToomas Soome 	tcam_ptr->ip6_tos_mask = fspec_mask.tos;
960e3d11eeeSToomas Soome #undef fspec_key
961e3d11eeeSToomas Soome #undef fspec_mask
96244961713Sgirish }
96344961713Sgirish 
9640a8e077aSspeer /* ARGSUSED */
96544961713Sgirish static void
nxge_fill_tcam_entry_tcp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)96644961713Sgirish nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec,
967*86ef0a63SRichard Lowe     tcam_entry_t *tcam_ptr)
96844961713Sgirish {
969e3d11eeeSToomas Soome #define	fspec_key (flow_spec->uh.tcpip4spec)
970e3d11eeeSToomas Soome #define	fspec_mask (flow_spec->um.tcpip4spec)
97144961713Sgirish 
972e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key.ip4dst);
973e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask.ip4dst);
974e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key.ip4src);
975e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask.ip4src);
97644961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
977e3d11eeeSToomas Soome 	    fspec_key.pdst, fspec_key.psrc);
97844961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
979e3d11eeeSToomas Soome 	    fspec_mask.pdst, fspec_mask.psrc);
98044961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
98152ccf843Smisaki 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4);
98244961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
98352ccf843Smisaki 	    tcam_ptr->ip4_proto_mask, IPPROTO_TCP);
984e3d11eeeSToomas Soome 	tcam_ptr->ip4_tos_key = fspec_key.tos;
985e3d11eeeSToomas Soome 	tcam_ptr->ip4_tos_mask = fspec_mask.tos;
986e3d11eeeSToomas Soome #undef fspec_key
987e3d11eeeSToomas Soome #undef fspec_mask
98844961713Sgirish }
98944961713Sgirish 
9900a8e077aSspeer /* ARGSUSED */
99144961713Sgirish static void
nxge_fill_tcam_entry_sctp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)99244961713Sgirish nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec,
993*86ef0a63SRichard Lowe     tcam_entry_t *tcam_ptr)
99444961713Sgirish {
995e3d11eeeSToomas Soome #define	fspec_key (flow_spec->uh.tcpip4spec)
996e3d11eeeSToomas Soome #define	fspec_mask (flow_spec->um.tcpip4spec)
99744961713Sgirish 
998e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key.ip4dst);
999e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask.ip4dst);
1000e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key.ip4src);
1001e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask.ip4src);
100244961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
100352ccf843Smisaki 	    tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4);
100444961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
100552ccf843Smisaki 	    tcam_ptr->ip4_proto_mask, IPPROTO_SCTP);
100644961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
1007e3d11eeeSToomas Soome 	    fspec_key.pdst, fspec_key.psrc);
100844961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
1009e3d11eeeSToomas Soome 	    fspec_mask.pdst, fspec_mask.psrc);
1010e3d11eeeSToomas Soome 	tcam_ptr->ip4_tos_key = fspec_key.tos;
1011e3d11eeeSToomas Soome 	tcam_ptr->ip4_tos_mask = fspec_mask.tos;
1012e3d11eeeSToomas Soome #undef fspec_key
1013e3d11eeeSToomas Soome #undef fspec_mask
101444961713Sgirish }
101544961713Sgirish 
101644961713Sgirish static void
nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)101744961713Sgirish nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1018*86ef0a63SRichard Lowe     tcam_entry_t *tcam_ptr)
101944961713Sgirish {
1020a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1021e3d11eeeSToomas Soome #define	fspec_key (flow_spec->uh.tcpip6spec)
1022e3d11eeeSToomas Soome #define	fspec_mask (flow_spec->um.tcpip6spec)
102344961713Sgirish 
102444961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
102544961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
102652ccf843Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
1027e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key.ip6src);
1028e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask.ip6src);
102944961713Sgirish 	} else {
1030e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key.ip6dst);
1031e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask.ip6dst);
103244961713Sgirish 	}
103344961713Sgirish 
103444961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
103552ccf843Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6);
103644961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
103752ccf843Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP);
103844961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
1039e3d11eeeSToomas Soome 	    fspec_key.pdst, fspec_key.psrc);
104044961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
1041e3d11eeeSToomas Soome 	    fspec_mask.pdst, fspec_mask.psrc);
1042e3d11eeeSToomas Soome 	tcam_ptr->ip6_tos_key = fspec_key.tos;
1043e3d11eeeSToomas Soome 	tcam_ptr->ip6_tos_mask = fspec_mask.tos;
1044e3d11eeeSToomas Soome #undef fspec_key
1045e3d11eeeSToomas Soome #undef fspec_mask
104644961713Sgirish }
104744961713Sgirish 
104844961713Sgirish static void
nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)104944961713Sgirish nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1050*86ef0a63SRichard Lowe     tcam_entry_t *tcam_ptr)
105144961713Sgirish {
1052a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1053e3d11eeeSToomas Soome #define	fspec_key (flow_spec->uh.tcpip6spec)
1054e3d11eeeSToomas Soome #define	fspec_mask (flow_spec->um.tcpip6spec)
105544961713Sgirish 
105644961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
105744961713Sgirish 
105844961713Sgirish 	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
105952ccf843Smisaki 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
1060e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key.ip6src);
1061e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask.ip6src);
106244961713Sgirish 	} else {
1063e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key.ip6dst);
1064e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask.ip6dst);
106544961713Sgirish 	}
106644961713Sgirish 
106744961713Sgirish 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
106852ccf843Smisaki 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6);
106944961713Sgirish 	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
107052ccf843Smisaki 	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP);
107144961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
1072e3d11eeeSToomas Soome 	    fspec_key.pdst, fspec_key.psrc);
107344961713Sgirish 	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
1074e3d11eeeSToomas Soome 	    fspec_mask.pdst, fspec_mask.psrc);
1075e3d11eeeSToomas Soome 	tcam_ptr->ip6_tos_key = fspec_key.tos;
1076e3d11eeeSToomas Soome 	tcam_ptr->ip6_tos_mask = fspec_mask.tos;
1077e3d11eeeSToomas Soome #undef fspec_key
1078e3d11eeeSToomas Soome #undef fspec_mask
10794df55fdeSJanie Lu }
10804df55fdeSJanie Lu 
10814df55fdeSJanie Lu /* ARGSUSED */
10824df55fdeSJanie Lu static void
nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)10834df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec,
1084*86ef0a63SRichard Lowe     tcam_entry_t *tcam_ptr)
10854df55fdeSJanie Lu {
1086e3d11eeeSToomas Soome #define	fspec_key (flow_spec->uh.ahip4spec)
1087e3d11eeeSToomas Soome #define	fspec_mask (flow_spec->um.ahip4spec)
10884df55fdeSJanie Lu 
1089e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key.ip4dst);
1090e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask.ip4dst);
1091e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key.ip4src);
1092e3d11eeeSToomas Soome 	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask.ip4src);
10934df55fdeSJanie Lu 
1094e3d11eeeSToomas Soome 	tcam_ptr->ip4_port_key = fspec_key.spi;
1095e3d11eeeSToomas Soome 	tcam_ptr->ip4_port_mask = fspec_mask.spi;
10964df55fdeSJanie Lu 
10974df55fdeSJanie Lu 	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
10984df55fdeSJanie Lu 	    tcam_ptr->ip4_class_mask,
10994df55fdeSJanie Lu 	    TCAM_CLASS_AH_ESP_IPV4);
11004df55fdeSJanie Lu 
11014df55fdeSJanie Lu 	if (flow_spec->flow_type == FSPEC_AHIP4) {
11024df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
11034df55fdeSJanie Lu 		    tcam_ptr->ip4_proto_mask, IPPROTO_AH);
11044df55fdeSJanie Lu 	} else {
11054df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
11064df55fdeSJanie Lu 		    tcam_ptr->ip4_proto_mask, IPPROTO_ESP);
11074df55fdeSJanie Lu 	}
1108e3d11eeeSToomas Soome 	tcam_ptr->ip4_tos_key = fspec_key.tos;
1109e3d11eeeSToomas Soome 	tcam_ptr->ip4_tos_mask = fspec_mask.tos;
1110e3d11eeeSToomas Soome #undef fspec_key
1111e3d11eeeSToomas Soome #undef fspec_mask
111244961713Sgirish }
111344961713Sgirish 
11144df55fdeSJanie Lu static void
nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)11154df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1116*86ef0a63SRichard Lowe     tcam_entry_t *tcam_ptr)
11174df55fdeSJanie Lu {
11184df55fdeSJanie Lu 	p_nxge_class_pt_cfg_t p_class_cfgp;
1119e3d11eeeSToomas Soome #define	fspec_key (flow_spec->uh.ahip6spec)
1120e3d11eeeSToomas Soome #define	fspec_mask (flow_spec->um.ahip6spec)
11214df55fdeSJanie Lu 
11224df55fdeSJanie Lu 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
11234df55fdeSJanie Lu 	if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] &
11244df55fdeSJanie Lu 	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
1125e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key.ip6src);
1126e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask.ip6src);
11274df55fdeSJanie Lu 	} else {
1128e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key.ip6dst);
1129e3d11eeeSToomas Soome 		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask.ip6dst);
11304df55fdeSJanie Lu 	}
11314df55fdeSJanie Lu 
11324df55fdeSJanie Lu 	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
11334df55fdeSJanie Lu 	    tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6);
11344df55fdeSJanie Lu 
11354df55fdeSJanie Lu 	if (flow_spec->flow_type == FSPEC_AHIP6) {
11364df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
11374df55fdeSJanie Lu 		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH);
11384df55fdeSJanie Lu 	} else {
11394df55fdeSJanie Lu 		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
11404df55fdeSJanie Lu 		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP);
11414df55fdeSJanie Lu 	}
1142e3d11eeeSToomas Soome 	tcam_ptr->ip6_port_key = fspec_key.spi;
1143e3d11eeeSToomas Soome 	tcam_ptr->ip6_port_mask = fspec_mask.spi;
1144e3d11eeeSToomas Soome 	tcam_ptr->ip6_tos_key = fspec_key.tos;
1145e3d11eeeSToomas Soome 	tcam_ptr->ip6_tos_mask = fspec_mask.tos;
1146e3d11eeeSToomas Soome #undef fspec_key
1147e3d11eeeSToomas Soome #undef fspec_mask
11484df55fdeSJanie Lu }
11494df55fdeSJanie Lu 
11504df55fdeSJanie Lu /* ARGSUSED */
11514df55fdeSJanie Lu static void
nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr,tcam_class_t class)11524df55fdeSJanie Lu nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec,
1153*86ef0a63SRichard Lowe     tcam_entry_t *tcam_ptr, tcam_class_t class)
11544df55fdeSJanie Lu {
1155e3d11eeeSToomas Soome #define	fspec_key (flow_spec->uh.ip_usr_spec)
1156e3d11eeeSToomas Soome #define	fspec_mask (flow_spec->um.ip_usr_spec)
11574df55fdeSJanie Lu 
1158e3d11eeeSToomas Soome 	if (fspec_key.ip_ver == FSPEC_IP4) {
1159e3d11eeeSToomas Soome 		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key.ip4dst);
1160e3d11eeeSToomas Soome 		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask.ip4dst);
1161e3d11eeeSToomas Soome 		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key.ip4src);
1162e3d11eeeSToomas Soome 		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask.ip4src);
11634df55fdeSJanie Lu 
1164e3d11eeeSToomas Soome 		tcam_ptr->ip4_port_key = fspec_key.l4_4_bytes;
1165e3d11eeeSToomas Soome 		tcam_ptr->ip4_port_mask = fspec_mask.l4_4_bytes;
11664df55fdeSJanie Lu 
11674df55fdeSJanie Lu 		TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
11684df55fdeSJanie Lu 		    tcam_ptr->ip4_class_mask, class);
11694df55fdeSJanie Lu 
1170e3d11eeeSToomas Soome 		tcam_ptr->ip4_proto_key = fspec_key.proto;
1171e3d11eeeSToomas Soome 		tcam_ptr->ip4_proto_mask = fspec_mask.proto;
11724df55fdeSJanie Lu 
1173e3d11eeeSToomas Soome 		tcam_ptr->ip4_tos_key = fspec_key.tos;
1174e3d11eeeSToomas Soome 		tcam_ptr->ip4_tos_mask = fspec_mask.tos;
11754df55fdeSJanie Lu 	}
1176e3d11eeeSToomas Soome #undef fspec_key
1177e3d11eeeSToomas Soome #undef fspec_mask
11784df55fdeSJanie Lu }
11794df55fdeSJanie Lu 
11804df55fdeSJanie Lu 
118144961713Sgirish nxge_status_t
nxge_flow_get_hash(p_nxge_t nxgep,flow_resource_t * flow_res,uint32_t * H1,uint16_t * H2)118244961713Sgirish nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res,
1183*86ef0a63SRichard Lowe     uint32_t *H1, uint16_t *H2)
118444961713Sgirish {
118544961713Sgirish 	flow_spec_t *flow_spec;
118644961713Sgirish 	uint32_t class_cfg;
118744961713Sgirish 	flow_template_t ft;
1188a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
118944961713Sgirish 
119044961713Sgirish 	int ft_size = sizeof (flow_template_t);
1191a3c5bd6dSspeer 
119244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash"));
119344961713Sgirish 
119444961713Sgirish 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
119544961713Sgirish 	bzero((char *)&ft, ft_size);
119644961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1197a3c5bd6dSspeer 
119844961713Sgirish 	switch (flow_spec->flow_type) {
1199a3c5bd6dSspeer 	case FSPEC_TCPIP4:
1200a3c5bd6dSspeer 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4];
1201a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1202a3c5bd6dSspeer 			ft.ip_proto = IPPROTO_TCP;
1203a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1204a3c5bd6dSspeer 			ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src;
1205a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1206a3c5bd6dSspeer 			ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst;
1207a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1208a3c5bd6dSspeer 			ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc;
1209a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1210a3c5bd6dSspeer 			ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst;
1211a3c5bd6dSspeer 		break;
1212a3c5bd6dSspeer 
1213a3c5bd6dSspeer 	case FSPEC_UDPIP4:
1214a3c5bd6dSspeer 		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4];
1215a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1216a3c5bd6dSspeer 			ft.ip_proto = IPPROTO_UDP;
1217a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1218a3c5bd6dSspeer 			ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src;
1219a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1220a3c5bd6dSspeer 			ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst;
1221a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1222a3c5bd6dSspeer 			ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc;
1223a3c5bd6dSspeer 		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1224a3c5bd6dSspeer 			ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst;
1225a3c5bd6dSspeer 		break;
1226a3c5bd6dSspeer 
1227a3c5bd6dSspeer 	default:
1228a3c5bd6dSspeer 		return (NXGE_ERROR);
122944961713Sgirish 	}
123044961713Sgirish 
123144961713Sgirish 	*H1 = nxge_compute_h1(p_class_cfgp->init_h1,
123252ccf843Smisaki 	    (uint32_t *)&ft, ft_size) & 0xfffff;
123344961713Sgirish 	*H2 = nxge_compute_h2(p_class_cfgp->init_h2,
123452ccf843Smisaki 	    (uint8_t *)&ft, ft_size);
123544961713Sgirish 
123644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash"));
123744961713Sgirish 	return (NXGE_OK);
123844961713Sgirish }
123944961713Sgirish 
124044961713Sgirish nxge_status_t
nxge_add_fcram_entry(p_nxge_t nxgep,flow_resource_t * flow_res)124144961713Sgirish nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
124244961713Sgirish {
124344961713Sgirish 	uint32_t H1;
124444961713Sgirish 	uint16_t H2;
124544961713Sgirish 	nxge_status_t status = NXGE_OK;
124644961713Sgirish 
124744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry"));
124844961713Sgirish 	status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2);
124944961713Sgirish 	if (status != NXGE_OK) {
125044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
125152ccf843Smisaki 		    " nxge_add_fcram_entry failed "));
125244961713Sgirish 		return (status);
125344961713Sgirish 	}
125444961713Sgirish 
125544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry"));
125644961713Sgirish 	return (NXGE_OK);
125744961713Sgirish }
125844961713Sgirish 
125944961713Sgirish /*
126044961713Sgirish  * Already decided this flow goes into the tcam
126144961713Sgirish  */
126244961713Sgirish 
126344961713Sgirish nxge_status_t
nxge_add_tcam_entry(p_nxge_t nxgep,flow_resource_t * flow_res)126444961713Sgirish nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
126544961713Sgirish {
126644961713Sgirish 	npi_handle_t handle;
12674df55fdeSJanie Lu 	uint64_t channel_cookie;
12684df55fdeSJanie Lu 	uint64_t flow_cookie;
126944961713Sgirish 	flow_spec_t *flow_spec;
127044961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
127144961713Sgirish 	tcam_entry_t tcam_ptr;
12724df55fdeSJanie Lu 	tcam_location_t location;
127344961713Sgirish 	uint8_t offset, rdc_grp;
1274a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
12754df55fdeSJanie Lu 	uint64_t class;
127644961713Sgirish 
127744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry"));
127844961713Sgirish 	handle = nxgep->npi_reg_handle;
127944961713Sgirish 
1280a3c5bd6dSspeer 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
128144961713Sgirish 	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
128244961713Sgirish 	flow_cookie = flow_res->flow_cookie;
128344961713Sgirish 	channel_cookie = flow_res->channel_cookie;
12844df55fdeSJanie Lu 	location = (tcam_location_t)nxge_tcam_get_index(nxgep,
12854df55fdeSJanie Lu 	    (uint16_t)flow_res->location);
12864df55fdeSJanie Lu 
12874df55fdeSJanie Lu 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
12884df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
12894df55fdeSJanie Lu 		    " nxge_add_tcam_entry: common hardware not set",
12904df55fdeSJanie Lu 		    nxgep->niu_type));
12914df55fdeSJanie Lu 		return (NXGE_ERROR);
12924df55fdeSJanie Lu 	}
12934df55fdeSJanie Lu 
1294e3d11eeeSToomas Soome 	class = TCAM_CLASS_INVALID;
12954df55fdeSJanie Lu 	if (flow_spec->flow_type == FSPEC_IP_USR) {
12964df55fdeSJanie Lu 		int i;
12974df55fdeSJanie Lu 		int add_usr_cls = 0;
12984df55fdeSJanie Lu 		int ipv6 = 0;
12994df55fdeSJanie Lu 		nxge_usr_l3_cls_t *l3_ucls_p;
1300e3d11eeeSToomas Soome #define	uspec (flow_spec->uh.ip_usr_spec)
1301e3d11eeeSToomas Soome #define	umask (flow_spec->um.ip_usr_spec)
13024df55fdeSJanie Lu 
13034df55fdeSJanie Lu 		MUTEX_ENTER(&hw_p->nxge_tcam_lock);
13044df55fdeSJanie Lu 
13054df55fdeSJanie Lu 		for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
13064df55fdeSJanie Lu 			l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
13074df55fdeSJanie Lu 			if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) {
1308e3d11eeeSToomas Soome 				if (uspec.proto == l3_ucls_p->pid) {
13094df55fdeSJanie Lu 					class = l3_ucls_p->cls;
13104df55fdeSJanie Lu 					l3_ucls_p->tcam_ref_cnt++;
13114df55fdeSJanie Lu 					add_usr_cls = 1;
13124df55fdeSJanie Lu 					break;
13134df55fdeSJanie Lu 				}
13144df55fdeSJanie Lu 			} else if (l3_ucls_p->valid == 0) {
13154df55fdeSJanie Lu 				/* Program new user IP class */
13164df55fdeSJanie Lu 				switch (i) {
13174df55fdeSJanie Lu 				case 0:
13184df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_4;
13194df55fdeSJanie Lu 					break;
13204df55fdeSJanie Lu 				case 1:
13214df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_5;
13224df55fdeSJanie Lu 					break;
13234df55fdeSJanie Lu 				case 2:
13244df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_6;
13254df55fdeSJanie Lu 					break;
13264df55fdeSJanie Lu 				case 3:
13274df55fdeSJanie Lu 					class = TCAM_CLASS_IP_USER_7;
13284df55fdeSJanie Lu 					break;
13294df55fdeSJanie Lu 				default:
13304df55fdeSJanie Lu 					break;
13314df55fdeSJanie Lu 				}
1332e3d11eeeSToomas Soome 				if (uspec.ip_ver == FSPEC_IP6)
13334df55fdeSJanie Lu 					ipv6 = 1;
13344df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
1335e3d11eeeSToomas Soome 				    (tcam_class_t)class, uspec.tos,
1336e3d11eeeSToomas Soome 				    umask.tos, uspec.proto, ipv6);
13374df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
13384df55fdeSJanie Lu 					goto fail;
13394df55fdeSJanie Lu 
13404df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
13414df55fdeSJanie Lu 				    (tcam_class_t)class);
13424df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
13434df55fdeSJanie Lu 					goto fail;
13444df55fdeSJanie Lu 
13454df55fdeSJanie Lu 				l3_ucls_p->cls = class;
1346e3d11eeeSToomas Soome 				l3_ucls_p->pid = uspec.proto;
13474df55fdeSJanie Lu 				l3_ucls_p->tcam_ref_cnt++;
13484df55fdeSJanie Lu 				l3_ucls_p->valid = 1;
13494df55fdeSJanie Lu 				add_usr_cls = 1;
13504df55fdeSJanie Lu 				break;
13514df55fdeSJanie Lu 			} else if (l3_ucls_p->tcam_ref_cnt == 0 &&
1352e3d11eeeSToomas Soome 			    uspec.proto == l3_ucls_p->pid) {
13534df55fdeSJanie Lu 				/*
13544df55fdeSJanie Lu 				 * The class has already been programmed,
13554df55fdeSJanie Lu 				 * probably for flow hash
13564df55fdeSJanie Lu 				 */
13574df55fdeSJanie Lu 				class = l3_ucls_p->cls;
1358e3d11eeeSToomas Soome 				if (uspec.ip_ver == FSPEC_IP6)
13594df55fdeSJanie Lu 					ipv6 = 1;
13604df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
1361e3d11eeeSToomas Soome 				    (tcam_class_t)class, uspec.tos,
1362e3d11eeeSToomas Soome 				    umask.tos, uspec.proto, ipv6);
13634df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
13644df55fdeSJanie Lu 					goto fail;
13654df55fdeSJanie Lu 
13664df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
13674df55fdeSJanie Lu 				    (tcam_class_t)class);
13684df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
13694df55fdeSJanie Lu 					goto fail;
13704df55fdeSJanie Lu 
1371e3d11eeeSToomas Soome 				l3_ucls_p->pid = uspec.proto;
13724df55fdeSJanie Lu 				l3_ucls_p->tcam_ref_cnt++;
13734df55fdeSJanie Lu 				add_usr_cls = 1;
13744df55fdeSJanie Lu 				break;
13754df55fdeSJanie Lu 			}
13764df55fdeSJanie Lu 		}
13774df55fdeSJanie Lu 		if (!add_usr_cls) {
13784df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13794df55fdeSJanie Lu 			    "nxge_add_tcam_entry: Could not find/insert class"
1380e3d11eeeSToomas Soome 			    "for pid %d", uspec.proto));
13814df55fdeSJanie Lu 			goto fail;
13824df55fdeSJanie Lu 		}
13834df55fdeSJanie Lu 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
1384e3d11eeeSToomas Soome #undef uspec
1385e3d11eeeSToomas Soome #undef umask
13864df55fdeSJanie Lu 	}
138744961713Sgirish 
138844961713Sgirish 	switch (flow_spec->flow_type) {
1389a3c5bd6dSspeer 	case FSPEC_TCPIP4:
1390a3c5bd6dSspeer 		nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr);
1391a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4,
139252ccf843Smisaki 		    flow_cookie);
1393a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4,
139452ccf843Smisaki 		    channel_cookie);
1395a3c5bd6dSspeer 		break;
1396a3c5bd6dSspeer 
1397a3c5bd6dSspeer 	case FSPEC_UDPIP4:
1398a3c5bd6dSspeer 		nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr);
1399a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
140052ccf843Smisaki 		    TCAM_CLASS_UDP_IPV4,
140152ccf843Smisaki 		    flow_cookie);
1402a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
140352ccf843Smisaki 		    TCAM_CLASS_UDP_IPV4,
140452ccf843Smisaki 		    channel_cookie);
1405a3c5bd6dSspeer 		break;
1406a3c5bd6dSspeer 
1407a3c5bd6dSspeer 	case FSPEC_TCPIP6:
1408a3c5bd6dSspeer 		nxge_fill_tcam_entry_tcp_ipv6(nxgep,
140952ccf843Smisaki 		    flow_spec, &tcam_ptr);
1410a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6,
141152ccf843Smisaki 		    flow_cookie);
1412a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6,
141352ccf843Smisaki 		    channel_cookie);
1414a3c5bd6dSspeer 		break;
1415a3c5bd6dSspeer 
1416a3c5bd6dSspeer 	case FSPEC_UDPIP6:
1417a3c5bd6dSspeer 		nxge_fill_tcam_entry_udp_ipv6(nxgep,
141852ccf843Smisaki 		    flow_spec, &tcam_ptr);
1419a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
142052ccf843Smisaki 		    TCAM_CLASS_UDP_IPV6,
14214df55fdeSJanie Lu 		    flow_cookie);
1422a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
142352ccf843Smisaki 		    TCAM_CLASS_UDP_IPV6,
14244df55fdeSJanie Lu 		    channel_cookie);
1425a3c5bd6dSspeer 		break;
1426a3c5bd6dSspeer 
1427a3c5bd6dSspeer 	case FSPEC_SCTPIP4:
1428a3c5bd6dSspeer 		nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr);
1429a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
143052ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV4,
14314df55fdeSJanie Lu 		    flow_cookie);
1432a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
143352ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV4,
14344df55fdeSJanie Lu 		    channel_cookie);
1435a3c5bd6dSspeer 		break;
1436a3c5bd6dSspeer 
1437a3c5bd6dSspeer 	case FSPEC_SCTPIP6:
1438a3c5bd6dSspeer 		nxge_fill_tcam_entry_sctp_ipv6(nxgep,
143952ccf843Smisaki 		    flow_spec, &tcam_ptr);
1440a3c5bd6dSspeer 		rdc_grp = nxge_get_rdc_group(nxgep,
144152ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV6,
14424df55fdeSJanie Lu 		    flow_cookie);
1443a3c5bd6dSspeer 		offset = nxge_get_rdc_offset(nxgep,
144452ccf843Smisaki 		    TCAM_CLASS_SCTP_IPV6,
14454df55fdeSJanie Lu 		    channel_cookie);
14464df55fdeSJanie Lu 		break;
14474df55fdeSJanie Lu 
14484df55fdeSJanie Lu 	case FSPEC_AHIP4:
14494df55fdeSJanie Lu 	case FSPEC_ESPIP4:
14504df55fdeSJanie Lu 		nxge_fill_tcam_entry_ah_esp(nxgep, flow_spec, &tcam_ptr);
14514df55fdeSJanie Lu 		rdc_grp = nxge_get_rdc_group(nxgep,
14524df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV4,
145352ccf843Smisaki 		    flow_cookie);
14544df55fdeSJanie Lu 		offset = nxge_get_rdc_offset(nxgep,
14554df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV4,
14564df55fdeSJanie Lu 		    channel_cookie);
1457a3c5bd6dSspeer 		break;
1458a3c5bd6dSspeer 
14594df55fdeSJanie Lu 	case FSPEC_AHIP6:
14604df55fdeSJanie Lu 	case FSPEC_ESPIP6:
14614df55fdeSJanie Lu 		nxge_fill_tcam_entry_ah_esp_ipv6(nxgep,
14624df55fdeSJanie Lu 		    flow_spec, &tcam_ptr);
14634df55fdeSJanie Lu 		rdc_grp = nxge_get_rdc_group(nxgep,
14644df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV6,
14654df55fdeSJanie Lu 		    flow_cookie);
14664df55fdeSJanie Lu 		offset = nxge_get_rdc_offset(nxgep,
14674df55fdeSJanie Lu 		    TCAM_CLASS_AH_ESP_IPV6,
14684df55fdeSJanie Lu 		    channel_cookie);
14694df55fdeSJanie Lu 		break;
14704df55fdeSJanie Lu 
14714df55fdeSJanie Lu 	case FSPEC_IP_USR:
14724df55fdeSJanie Lu 		nxge_fill_tcam_entry_ip_usr(nxgep, flow_spec, &tcam_ptr,
14734df55fdeSJanie Lu 		    (tcam_class_t)class);
14744df55fdeSJanie Lu 		rdc_grp = nxge_get_rdc_group(nxgep,
14754df55fdeSJanie Lu 		    (tcam_class_t)class, flow_cookie);
14764df55fdeSJanie Lu 		offset = nxge_get_rdc_offset(nxgep,
14774df55fdeSJanie Lu 		    (tcam_class_t)class, channel_cookie);
14784df55fdeSJanie Lu 		break;
1479a3c5bd6dSspeer 	default:
14804df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14814df55fdeSJanie Lu 		    "nxge_add_tcam_entry: Unknown flow spec 0x%x",
14824df55fdeSJanie Lu 		    flow_spec->flow_type));
14834df55fdeSJanie Lu 		return (NXGE_ERROR);
148444961713Sgirish 	}
148544961713Sgirish 
148644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
148752ccf843Smisaki 	    " nxge_add_tcam_entry write"
148852ccf843Smisaki 	    " for location %d offset %d", location, offset));
148944961713Sgirish 
149044961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
1491a3c5bd6dSspeer 	rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr);
149244961713Sgirish 
149344961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
149444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
149552ccf843Smisaki 		    " nxge_add_tcam_entry write"
149652ccf843Smisaki 		    " failed for location %d", location));
14974df55fdeSJanie Lu 		goto fail;
149844961713Sgirish 	}
1499a3c5bd6dSspeer 
150044961713Sgirish 	tcam_ptr.match_action.value = 0;
150144961713Sgirish 	tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp;
150244961713Sgirish 	tcam_ptr.match_action.bits.ldw.offset = offset;
150344961713Sgirish 	tcam_ptr.match_action.bits.ldw.tres =
150452ccf843Smisaki 	    TRES_TERM_OVRD_L2RDC;
15054df55fdeSJanie Lu 	if (channel_cookie == NXGE_PKT_DISCARD)
150644961713Sgirish 		tcam_ptr.match_action.bits.ldw.disc = 1;
150744961713Sgirish 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
150852ccf843Smisaki 	    location, tcam_ptr.match_action.value);
150944961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
151044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
151152ccf843Smisaki 		    " nxge_add_tcam_entry write"
151252ccf843Smisaki 		    " failed for ASC RAM location %d", location));
15134df55fdeSJanie Lu 		goto fail;
151444961713Sgirish 	}
1515a3c5bd6dSspeer 	bcopy((void *) &tcam_ptr,
151652ccf843Smisaki 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
151752ccf843Smisaki 	    sizeof (tcam_entry_t));
15184df55fdeSJanie Lu 	nxgep->classifier.tcam_entry_cnt++;
15194df55fdeSJanie Lu 	nxgep->classifier.tcam_entries[location].valid = 1;
152044961713Sgirish 
152144961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
152244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry"));
152344961713Sgirish 	return (NXGE_OK);
15244df55fdeSJanie Lu fail:
15254df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15264df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_tcam_entry FAILED"));
15274df55fdeSJanie Lu 	return (NXGE_ERROR);
152844961713Sgirish }
152944961713Sgirish 
153014ea4bb7Ssd static nxge_status_t
nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)153114ea4bb7Ssd nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)
153244961713Sgirish {
153344961713Sgirish 	tcam_entry_t tcam_ptr;
153444961713Sgirish 	tcam_location_t location;
153544961713Sgirish 	uint8_t class;
153614ea4bb7Ssd 	uint32_t class_config;
153744961713Sgirish 	npi_handle_t handle;
153844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1539a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
154014ea4bb7Ssd 	nxge_status_t status = NXGE_OK;
154144961713Sgirish 
154244961713Sgirish 	handle = nxgep->npi_reg_handle;
154344961713Sgirish 	class = 0;
1544a3c5bd6dSspeer 	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
154544961713Sgirish 	tcam_ptr.ip4_noport_key = 1;
154644961713Sgirish 	tcam_ptr.ip4_noport_mask = 1;
154714ea4bb7Ssd 	location = nxgep->function_num;
154844961713Sgirish 	nxgep->classifier.fragment_bug_location = location;
154944961713Sgirish 
155044961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
155144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
155252ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment: common hardware not set",
155352ccf843Smisaki 		    nxgep->niu_type));
155414ea4bb7Ssd 		return (NXGE_ERROR);
155544961713Sgirish 	}
155644961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
155744961713Sgirish 	rs = npi_fflp_tcam_entry_write(handle,
155852ccf843Smisaki 	    location, &tcam_ptr);
155944961713Sgirish 
156044961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
156144961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
156244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
156352ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment "
156452ccf843Smisaki 		    " tcam_entry write"
156552ccf843Smisaki 		    " failed for location %d", location));
156614ea4bb7Ssd 		return (NXGE_ERROR);
156744961713Sgirish 	}
156844961713Sgirish 	tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp;
1569a3c5bd6dSspeer 	tcam_ptr.match_action.bits.ldw.offset = 0;	/* use the default */
157044961713Sgirish 	tcam_ptr.match_action.bits.ldw.tres =
157152ccf843Smisaki 	    TRES_TERM_USE_OFFSET;
157244961713Sgirish 	rs = npi_fflp_tcam_asc_ram_entry_write(handle,
157352ccf843Smisaki 	    location, tcam_ptr.match_action.value);
157444961713Sgirish 
157544961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
157644961713Sgirish 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
157744961713Sgirish 		NXGE_DEBUG_MSG((nxgep,
157852ccf843Smisaki 		    FFLP_CTL,
157952ccf843Smisaki 		    " nxge_tcam_handle_ip_fragment "
158052ccf843Smisaki 		    " tcam_entry write"
158152ccf843Smisaki 		    " failed for ASC RAM location %d", location));
158214ea4bb7Ssd 		return (NXGE_ERROR);
158344961713Sgirish 	}
1584a3c5bd6dSspeer 	bcopy((void *) &tcam_ptr,
158552ccf843Smisaki 	    (void *) &nxgep->classifier.tcam_entries[location].tce,
158652ccf843Smisaki 	    sizeof (tcam_entry_t));
15874df55fdeSJanie Lu 	nxgep->classifier.tcam_entry_cnt++;
15884df55fdeSJanie Lu 	nxgep->classifier.tcam_entries[location].valid = 1;
158914ea4bb7Ssd 	for (class = TCAM_CLASS_TCP_IPV4;
159052ccf843Smisaki 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
159114ea4bb7Ssd 		class_config = nxgep->class_config.class_cfg[class];
159214ea4bb7Ssd 		class_config |= NXGE_CLASS_TCAM_LOOKUP;
159314ea4bb7Ssd 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
159414ea4bb7Ssd 
159514ea4bb7Ssd 		if (status & NPI_FFLP_ERROR) {
159614ea4bb7Ssd 			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
159714ea4bb7Ssd 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
159852ccf843Smisaki 			    "nxge_tcam_handle_ip_fragment "
159952ccf843Smisaki 			    "nxge_fflp_ip_class_config failed "
160052ccf843Smisaki 			    " class %d config %x ", class, class_config));
160114ea4bb7Ssd 			return (NXGE_ERROR);
160214ea4bb7Ssd 		}
160314ea4bb7Ssd 	}
160414ea4bb7Ssd 
160514ea4bb7Ssd 	rs = npi_fflp_cfg_tcam_enable(handle);
160614ea4bb7Ssd 	if (rs & NPI_FFLP_ERROR) {
160714ea4bb7Ssd 		MUTEX_EXIT(&hw_p->nxge_tcam_lock);
160814ea4bb7Ssd 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
160952ccf843Smisaki 		    "nxge_tcam_handle_ip_fragment "
161052ccf843Smisaki 		    " nxge_fflp_config_tcam_enable failed"));
161114ea4bb7Ssd 		return (NXGE_ERROR);
161214ea4bb7Ssd 	}
161344961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
161414ea4bb7Ssd 	return (NXGE_OK);
161544961713Sgirish }
161644961713Sgirish 
161744961713Sgirish /* ARGSUSED */
161844961713Sgirish static int
nxge_flow_need_hash_lookup(p_nxge_t nxgep,flow_resource_t * flow_res)1619a3c5bd6dSspeer nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res)
162044961713Sgirish {
162144961713Sgirish 	return (0);
162244961713Sgirish }
162344961713Sgirish 
162444961713Sgirish nxge_status_t
nxge_add_flow(p_nxge_t nxgep,flow_resource_t * flow_res)162544961713Sgirish nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res)
162644961713Sgirish {
162744961713Sgirish 
162844961713Sgirish 	int insert_hash = 0;
162944961713Sgirish 	nxge_status_t status = NXGE_OK;
163044961713Sgirish 
16312e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
1632a3c5bd6dSspeer 		/* determine whether to do TCAM or Hash flow */
163344961713Sgirish 		insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res);
163444961713Sgirish 	}
163544961713Sgirish 	if (insert_hash) {
163644961713Sgirish 		status = nxge_add_fcram_entry(nxgep, flow_res);
163744961713Sgirish 	} else {
163844961713Sgirish 		status = nxge_add_tcam_entry(nxgep, flow_res);
163944961713Sgirish 	}
164044961713Sgirish 	return (status);
164144961713Sgirish }
164244961713Sgirish 
164344961713Sgirish void
nxge_put_tcam(p_nxge_t nxgep,p_mblk_t mp)164444961713Sgirish nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp)
164544961713Sgirish {
164644961713Sgirish 	flow_resource_t *fs;
164744961713Sgirish 
1648a3c5bd6dSspeer 	fs = (flow_resource_t *)mp->b_rptr;
164944961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
165052ccf843Smisaki 	    "nxge_put_tcam addr fs $%p  type %x offset %x",
165152ccf843Smisaki 	    fs, fs->flow_spec.flow_type, fs->channel_cookie));
165244961713Sgirish 	(void) nxge_add_tcam_entry(nxgep, fs);
165344961713Sgirish }
165444961713Sgirish 
165544961713Sgirish nxge_status_t
nxge_fflp_config_tcam_enable(p_nxge_t nxgep)165644961713Sgirish nxge_fflp_config_tcam_enable(p_nxge_t nxgep)
165744961713Sgirish {
165844961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
165944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
166044961713Sgirish 
166144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable"));
166244961713Sgirish 	rs = npi_fflp_cfg_tcam_enable(handle);
166344961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
166444961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
166552ccf843Smisaki 		    " nxge_fflp_config_tcam_enable failed"));
166644961713Sgirish 		return (NXGE_ERROR | rs);
166744961713Sgirish 	}
166844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable"));
166944961713Sgirish 	return (NXGE_OK);
167044961713Sgirish }
167144961713Sgirish 
167244961713Sgirish nxge_status_t
nxge_fflp_config_tcam_disable(p_nxge_t nxgep)167344961713Sgirish nxge_fflp_config_tcam_disable(p_nxge_t nxgep)
167444961713Sgirish {
167544961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
167644961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
167744961713Sgirish 
167844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
167952ccf843Smisaki 	    " ==> nxge_fflp_config_tcam_disable"));
168044961713Sgirish 	rs = npi_fflp_cfg_tcam_disable(handle);
168144961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
168244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
168352ccf843Smisaki 		    " nxge_fflp_config_tcam_disable failed"));
168444961713Sgirish 		return (NXGE_ERROR | rs);
168544961713Sgirish 	}
168644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
168752ccf843Smisaki 	    " <== nxge_fflp_config_tcam_disable"));
168844961713Sgirish 	return (NXGE_OK);
168944961713Sgirish }
169044961713Sgirish 
169144961713Sgirish nxge_status_t
nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)169244961713Sgirish nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)
169344961713Sgirish {
169444961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
169544961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1696a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1697a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1698a3c5bd6dSspeer 	uint8_t partition;
169944961713Sgirish 
170044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
170152ccf843Smisaki 	    " ==> nxge_fflp_config_hash_lookup_enable"));
170244961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
170344961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
170444961713Sgirish 
1705678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1706678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
1707678453a8Sspeer 			rs = npi_fflp_cfg_fcram_partition_enable(
170852ccf843Smisaki 			    handle, partition);
1709678453a8Sspeer 			if (rs != NPI_SUCCESS) {
1710678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1711678453a8Sspeer 				    " nxge_fflp_config_hash_lookup_enable"
1712678453a8Sspeer 				    "failed FCRAM partition"
1713678453a8Sspeer 				    " enable for partition %d ", partition));
1714678453a8Sspeer 				return (NXGE_ERROR | rs);
1715678453a8Sspeer 			}
171644961713Sgirish 		}
171744961713Sgirish 	}
171844961713Sgirish 
171944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
172052ccf843Smisaki 	    " <== nxge_fflp_config_hash_lookup_enable"));
172144961713Sgirish 	return (NXGE_OK);
172244961713Sgirish }
172344961713Sgirish 
172444961713Sgirish nxge_status_t
nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)172544961713Sgirish nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)
172644961713Sgirish {
172744961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
172844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1729a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
1730a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
1731a3c5bd6dSspeer 	uint8_t partition;
173244961713Sgirish 
173344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
173452ccf843Smisaki 	    " ==> nxge_fflp_config_hash_lookup_disable"));
173544961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
173644961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
173744961713Sgirish 
1738678453a8Sspeer 	for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
1739678453a8Sspeer 		if (p_cfgp->grpids[partition]) {
1740678453a8Sspeer 			rs = npi_fflp_cfg_fcram_partition_disable(handle,
1741678453a8Sspeer 			    partition);
1742678453a8Sspeer 			if (rs != NPI_SUCCESS) {
1743678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1744678453a8Sspeer 				    " nxge_fflp_config_hash_lookup_disable"
1745678453a8Sspeer 				    " failed FCRAM partition"
1746678453a8Sspeer 				    " disable for partition %d ", partition));
1747678453a8Sspeer 				return (NXGE_ERROR | rs);
1748678453a8Sspeer 			}
174944961713Sgirish 		}
175044961713Sgirish 	}
175144961713Sgirish 
175244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
175352ccf843Smisaki 	    " <== nxge_fflp_config_hash_lookup_disable"));
175444961713Sgirish 	return (NXGE_OK);
175544961713Sgirish }
175644961713Sgirish 
175744961713Sgirish nxge_status_t
nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)175844961713Sgirish nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)
175944961713Sgirish {
176044961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
176144961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
176244961713Sgirish 
176344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
176452ccf843Smisaki 	    " ==> nxge_fflp_config_llc_snap_enable"));
176544961713Sgirish 	rs = npi_fflp_cfg_llcsnap_enable(handle);
176644961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
176744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
176852ccf843Smisaki 		    " nxge_fflp_config_llc_snap_enable failed"));
176944961713Sgirish 		return (NXGE_ERROR | rs);
177044961713Sgirish 	}
177144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
177252ccf843Smisaki 	    " <== nxge_fflp_config_llc_snap_enable"));
177344961713Sgirish 	return (NXGE_OK);
177444961713Sgirish }
177544961713Sgirish 
177644961713Sgirish nxge_status_t
nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)177744961713Sgirish nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)
177844961713Sgirish {
177944961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
178044961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
1781a3c5bd6dSspeer 
178244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
178352ccf843Smisaki 	    " ==> nxge_fflp_config_llc_snap_disable"));
178444961713Sgirish 	rs = npi_fflp_cfg_llcsnap_disable(handle);
178544961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
178644961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
178752ccf843Smisaki 		    " nxge_fflp_config_llc_snap_disable failed"));
178844961713Sgirish 		return (NXGE_ERROR | rs);
178944961713Sgirish 	}
179044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
179152ccf843Smisaki 	    " <== nxge_fflp_config_llc_snap_disable"));
179244961713Sgirish 	return (NXGE_OK);
179344961713Sgirish }
179444961713Sgirish 
179544961713Sgirish nxge_status_t
nxge_fflp_ip_usr_class_config(p_nxge_t nxgep,tcam_class_t class,uint32_t config)179644961713Sgirish nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class,
1797*86ef0a63SRichard Lowe     uint32_t config)
179844961713Sgirish {
179944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
180044961713Sgirish 	npi_handle_t handle = nxgep->npi_reg_handle;
180144961713Sgirish 	uint8_t tos, tos_mask, proto, ver = 0;
180244961713Sgirish 	uint8_t class_enable = 0;
180344961713Sgirish 
180444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config"));
180544961713Sgirish 
180644961713Sgirish 	tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >>
180752ccf843Smisaki 	    NXGE_CLASS_CFG_IP_TOS_SHIFT;
180844961713Sgirish 	tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >>
180952ccf843Smisaki 	    NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT;
181044961713Sgirish 	proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >>
181152ccf843Smisaki 	    NXGE_CLASS_CFG_IP_PROTO_SHIFT;
181244961713Sgirish 	if (config & NXGE_CLASS_CFG_IP_IPV6_MASK)
181344961713Sgirish 		ver = 1;
181444961713Sgirish 	if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK)
181544961713Sgirish 		class_enable = 1;
181644961713Sgirish 	rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask,
181752ccf843Smisaki 	    proto, ver);
181844961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
181944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
182052ccf843Smisaki 		    " nxge_fflp_ip_usr_class_config"
182152ccf843Smisaki 		    " for class %d failed ", class));
182244961713Sgirish 		return (NXGE_ERROR | rs);
182344961713Sgirish 	}
182444961713Sgirish 	if (class_enable)
182544961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class);
182644961713Sgirish 	else
182744961713Sgirish 		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
182844961713Sgirish 
182944961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
183044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
183152ccf843Smisaki 		    " nxge_fflp_ip_usr_class_config"
183252ccf843Smisaki 		    " TCAM enable/disable for class %d failed ", class));
183344961713Sgirish 		return (NXGE_ERROR | rs);
183444961713Sgirish 	}
183544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config"));
183644961713Sgirish 	return (NXGE_OK);
183744961713Sgirish }
183844961713Sgirish 
183944961713Sgirish nxge_status_t
nxge_fflp_ip_class_config(p_nxge_t nxgep,tcam_class_t class,uint32_t config)1840a3c5bd6dSspeer nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config)
184144961713Sgirish {
184244961713Sgirish 	uint32_t class_config;
184344961713Sgirish 	nxge_status_t t_status = NXGE_OK;
184444961713Sgirish 	nxge_status_t f_status = NXGE_OK;
1845a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
184644961713Sgirish 
184744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
1848a3c5bd6dSspeer 
184944961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
185044961713Sgirish 	class_config = p_class_cfgp->class_cfg[class];
185144961713Sgirish 
185244961713Sgirish 	if (class_config != config) {
185344961713Sgirish 		p_class_cfgp->class_cfg[class] = config;
185444961713Sgirish 		class_config = config;
185544961713Sgirish 	}
185644961713Sgirish 
185744961713Sgirish 	t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config);
185844961713Sgirish 	f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config);
185944961713Sgirish 
186044961713Sgirish 	if (t_status & NPI_FFLP_ERROR) {
186144961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
186252ccf843Smisaki 		    " nxge_fflp_ip_class_config %x"
186352ccf843Smisaki 		    " for class %d tcam failed", config, class));
186444961713Sgirish 		return (t_status);
186544961713Sgirish 	}
186644961713Sgirish 	if (f_status & NPI_FFLP_ERROR) {
186744961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
186852ccf843Smisaki 		    " nxge_fflp_ip_class_config %x"
186952ccf843Smisaki 		    " for class %d flow key failed", config, class));
187044961713Sgirish 		return (f_status);
187144961713Sgirish 	}
187244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
187344961713Sgirish 	return (NXGE_OK);
187444961713Sgirish }
187544961713Sgirish 
187644961713Sgirish nxge_status_t
nxge_fflp_ip_class_config_get(p_nxge_t nxgep,tcam_class_t class,uint32_t * config)187744961713Sgirish nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class,
1878*86ef0a63SRichard Lowe     uint32_t *config)
187944961713Sgirish {
188044961713Sgirish 	uint32_t t_class_config, f_class_config;
188144961713Sgirish 	int t_status = NXGE_OK;
188244961713Sgirish 	int f_status = NXGE_OK;
188344961713Sgirish 
188444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
1885a3c5bd6dSspeer 
188644961713Sgirish 	t_class_config = f_class_config = 0;
188744961713Sgirish 	t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config);
188844961713Sgirish 	f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config);
188944961713Sgirish 
189044961713Sgirish 	if (t_status & NPI_FFLP_ERROR) {
189144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
189252ccf843Smisaki 		    " nxge_fflp_ip_class_config_get  "
189352ccf843Smisaki 		    " for class %d tcam failed", class));
189444961713Sgirish 		return (t_status);
189544961713Sgirish 	}
189644961713Sgirish 
189744961713Sgirish 	if (f_status & NPI_FFLP_ERROR) {
189844961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
189952ccf843Smisaki 		    " nxge_fflp_ip_class_config_get  "
190052ccf843Smisaki 		    " for class %d flow key failed", class));
190144961713Sgirish 		return (f_status);
190244961713Sgirish 	}
190344961713Sgirish 
190444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
190552ccf843Smisaki 	    " nxge_fflp_ip_class_config tcam %x flow %x",
190652ccf843Smisaki 	    t_class_config, f_class_config));
190744961713Sgirish 
190844961713Sgirish 	*config = t_class_config | f_class_config;
190944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get"));
191044961713Sgirish 	return (NXGE_OK);
191144961713Sgirish }
191244961713Sgirish 
191344961713Sgirish nxge_status_t
nxge_fflp_ip_class_config_all(p_nxge_t nxgep)191444961713Sgirish nxge_fflp_ip_class_config_all(p_nxge_t nxgep)
191544961713Sgirish {
191644961713Sgirish 	uint32_t class_config;
191744961713Sgirish 	tcam_class_t class;
191844961713Sgirish 
191944961713Sgirish #ifdef	NXGE_DEBUG
192044961713Sgirish 	int status = NXGE_OK;
192144961713Sgirish #endif
192244961713Sgirish 
192344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config"));
192444961713Sgirish 	for (class = TCAM_CLASS_TCP_IPV4;
192552ccf843Smisaki 	    class <= TCAM_CLASS_SCTP_IPV6; class++) {
192644961713Sgirish 		class_config = nxgep->class_config.class_cfg[class];
192744961713Sgirish #ifndef	NXGE_DEBUG
192844961713Sgirish 		(void) nxge_fflp_ip_class_config(nxgep, class, class_config);
192944961713Sgirish #else
193044961713Sgirish 		status = nxge_fflp_ip_class_config(nxgep, class, class_config);
193144961713Sgirish 		if (status & NPI_FFLP_ERROR) {
193244961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
193352ccf843Smisaki 			    "nxge_fflp_ip_class_config failed "
193452ccf843Smisaki 			    " class %d config %x ",
193552ccf843Smisaki 			    class, class_config));
193644961713Sgirish 		}
193744961713Sgirish #endif
193844961713Sgirish 	}
193944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
194044961713Sgirish 	return (NXGE_OK);
194144961713Sgirish }
194244961713Sgirish 
194344961713Sgirish nxge_status_t
nxge_fflp_config_vlan_table(p_nxge_t nxgep,uint16_t vlan_id)194444961713Sgirish nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id)
194544961713Sgirish {
194644961713Sgirish 	uint8_t port, rdc_grp;
194744961713Sgirish 	npi_handle_t handle;
194844961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
194944961713Sgirish 	uint8_t priority = 1;
195044961713Sgirish 	p_nxge_mv_cfg_t vlan_table;
1951a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
1952a3c5bd6dSspeer 	p_nxge_hw_list_t hw_p;
195344961713Sgirish 
195444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table"));
195544961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
195644961713Sgirish 	handle = nxgep->npi_reg_handle;
195744961713Sgirish 	vlan_table = p_class_cfgp->vlan_tbl;
195844961713Sgirish 	port = nxgep->function_num;
195944961713Sgirish 
196044961713Sgirish 	if (vlan_table[vlan_id].flag == 0) {
196144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
196252ccf843Smisaki 		    " nxge_fflp_config_vlan_table"
196352ccf843Smisaki 		    " vlan id is not configured %d", vlan_id));
196444961713Sgirish 		return (NXGE_ERROR);
196544961713Sgirish 	}
196644961713Sgirish 
196744961713Sgirish 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
196844961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
196952ccf843Smisaki 		    " nxge_fflp_config_vlan_table:"
197052ccf843Smisaki 		    " common hardware not set", nxgep->niu_type));
197144961713Sgirish 		return (NXGE_ERROR);
197244961713Sgirish 	}
197344961713Sgirish 	MUTEX_ENTER(&hw_p->nxge_vlan_lock);
197444961713Sgirish 	rdc_grp = vlan_table[vlan_id].rdctbl;
197544961713Sgirish 	rs = npi_fflp_cfg_enet_vlan_table_assoc(handle,
197652ccf843Smisaki 	    port, vlan_id,
197752ccf843Smisaki 	    rdc_grp, priority);
197844961713Sgirish 
197944961713Sgirish 	MUTEX_EXIT(&hw_p->nxge_vlan_lock);
198044961713Sgirish 	if (rs & NPI_FFLP_ERROR) {
198144961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
198252ccf843Smisaki 		    "nxge_fflp_config_vlan_table failed "
198352ccf843Smisaki 		    " Port %d vlan_id %d rdc_grp %d",
198452ccf843Smisaki 		    port, vlan_id, rdc_grp));
198544961713Sgirish 		return (NXGE_ERROR | rs);
198644961713Sgirish 	}
1987a3c5bd6dSspeer 
198844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table"));
198944961713Sgirish 	return (NXGE_OK);
199044961713Sgirish }
199144961713Sgirish 
199244961713Sgirish nxge_status_t
nxge_fflp_update_hw(p_nxge_t nxgep)199344961713Sgirish nxge_fflp_update_hw(p_nxge_t nxgep)
199444961713Sgirish {
199544961713Sgirish 	nxge_status_t status = NXGE_OK;
199644961713Sgirish 	p_nxge_param_t pa;
199744961713Sgirish 	uint64_t cfgd_vlans;
199844961713Sgirish 	uint64_t *val_ptr;
199944961713Sgirish 	int i;
200044961713Sgirish 	int num_macs;
200144961713Sgirish 	uint8_t alt_mac;
200244961713Sgirish 	nxge_param_map_t *p_map;
200344961713Sgirish 	p_nxge_mv_cfg_t vlan_table;
2004a3c5bd6dSspeer 	p_nxge_class_pt_cfg_t p_class_cfgp;
2005a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_all_cfgp;
2006a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
200744961713Sgirish 
200844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw"));
2009a3c5bd6dSspeer 
201044961713Sgirish 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
201144961713Sgirish 	p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
201244961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
201344961713Sgirish 
201444961713Sgirish 	status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1);
201544961713Sgirish 	if (status != NXGE_OK) {
201644961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
201752ccf843Smisaki 		    "nxge_fflp_set_hash1 Failed"));
201844961713Sgirish 		return (NXGE_ERROR);
201944961713Sgirish 	}
202044961713Sgirish 
202144961713Sgirish 	status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2);
202244961713Sgirish 	if (status != NXGE_OK) {
202344961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
202452ccf843Smisaki 		    "nxge_fflp_set_hash2 Failed"));
202544961713Sgirish 		return (NXGE_ERROR);
202644961713Sgirish 	}
202744961713Sgirish 	vlan_table = p_class_cfgp->vlan_tbl;
202844961713Sgirish 
2029a3c5bd6dSspeer 	/* configure vlan tables */
203044961713Sgirish 	pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp];
203144961713Sgirish 	val_ptr = (uint64_t *)pa->value;
2032a3c5bd6dSspeer 	cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >>
203352ccf843Smisaki 	    NXGE_PARAM_ARRAY_CNT_SHIFT);
203444961713Sgirish 
203544961713Sgirish 	for (i = 0; i < cfgd_vlans; i++) {
203644961713Sgirish 		p_map = (nxge_param_map_t *)&val_ptr[i];
203744961713Sgirish 		if (vlan_table[p_map->param_id].flag) {
203844961713Sgirish 			status = nxge_fflp_config_vlan_table(nxgep,
203952ccf843Smisaki 			    p_map->param_id);
204044961713Sgirish 			if (status != NXGE_OK) {
204144961713Sgirish 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
204252ccf843Smisaki 				    "nxge_fflp_config_vlan_table Failed"));
204344961713Sgirish 				return (NXGE_ERROR);
204444961713Sgirish 			}
204544961713Sgirish 		}
204644961713Sgirish 	}
2047a3c5bd6dSspeer 
2048a3c5bd6dSspeer 	/* config MAC addresses */
204944961713Sgirish 	num_macs = p_cfgp->max_macs;
205044961713Sgirish 	pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp];
205144961713Sgirish 	val_ptr = (uint64_t *)pa->value;
205244961713Sgirish 
205344961713Sgirish 	for (alt_mac = 0; alt_mac < num_macs; alt_mac++) {
205444961713Sgirish 		if (p_class_cfgp->mac_host_info[alt_mac].flag) {
205544961713Sgirish 			status = nxge_logical_mac_assign_rdc_table(nxgep,
205652ccf843Smisaki 			    alt_mac);
205744961713Sgirish 			if (status != NXGE_OK) {
205844961713Sgirish 				NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
205952ccf843Smisaki 				    "nxge_logical_mac_assign_rdc_table"
206052ccf843Smisaki 				    " Failed"));
206144961713Sgirish 				return (NXGE_ERROR);
206244961713Sgirish 			}
206344961713Sgirish 		}
206444961713Sgirish 	}
2065a3c5bd6dSspeer 
2066a3c5bd6dSspeer 	/* Config Hash values */
2067f6485eecSyc 	/* config classes */
206844961713Sgirish 	status = nxge_fflp_ip_class_config_all(nxgep);
206944961713Sgirish 	if (status != NXGE_OK) {
207044961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
207152ccf843Smisaki 		    "nxge_fflp_ip_class_config_all Failed"));
207244961713Sgirish 		return (NXGE_ERROR);
207344961713Sgirish 	}
207444961713Sgirish 	return (NXGE_OK);
207544961713Sgirish }
207644961713Sgirish 
207744961713Sgirish nxge_status_t
nxge_classify_init_hw(p_nxge_t nxgep)207844961713Sgirish nxge_classify_init_hw(p_nxge_t nxgep)
207944961713Sgirish {
208044961713Sgirish 	nxge_status_t status = NXGE_OK;
208144961713Sgirish 
208244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw"));
208344961713Sgirish 
208444961713Sgirish 	if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) {
208544961713Sgirish 		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
208652ccf843Smisaki 		    "nxge_classify_init_hw already init"));
208744961713Sgirish 		return (NXGE_OK);
208844961713Sgirish 	}
208944961713Sgirish 
2090a3c5bd6dSspeer 	/* Now do a real configuration */
209144961713Sgirish 	status = nxge_fflp_update_hw(nxgep);
209244961713Sgirish 	if (status != NXGE_OK) {
209344961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
209452ccf843Smisaki 		    "nxge_fflp_update_hw failed"));
209544961713Sgirish 		return (NXGE_ERROR);
209644961713Sgirish 	}
2097a3c5bd6dSspeer 
2098a3c5bd6dSspeer 	/* Init RDC tables? ? who should do that? rxdma or fflp ? */
2099a3c5bd6dSspeer 	/* attach rdc table to the MAC port. */
210044961713Sgirish 	status = nxge_main_mac_assign_rdc_table(nxgep);
210144961713Sgirish 	if (status != NXGE_OK) {
210244961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
210352ccf843Smisaki 		    "nxge_main_mac_assign_rdc_table failed"));
210444961713Sgirish 		return (NXGE_ERROR);
210544961713Sgirish 	}
2106a3c5bd6dSspeer 
210758324dfcSspeer 	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
210844961713Sgirish 	if (status != NXGE_OK) {
210944961713Sgirish 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
211052ccf843Smisaki 		    "nxge_multicast_mac_assign_rdc_table failed"));
211144961713Sgirish 		return (NXGE_ERROR);
211244961713Sgirish 	}
211314ea4bb7Ssd 
21144df55fdeSJanie Lu 	if (nxgep->classifier.fragment_bug == 1) {
21154df55fdeSJanie Lu 		status = nxge_tcam_handle_ip_fragment(nxgep);
21164df55fdeSJanie Lu 		if (status != NXGE_OK) {
21174df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21184df55fdeSJanie Lu 			    "nxge_tcam_handle_ip_fragment failed"));
21194df55fdeSJanie Lu 			return (NXGE_ERROR);
21204df55fdeSJanie Lu 		}
212114ea4bb7Ssd 	}
212244961713Sgirish 
212344961713Sgirish 	nxgep->classifier.state |= NXGE_FFLP_HW_INIT;
212444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw"));
212544961713Sgirish 	return (NXGE_OK);
212644961713Sgirish }
212744961713Sgirish 
212844961713Sgirish nxge_status_t
nxge_fflp_handle_sys_errors(p_nxge_t nxgep)212944961713Sgirish nxge_fflp_handle_sys_errors(p_nxge_t nxgep)
213044961713Sgirish {
2131a3c5bd6dSspeer 	npi_handle_t handle;
2132a3c5bd6dSspeer 	p_nxge_fflp_stats_t statsp;
2133a3c5bd6dSspeer 	uint8_t portn, rdc_grp;
2134a3c5bd6dSspeer 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
2135a3c5bd6dSspeer 	p_nxge_hw_pt_cfg_t p_cfgp;
2136a3c5bd6dSspeer 	vlan_par_err_t vlan_err;
2137a3c5bd6dSspeer 	tcam_err_t tcam_err;
2138a3c5bd6dSspeer 	hash_lookup_err_log1_t fcram1_err;
2139a3c5bd6dSspeer 	hash_lookup_err_log2_t fcram2_err;
2140a3c5bd6dSspeer 	hash_tbl_data_log_t fcram_err;
214144961713Sgirish 
214244961713Sgirish 	handle = nxgep->npi_handle;
214344961713Sgirish 	statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats;
214444961713Sgirish 	portn = nxgep->mac.portnum;
214544961713Sgirish 
214644961713Sgirish 	/*
2147a3c5bd6dSspeer 	 * need to read the fflp error registers to figure out what the error
2148a3c5bd6dSspeer 	 * is
214944961713Sgirish 	 */
215044961713Sgirish 	npi_fflp_vlan_error_get(handle, &vlan_err);
215144961713Sgirish 	npi_fflp_tcam_error_get(handle, &tcam_err);
215244961713Sgirish 
215344961713Sgirish 	if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) {
215444961713Sgirish 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
215552ccf843Smisaki 		    " vlan table parity error on port %d"
215652ccf843Smisaki 		    " addr: 0x%x data: 0x%x",
215752ccf843Smisaki 		    portn, vlan_err.bits.ldw.addr,
215852ccf843Smisaki 		    vlan_err.bits.ldw.data));
215944961713Sgirish 		statsp->vlan_parity_err++;
216044961713Sgirish 
216144961713Sgirish 		if (vlan_err.bits.ldw.m_err) {
216244961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
216352ccf843Smisaki 			    " vlan table multiple errors on port %d",
216452ccf843Smisaki 			    portn));
216544961713Sgirish 		}
216644961713Sgirish 		statsp->errlog.vlan = (uint32_t)vlan_err.value;
2167b37cc459SToomas Soome 		NXGE_FM_REPORT_ERROR(nxgep, 0, 0,
216852ccf843Smisaki 		    NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR);
216944961713Sgirish 		npi_fflp_vlan_error_clear(handle);
217044961713Sgirish 	}
217144961713Sgirish 
217244961713Sgirish 	if (tcam_err.bits.ldw.err) {
217344961713Sgirish 		if (tcam_err.bits.ldw.p_ecc != 0) {
217444961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
217552ccf843Smisaki 			    " TCAM ECC error on port %d"
217652ccf843Smisaki 			    " TCAM entry: 0x%x syndrome: 0x%x",
217752ccf843Smisaki 			    portn, tcam_err.bits.ldw.addr,
217852ccf843Smisaki 			    tcam_err.bits.ldw.syndrome));
217944961713Sgirish 			statsp->tcam_ecc_err++;
218044961713Sgirish 		} else {
218144961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
218252ccf843Smisaki 			    " TCAM Parity error on port %d"
218352ccf843Smisaki 			    " addr: 0x%x parity value: 0x%x",
218452ccf843Smisaki 			    portn, tcam_err.bits.ldw.addr,
218552ccf843Smisaki 			    tcam_err.bits.ldw.syndrome));
218644961713Sgirish 			statsp->tcam_parity_err++;
218744961713Sgirish 		}
218844961713Sgirish 
218944961713Sgirish 		if (tcam_err.bits.ldw.mult) {
219044961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
219152ccf843Smisaki 			    " TCAM Multiple errors on port %d", portn));
219244961713Sgirish 		} else {
219344961713Sgirish 			NXGE_ERROR_MSG((nxgep, FFLP_CTL,
219452ccf843Smisaki 			    " TCAM PIO error on port %d", portn));
219544961713Sgirish 		}
219644961713Sgirish 
219744961713Sgirish 		statsp->errlog.tcam = (uint32_t)tcam_err.value;
2198b37cc459SToomas Soome 		NXGE_FM_REPORT_ERROR(nxgep, 0, 0,
219952ccf843Smisaki 		    NXGE_FM_EREPORT_FFLP_TCAM_ERR);
220044961713Sgirish 		npi_fflp_tcam_error_clear(handle);
220144961713Sgirish 	}
220244961713Sgirish 
220344961713Sgirish 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
220444961713Sgirish 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
220544961713Sgirish 
2206678453a8Sspeer 	for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) {
2207678453a8Sspeer 		if (p_cfgp->grpids[rdc_grp]) {
2208678453a8Sspeer 			npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp);
2209678453a8Sspeer 			if (fcram_err.bits.ldw.pio_err) {
2210678453a8Sspeer 				NXGE_ERROR_MSG((nxgep, FFLP_CTL,
221152ccf843Smisaki 				    " FCRAM PIO ECC error on port %d"
221252ccf843Smisaki 				    " rdc group: %d Hash Table addr: 0x%x"
221352ccf843Smisaki 				    " syndrome: 0x%x",
221452ccf843Smisaki 				    portn, rdc_grp,
221552ccf843Smisaki 				    fcram_err.bits.ldw.fcram_addr,
221652ccf843Smisaki 				    fcram_err.bits.ldw.syndrome));
2217678453a8Sspeer 				statsp->hash_pio_err[rdc_grp]++;
2218678453a8Sspeer 				statsp->errlog.hash_pio[rdc_grp] =
2219678453a8Sspeer 				    (uint32_t)fcram_err.value;
2220b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, 0, 0,
2221678453a8Sspeer 				    NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR);
2222678453a8Sspeer 				npi_fflp_fcram_error_clear(handle, rdc_grp);
2223678453a8Sspeer 			}
222444961713Sgirish 		}
222544961713Sgirish 	}
222644961713Sgirish 
222744961713Sgirish 	npi_fflp_fcram_error_log1_get(handle, &fcram1_err);
222844961713Sgirish 	if (fcram1_err.bits.ldw.ecc_err) {
222944961713Sgirish 		char *multi_str = "";
223044961713Sgirish 		char *multi_bit_str = "";
2231a3c5bd6dSspeer 
223244961713Sgirish 		npi_fflp_fcram_error_log2_get(handle, &fcram2_err);
223344961713Sgirish 		if (fcram1_err.bits.ldw.mult_lk) {
223444961713Sgirish 			multi_str = "multiple";
223544961713Sgirish 		}
223644961713Sgirish 		if (fcram1_err.bits.ldw.mult_bit) {
223744961713Sgirish 			multi_bit_str = "multiple bits";
223844961713Sgirish 		}
2239f6485eecSyc 		statsp->hash_lookup_err++;
224044961713Sgirish 		NXGE_ERROR_MSG((nxgep, FFLP_CTL,
224152ccf843Smisaki 		    " FCRAM %s lookup %s ECC error on port %d"
224252ccf843Smisaki 		    " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x",
224352ccf843Smisaki 		    multi_str, multi_bit_str, portn,
224452ccf843Smisaki 		    fcram2_err.bits.ldw.h1,
224552ccf843Smisaki 		    fcram2_err.bits.ldw.subarea,
224652ccf843Smisaki 		    fcram2_err.bits.ldw.syndrome));
2247b37cc459SToomas Soome 		NXGE_FM_REPORT_ERROR(nxgep, 0, 0,
224852ccf843Smisaki 		    NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR);
224944961713Sgirish 	}
225044961713Sgirish 	statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value;
225144961713Sgirish 	statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value;
225244961713Sgirish 	return (NXGE_OK);
225344961713Sgirish }
22544df55fdeSJanie Lu 
22554df55fdeSJanie Lu int
nxge_get_valid_tcam_cnt(p_nxge_t nxgep)2256*86ef0a63SRichard Lowe nxge_get_valid_tcam_cnt(p_nxge_t nxgep)
2257*86ef0a63SRichard Lowe {
22584df55fdeSJanie Lu 	return ((nxgep->classifier.fragment_bug == 1) ?
2259*86ef0a63SRichard Lowe 	    nxgep->classifier.tcam_entry_cnt - 1 :
2260*86ef0a63SRichard Lowe 	    nxgep->classifier.tcam_entry_cnt);
22614df55fdeSJanie Lu }
22624df55fdeSJanie Lu 
22634df55fdeSJanie Lu int
nxge_rxdma_channel_cnt(p_nxge_t nxgep)22644df55fdeSJanie Lu nxge_rxdma_channel_cnt(p_nxge_t nxgep)
22654df55fdeSJanie Lu {
22664df55fdeSJanie Lu 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
22674df55fdeSJanie Lu 	p_nxge_hw_pt_cfg_t p_cfgp;
22684df55fdeSJanie Lu 
22694df55fdeSJanie Lu 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
22704df55fdeSJanie Lu 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
22714df55fdeSJanie Lu 	return (p_cfgp->max_rdcs);
22724df55fdeSJanie Lu }
22734df55fdeSJanie Lu 
22744df55fdeSJanie Lu /* ARGSUSED */
22754df55fdeSJanie Lu int
nxge_rxclass_ioctl(p_nxge_t nxgep,queue_t * wq,mblk_t * mp)22764df55fdeSJanie Lu nxge_rxclass_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
22774df55fdeSJanie Lu {
22784df55fdeSJanie Lu 	uint32_t cmd;
22794df55fdeSJanie Lu 	rx_class_cfg_t *cfg_info = (rx_class_cfg_t *)mp->b_rptr;
22804df55fdeSJanie Lu 
22814df55fdeSJanie Lu 	if (nxgep == NULL) {
22824df55fdeSJanie Lu 		return (-1);
22834df55fdeSJanie Lu 	}
22844df55fdeSJanie Lu 	cmd = cfg_info->cmd;
22854df55fdeSJanie Lu 	switch (cmd) {
22864df55fdeSJanie Lu 	default:
22874df55fdeSJanie Lu 		return (-1);
22884df55fdeSJanie Lu 
22894df55fdeSJanie Lu 	case NXGE_RX_CLASS_GCHAN:
22904df55fdeSJanie Lu 		cfg_info->data = nxge_rxdma_channel_cnt(nxgep);
22914df55fdeSJanie Lu 		break;
22924df55fdeSJanie Lu 	case NXGE_RX_CLASS_GRULE_CNT:
22934df55fdeSJanie Lu 		MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
22944df55fdeSJanie Lu 		cfg_info->rule_cnt = nxge_get_valid_tcam_cnt(nxgep);
22954df55fdeSJanie Lu 		MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
22964df55fdeSJanie Lu 		break;
22974df55fdeSJanie Lu 	case NXGE_RX_CLASS_GRULE:
22984df55fdeSJanie Lu 		nxge_get_tcam_entry(nxgep, &cfg_info->fs);
22994df55fdeSJanie Lu 		break;
23004df55fdeSJanie Lu 	case NXGE_RX_CLASS_GRULE_ALL:
23014df55fdeSJanie Lu 		nxge_get_tcam_entry_all(nxgep, cfg_info);
23024df55fdeSJanie Lu 		break;
23034df55fdeSJanie Lu 	case NXGE_RX_CLASS_RULE_DEL:
23044df55fdeSJanie Lu 		nxge_del_tcam_entry(nxgep, cfg_info->fs.location);
23054df55fdeSJanie Lu 		break;
23064df55fdeSJanie Lu 	case NXGE_RX_CLASS_RULE_INS:
23074df55fdeSJanie Lu 		(void) nxge_add_tcam_entry(nxgep, &cfg_info->fs);
23084df55fdeSJanie Lu 		break;
23094df55fdeSJanie Lu 	}
23104df55fdeSJanie Lu 	return (0);
23114df55fdeSJanie Lu }
23124df55fdeSJanie Lu /* ARGSUSED */
23134df55fdeSJanie Lu int
nxge_rxhash_ioctl(p_nxge_t nxgep,queue_t * wq,mblk_t * mp)23144df55fdeSJanie Lu nxge_rxhash_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
23154df55fdeSJanie Lu {
23164df55fdeSJanie Lu 	uint32_t cmd;
23174df55fdeSJanie Lu 	cfg_cmd_t	*cfg_info = (cfg_cmd_t *)mp->b_rptr;
23184df55fdeSJanie Lu 
23194df55fdeSJanie Lu 	if (nxgep == NULL) {
23204df55fdeSJanie Lu 		return (-1);
23214df55fdeSJanie Lu 	}
23224df55fdeSJanie Lu 	cmd = cfg_info->cmd;
23234df55fdeSJanie Lu 
23244df55fdeSJanie Lu 	switch (cmd) {
23254df55fdeSJanie Lu 	default:
23264df55fdeSJanie Lu 		return (-1);
23274df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_ADD_CLS:
23284df55fdeSJanie Lu 		nxge_add_iptun_class(nxgep, &cfg_info->iptun_cfg,
23294df55fdeSJanie Lu 		    &cfg_info->class_id);
23304df55fdeSJanie Lu 		break;
23314df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_SET_HASH:
23324df55fdeSJanie Lu 		nxge_cfg_iptun_hash(nxgep, &cfg_info->iptun_cfg,
23334df55fdeSJanie Lu 		    cfg_info->class_id);
23344df55fdeSJanie Lu 		break;
23354df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_DEL_CLS:
23364df55fdeSJanie Lu 		nxge_del_iptun_class(nxgep, cfg_info->class_id);
23374df55fdeSJanie Lu 		break;
23384df55fdeSJanie Lu 	case NXGE_IPTUN_CFG_GET_CLS:
23394df55fdeSJanie Lu 		nxge_get_iptun_class(nxgep, &cfg_info->iptun_cfg,
23404df55fdeSJanie Lu 		    cfg_info->class_id);
23414df55fdeSJanie Lu 		break;
23424df55fdeSJanie Lu 	case NXGE_CLS_CFG_SET_SYM:
23434df55fdeSJanie Lu 		nxge_set_ip_cls_sym(nxgep, cfg_info->class_id, cfg_info->sym);
23444df55fdeSJanie Lu 		break;
23454df55fdeSJanie Lu 	case NXGE_CLS_CFG_GET_SYM:
23464df55fdeSJanie Lu 		nxge_get_ip_cls_sym(nxgep, cfg_info->class_id, &cfg_info->sym);
23474df55fdeSJanie Lu 		break;
23484df55fdeSJanie Lu 	}
23494df55fdeSJanie Lu 	return (0);
23504df55fdeSJanie Lu }
23514df55fdeSJanie Lu 
23524df55fdeSJanie Lu void
nxge_get_tcam_entry_all(p_nxge_t nxgep,rx_class_cfg_t * cfgp)23534df55fdeSJanie Lu nxge_get_tcam_entry_all(p_nxge_t nxgep, rx_class_cfg_t *cfgp)
23544df55fdeSJanie Lu {
23554df55fdeSJanie Lu 	nxge_classify_t *clasp = &nxgep->classifier;
23564df55fdeSJanie Lu 	uint16_t	n_entries;
23574df55fdeSJanie Lu 	int		i, j, k;
23584df55fdeSJanie Lu 	tcam_flow_spec_t	*tcam_entryp;
23594df55fdeSJanie Lu 
23604df55fdeSJanie Lu 	cfgp->data = clasp->tcam_size;
23614df55fdeSJanie Lu 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
23624df55fdeSJanie Lu 	n_entries = cfgp->rule_cnt;
23634df55fdeSJanie Lu 
23644df55fdeSJanie Lu 	for (i = 0, j = 0; j < cfgp->data; j++) {
23654df55fdeSJanie Lu 		k = nxge_tcam_get_index(nxgep, j);
23664df55fdeSJanie Lu 		tcam_entryp = &clasp->tcam_entries[k];
23674df55fdeSJanie Lu 		if (tcam_entryp->valid != 1)
23684df55fdeSJanie Lu 			continue;
23694df55fdeSJanie Lu 		cfgp->rule_locs[i] = j;
23704df55fdeSJanie Lu 		i++;
23714df55fdeSJanie Lu 	};
23724df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
23734df55fdeSJanie Lu 
23744df55fdeSJanie Lu 	if (n_entries != i) {
23754df55fdeSJanie Lu 		/* print warning, this should not happen */
23764df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry_all"
23774df55fdeSJanie Lu 		    "n_entries[%d] != i[%d]!!!", n_entries, i));
23784df55fdeSJanie Lu 	}
23794df55fdeSJanie Lu }
23804df55fdeSJanie Lu 
23814df55fdeSJanie Lu 
23824df55fdeSJanie Lu /* Entries for the ports are interleaved in the TCAM */
23834df55fdeSJanie Lu static uint16_t
nxge_tcam_get_index(p_nxge_t nxgep,uint16_t index)23844df55fdeSJanie Lu nxge_tcam_get_index(p_nxge_t nxgep, uint16_t index)
23854df55fdeSJanie Lu {
23864df55fdeSJanie Lu 	/* One entry reserved for IP fragment rule */
23874df55fdeSJanie Lu 	if (index >= (nxgep->classifier.tcam_size - 1))
23884df55fdeSJanie Lu 		index = 0;
23894df55fdeSJanie Lu 	if (nxgep->classifier.fragment_bug == 1)
23904df55fdeSJanie Lu 		index++;
23914df55fdeSJanie Lu 	return (nxgep->classifier.tcam_top + (index * nxgep->nports));
23924df55fdeSJanie Lu }
23934df55fdeSJanie Lu 
23944df55fdeSJanie Lu static uint32_t
nxge_tcam_cls_to_flow(uint32_t class_code)2395*86ef0a63SRichard Lowe nxge_tcam_cls_to_flow(uint32_t class_code)
2396*86ef0a63SRichard Lowe {
23974df55fdeSJanie Lu 	switch (class_code) {
23984df55fdeSJanie Lu 	case TCAM_CLASS_TCP_IPV4:
23994df55fdeSJanie Lu 		return (FSPEC_TCPIP4);
24004df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV4:
24014df55fdeSJanie Lu 		return (FSPEC_UDPIP4);
24024df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV4:
24034df55fdeSJanie Lu 		return (FSPEC_AHIP4);
24044df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV4:
24054df55fdeSJanie Lu 		return (FSPEC_SCTPIP4);
24064df55fdeSJanie Lu 	case  TCAM_CLASS_TCP_IPV6:
24074df55fdeSJanie Lu 		return (FSPEC_TCPIP6);
24084df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV6:
24094df55fdeSJanie Lu 		return (FSPEC_UDPIP6);
24104df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV6:
24114df55fdeSJanie Lu 		return (FSPEC_AHIP6);
24124df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV6:
24134df55fdeSJanie Lu 		return (FSPEC_SCTPIP6);
24144df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_4:
24154df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_5:
24164df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_6:
24174df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_7:
24184df55fdeSJanie Lu 		return (FSPEC_IP_USR);
24194df55fdeSJanie Lu 	default:
24204df55fdeSJanie Lu 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "nxge_tcam_cls_to_flow"
24214df55fdeSJanie Lu 		    ": Unknown class code [0x%x]", class_code));
24224df55fdeSJanie Lu 		break;
24234df55fdeSJanie Lu 	}
24244df55fdeSJanie Lu 	return (0);
24254df55fdeSJanie Lu }
24264df55fdeSJanie Lu 
24274df55fdeSJanie Lu void
nxge_get_tcam_entry(p_nxge_t nxgep,flow_resource_t * fs)24284df55fdeSJanie Lu nxge_get_tcam_entry(p_nxge_t nxgep, flow_resource_t *fs)
24294df55fdeSJanie Lu {
2430*86ef0a63SRichard Lowe 	uint16_t	index;
24314df55fdeSJanie Lu 	tcam_flow_spec_t *tcam_ep;
24324df55fdeSJanie Lu 	tcam_entry_t	*tp;
24334df55fdeSJanie Lu 	flow_spec_t	*fspec;
2434e3d11eeeSToomas Soome #define	fspec_key (fspec->uh.tcpip4spec)
2435e3d11eeeSToomas Soome #define	fspec_mask (fspec->um.tcpip4spec)
24364df55fdeSJanie Lu 
24374df55fdeSJanie Lu 	index = nxge_tcam_get_index(nxgep, (uint16_t)fs->location);
24384df55fdeSJanie Lu 	tcam_ep = &nxgep->classifier.tcam_entries[index];
24394df55fdeSJanie Lu 	if (tcam_ep->valid != 1) {
24404df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry: :"
24414df55fdeSJanie Lu 		    "Entry [%d] invalid for index [%d]", fs->location, index));
24424df55fdeSJanie Lu 		return;
24434df55fdeSJanie Lu 	}
24444df55fdeSJanie Lu 
24454df55fdeSJanie Lu 	/* Fill the flow spec entry */
24464df55fdeSJanie Lu 	tp = &tcam_ep->tce;
24474df55fdeSJanie Lu 	fspec = &fs->flow_spec;
24484df55fdeSJanie Lu 	fspec->flow_type = nxge_tcam_cls_to_flow(tp->ip4_class_key);
24494df55fdeSJanie Lu 
24504df55fdeSJanie Lu 	/* TODO - look at proto field to differentiate between AH and ESP */
24514df55fdeSJanie Lu 	if (fspec->flow_type == FSPEC_AHIP4) {
24524df55fdeSJanie Lu 		if (tp->ip4_proto_key == IPPROTO_ESP)
24534df55fdeSJanie Lu 			fspec->flow_type = FSPEC_ESPIP4;
24544df55fdeSJanie Lu 	}
24554df55fdeSJanie Lu 
24564df55fdeSJanie Lu 	switch (tp->ip4_class_key) {
24574df55fdeSJanie Lu 	case TCAM_CLASS_TCP_IPV4:
24584df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV4:
24594df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV4:
24604df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV4:
2461e3d11eeeSToomas Soome 		FSPEC_IPV4_ADDR(fspec_key.ip4dst, tp->ip4_dest_key);
2462e3d11eeeSToomas Soome 		FSPEC_IPV4_ADDR(fspec_mask.ip4dst, tp->ip4_dest_mask);
2463e3d11eeeSToomas Soome 		FSPEC_IPV4_ADDR(fspec_key.ip4src, tp->ip4_src_key);
2464e3d11eeeSToomas Soome 		FSPEC_IPV4_ADDR(fspec_mask.ip4src, tp->ip4_src_mask);
2465e3d11eeeSToomas Soome 		fspec_key.tos = tp->ip4_tos_key;
2466e3d11eeeSToomas Soome 		fspec_mask.tos = tp->ip4_tos_mask;
24674df55fdeSJanie Lu 		break;
24684df55fdeSJanie Lu 	default:
24694df55fdeSJanie Lu 		break;
24704df55fdeSJanie Lu 	}
24714df55fdeSJanie Lu 
24724df55fdeSJanie Lu 	switch (tp->ip4_class_key) {
24734df55fdeSJanie Lu 	case TCAM_CLASS_TCP_IPV4:
24744df55fdeSJanie Lu 	case TCAM_CLASS_UDP_IPV4:
24754df55fdeSJanie Lu 	case TCAM_CLASS_SCTP_IPV4:
2476e3d11eeeSToomas Soome 		FSPEC_IP_PORTS(fspec_key.pdst, fspec_key.psrc,
24774df55fdeSJanie Lu 		    tp->ip4_port_key);
2478e3d11eeeSToomas Soome 		FSPEC_IP_PORTS(fspec_mask.pdst, fspec_mask.psrc,
24794df55fdeSJanie Lu 		    tp->ip4_port_mask);
24804df55fdeSJanie Lu 		break;
24814df55fdeSJanie Lu 	case TCAM_CLASS_AH_ESP_IPV4:
24824df55fdeSJanie Lu 		fspec->uh.ahip4spec.spi = tp->ip4_port_key;
24834df55fdeSJanie Lu 		fspec->um.ahip4spec.spi = tp->ip4_port_mask;
24844df55fdeSJanie Lu 		break;
24854df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_4:
24864df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_5:
24874df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_6:
24884df55fdeSJanie Lu 	case TCAM_CLASS_IP_USER_7:
24894df55fdeSJanie Lu 		fspec->uh.ip_usr_spec.l4_4_bytes = tp->ip4_port_key;
24904df55fdeSJanie Lu 		fspec->um.ip_usr_spec.l4_4_bytes = tp->ip4_port_mask;
24914df55fdeSJanie Lu 		fspec->uh.ip_usr_spec.ip_ver = FSPEC_IP4;
24924df55fdeSJanie Lu 		fspec->uh.ip_usr_spec.proto = tp->ip4_proto_key;
24934df55fdeSJanie Lu 		fspec->um.ip_usr_spec.proto = tp->ip4_proto_mask;
24944df55fdeSJanie Lu 		break;
24954df55fdeSJanie Lu 	default:
24964df55fdeSJanie Lu 		break;
24974df55fdeSJanie Lu 	}
24984df55fdeSJanie Lu 
24994df55fdeSJanie Lu 	if (tp->match_action.bits.ldw.disc == 1) {
25004df55fdeSJanie Lu 		fs->channel_cookie = NXGE_PKT_DISCARD;
25014df55fdeSJanie Lu 	} else {
25024df55fdeSJanie Lu 		fs->channel_cookie = tp->match_action.bits.ldw.offset;
25034df55fdeSJanie Lu 	}
2504e3d11eeeSToomas Soome #undef fspec_key
2505e3d11eeeSToomas Soome #undef fspec_mask
25064df55fdeSJanie Lu }
25074df55fdeSJanie Lu 
25084df55fdeSJanie Lu void
nxge_del_tcam_entry(p_nxge_t nxgep,uint32_t location)25094df55fdeSJanie Lu nxge_del_tcam_entry(p_nxge_t nxgep, uint32_t location)
25104df55fdeSJanie Lu {
25114df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
2512*86ef0a63SRichard Lowe 	uint16_t	index;
25134df55fdeSJanie Lu 	tcam_flow_spec_t *tcam_ep;
25144df55fdeSJanie Lu 	tcam_entry_t	*tp;
25154df55fdeSJanie Lu 	tcam_class_t	class;
25164df55fdeSJanie Lu 
25174df55fdeSJanie Lu 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
25184df55fdeSJanie Lu 	index = nxge_tcam_get_index(nxgep, (uint16_t)location);
25194df55fdeSJanie Lu 	tcam_ep = &nxgep->classifier.tcam_entries[index];
25204df55fdeSJanie Lu 	if (tcam_ep->valid != 1) {
25214df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_tcam_entry: :"
25224df55fdeSJanie Lu 		    "Entry [%d] invalid for index [%d]", location, index));
25234df55fdeSJanie Lu 		goto fail;
25244df55fdeSJanie Lu 	}
25254df55fdeSJanie Lu 
25264df55fdeSJanie Lu 	/* Fill the flow spec entry */
25274df55fdeSJanie Lu 	tp = &tcam_ep->tce;
25284df55fdeSJanie Lu 	class = tp->ip4_class_key;
25294df55fdeSJanie Lu 	if (class >= TCAM_CLASS_IP_USER_4 && class <= TCAM_CLASS_IP_USER_7) {
25304df55fdeSJanie Lu 		int i;
25314df55fdeSJanie Lu 		nxge_usr_l3_cls_t *l3_ucls_p;
25324df55fdeSJanie Lu 		p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
25334df55fdeSJanie Lu 
25344df55fdeSJanie Lu 		for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
25354df55fdeSJanie Lu 			l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
25364df55fdeSJanie Lu 			if (l3_ucls_p->valid) {
25374df55fdeSJanie Lu 				if (l3_ucls_p->cls == class &&
25384df55fdeSJanie Lu 				    l3_ucls_p->tcam_ref_cnt) {
25394df55fdeSJanie Lu 					l3_ucls_p->tcam_ref_cnt--;
25404df55fdeSJanie Lu 					if (l3_ucls_p->tcam_ref_cnt > 0)
25414df55fdeSJanie Lu 						continue;
25424df55fdeSJanie Lu 					/* disable class */
25434df55fdeSJanie Lu 					rs = npi_fflp_cfg_ip_usr_cls_disable(
25444df55fdeSJanie Lu 					    nxgep->npi_reg_handle,
25454df55fdeSJanie Lu 					    (tcam_class_t)class);
25464df55fdeSJanie Lu 					if (rs != NPI_SUCCESS)
25474df55fdeSJanie Lu 						goto fail;
25484df55fdeSJanie Lu 					l3_ucls_p->cls = 0;
25494df55fdeSJanie Lu 					l3_ucls_p->pid = 0;
25504df55fdeSJanie Lu 					l3_ucls_p->valid = 0;
25514df55fdeSJanie Lu 					break;
25524df55fdeSJanie Lu 				}
25534df55fdeSJanie Lu 			}
25544df55fdeSJanie Lu 		}
25554df55fdeSJanie Lu 		if (i == NXGE_L3_PROG_CLS) {
25564df55fdeSJanie Lu 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25574df55fdeSJanie Lu 			    "nxge_del_tcam_entry: Usr class "
25584df55fdeSJanie Lu 			    "0x%llx not found", (unsigned long long) class));
25594df55fdeSJanie Lu 			goto fail;
25604df55fdeSJanie Lu 		}
25614df55fdeSJanie Lu 	}
25624df55fdeSJanie Lu 
25634df55fdeSJanie Lu 	rs = npi_fflp_tcam_entry_invalidate(nxgep->npi_reg_handle, index);
25644df55fdeSJanie Lu 	if (rs != NPI_SUCCESS) {
25654df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25664df55fdeSJanie Lu 		    "nxge_del_tcam_entry: TCAM invalidate failed "
25674df55fdeSJanie Lu 		    "at loc %d ", location));
25684df55fdeSJanie Lu 		goto fail;
25694df55fdeSJanie Lu 	}
25704df55fdeSJanie Lu 
25714df55fdeSJanie Lu 	nxgep->classifier.tcam_entries[index].valid = 0;
25724df55fdeSJanie Lu 	nxgep->classifier.tcam_entry_cnt--;
25734df55fdeSJanie Lu 
25744df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
25754df55fdeSJanie Lu 	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_del_tcam_entry"));
25764df55fdeSJanie Lu 	return;
25774df55fdeSJanie Lu fail:
25784df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
25794df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25804df55fdeSJanie Lu 	    "<== nxge_del_tcam_entry FAILED"));
25814df55fdeSJanie Lu }
25824df55fdeSJanie Lu 
25834df55fdeSJanie Lu static uint8_t
nxge_iptun_pkt_type_to_pid(uint8_t pkt_type)25844df55fdeSJanie Lu nxge_iptun_pkt_type_to_pid(uint8_t pkt_type)
25854df55fdeSJanie Lu {
25864df55fdeSJanie Lu 	uint8_t pid = 0;
25874df55fdeSJanie Lu 
25884df55fdeSJanie Lu 	switch (pkt_type) {
25894df55fdeSJanie Lu 	case IPTUN_PKT_IPV4:
25904df55fdeSJanie Lu 		pid = 4;
25914df55fdeSJanie Lu 		break;
25924df55fdeSJanie Lu 	case IPTUN_PKT_IPV6:
25934df55fdeSJanie Lu 		pid = 41;
25944df55fdeSJanie Lu 		break;
25954df55fdeSJanie Lu 	case IPTUN_PKT_GRE:
25964df55fdeSJanie Lu 		pid = 47;
25974df55fdeSJanie Lu 		break;
25984df55fdeSJanie Lu 	case IPTUN_PKT_GTP:
25994df55fdeSJanie Lu 		pid = 17;
26004df55fdeSJanie Lu 		break;
26014df55fdeSJanie Lu 	default:
26024df55fdeSJanie Lu 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
26034df55fdeSJanie Lu 		    "nxge_iptun_pkt_type_to_pid: Unknown pkt type 0x%x",
26044df55fdeSJanie Lu 		    pkt_type));
26054df55fdeSJanie Lu 		break;
26064df55fdeSJanie Lu 	}
26074df55fdeSJanie Lu 
26084df55fdeSJanie Lu 	return (pid);
26094df55fdeSJanie Lu }
26104df55fdeSJanie Lu 
26114df55fdeSJanie Lu static npi_status_t
nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep,uint64_t class,iptun_cfg_t * iptunp)26124df55fdeSJanie Lu nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep, uint64_t class,
2613*86ef0a63SRichard Lowe     iptun_cfg_t *iptunp)
26144df55fdeSJanie Lu {
26154df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
26164df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
26174df55fdeSJanie Lu 
26184df55fdeSJanie Lu 	switch (iptunp->in_pkt_type) {
26194df55fdeSJanie Lu 	case IPTUN_PKT_IPV4:
26204df55fdeSJanie Lu 	case IPTUN_PKT_IPV6:
26214df55fdeSJanie Lu 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
26224df55fdeSJanie Lu 		    (tcam_class_t)class, 0, 0, 0, 0);
26234df55fdeSJanie Lu 		break;
26244df55fdeSJanie Lu 	case IPTUN_PKT_GRE:
26254df55fdeSJanie Lu 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
26264df55fdeSJanie Lu 		    (tcam_class_t)class, iptunp->l4b0_val,
26274df55fdeSJanie Lu 		    iptunp->l4b0_mask, 0, 0);
26284df55fdeSJanie Lu 		break;
26294df55fdeSJanie Lu 	case IPTUN_PKT_GTP:
26304df55fdeSJanie Lu 		rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
26314df55fdeSJanie Lu 		    (tcam_class_t)class, 0, 0, iptunp->l4b23_val,
26324df55fdeSJanie Lu 		    (iptunp->l4b23_sel & 0x01));
26334df55fdeSJanie Lu 		break;
26344df55fdeSJanie Lu 	default:
26354df55fdeSJanie Lu 		rs = NPI_FFLP_TCAM_CLASS_INVALID;
26364df55fdeSJanie Lu 		break;
26374df55fdeSJanie Lu 	}
26384df55fdeSJanie Lu 	return (rs);
26394df55fdeSJanie Lu }
26404df55fdeSJanie Lu 
26414df55fdeSJanie Lu void
nxge_add_iptun_class(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t * cls_idp)26424df55fdeSJanie Lu nxge_add_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp,
2643*86ef0a63SRichard Lowe     uint8_t *cls_idp)
26444df55fdeSJanie Lu {
26454df55fdeSJanie Lu 	int i, add_cls;
26464df55fdeSJanie Lu 	uint8_t pid;
26474df55fdeSJanie Lu 	uint64_t class;
26484df55fdeSJanie Lu 	p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
26494df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
26504df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
26514df55fdeSJanie Lu 
26524df55fdeSJanie Lu 	pid = nxge_iptun_pkt_type_to_pid(iptunp->in_pkt_type);
26534df55fdeSJanie Lu 	if (pid == 0)
26544df55fdeSJanie Lu 		return;
26554df55fdeSJanie Lu 
26564df55fdeSJanie Lu 	add_cls = 0;
26574df55fdeSJanie Lu 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
26584df55fdeSJanie Lu 
26594df55fdeSJanie Lu 	/* Get an user programmable class ID */
2660e3d11eeeSToomas Soome 	class = TCAM_CLASS_INVALID;
26614df55fdeSJanie Lu 	for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
26624df55fdeSJanie Lu 		if (hw_p->tcam_l3_prog_cls[i].valid == 0) {
26634df55fdeSJanie Lu 			/* todo add new usr class reg */
26644df55fdeSJanie Lu 			switch (i) {
26654df55fdeSJanie Lu 			case 0:
26664df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_4;
26674df55fdeSJanie Lu 				break;
26684df55fdeSJanie Lu 			case 1:
26694df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_5;
26704df55fdeSJanie Lu 				break;
26714df55fdeSJanie Lu 			case 2:
26724df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_6;
26734df55fdeSJanie Lu 				break;
26744df55fdeSJanie Lu 			case 3:
26754df55fdeSJanie Lu 				class = TCAM_CLASS_IP_USER_7;
26764df55fdeSJanie Lu 				break;
26774df55fdeSJanie Lu 			default:
26784df55fdeSJanie Lu 				break;
26794df55fdeSJanie Lu 			}
26804df55fdeSJanie Lu 			rs = npi_fflp_cfg_ip_usr_cls_set(handle,
26814df55fdeSJanie Lu 			    (tcam_class_t)class, 0, 0, pid, 0);
26824df55fdeSJanie Lu 			if (rs != NPI_SUCCESS)
26834df55fdeSJanie Lu 				goto fail;
26844df55fdeSJanie Lu 
26854df55fdeSJanie Lu 			rs = nxge_set_iptun_usr_cls_reg(nxgep, class, iptunp);
26864df55fdeSJanie Lu 
26874df55fdeSJanie Lu 			if (rs != NPI_SUCCESS)
26884df55fdeSJanie Lu 				goto fail;
26894df55fdeSJanie Lu 
26904df55fdeSJanie Lu 			rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
26914df55fdeSJanie Lu 			    (tcam_class_t)class);
26924df55fdeSJanie Lu 			if (rs != NPI_SUCCESS)
26934df55fdeSJanie Lu 				goto fail;
26944df55fdeSJanie Lu 
26954df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].cls = class;
26964df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].pid = pid;
26974df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
26984df55fdeSJanie Lu 			    iptunp->in_pkt_type;
26994df55fdeSJanie Lu 			hw_p->tcam_l3_prog_cls[i].valid = 1;
27004df55fdeSJanie Lu 			*cls_idp = (uint8_t)class;
27014df55fdeSJanie Lu 			add_cls = 1;
27024df55fdeSJanie Lu 			break;
27034df55fdeSJanie Lu 		} else if (hw_p->tcam_l3_prog_cls[i].pid == pid) {
27044df55fdeSJanie Lu 			if (hw_p->tcam_l3_prog_cls[i].flow_pkt_type == 0) {
27054df55fdeSJanie Lu 				/* there is no flow key */
27064df55fdeSJanie Lu 				/* todo program the existing usr class reg */
27074df55fdeSJanie Lu 
27084df55fdeSJanie Lu 				rs = nxge_set_iptun_usr_cls_reg(nxgep, class,
27094df55fdeSJanie Lu 				    iptunp);
27104df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
27114df55fdeSJanie Lu 					goto fail;
27124df55fdeSJanie Lu 
27134df55fdeSJanie Lu 				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
27144df55fdeSJanie Lu 				    (tcam_class_t)class);
27154df55fdeSJanie Lu 				if (rs != NPI_SUCCESS)
27164df55fdeSJanie Lu 					goto fail;
27174df55fdeSJanie Lu 
27184df55fdeSJanie Lu 				hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
27194df55fdeSJanie Lu 				    iptunp->in_pkt_type;
27204df55fdeSJanie Lu 				*cls_idp = (uint8_t)class;
27214df55fdeSJanie Lu 				add_cls = 1;
27224df55fdeSJanie Lu 			} else {
27234df55fdeSJanie Lu 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27244df55fdeSJanie Lu 				    "nxge_add_iptun_class: L3 usr "
27254df55fdeSJanie Lu 				    "programmable class with pid %d "
27264df55fdeSJanie Lu 				    "already exists", pid));
27274df55fdeSJanie Lu 			}
27284df55fdeSJanie Lu 			break;
27294df55fdeSJanie Lu 		}
27304df55fdeSJanie Lu 	}
27314df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
27324df55fdeSJanie Lu 
27334df55fdeSJanie Lu 	if (add_cls != 1) {
27344df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27354df55fdeSJanie Lu 		    "nxge_add_iptun_class: Could not add IP tunneling class"));
27364df55fdeSJanie Lu 	}
27374df55fdeSJanie Lu 	return;
27384df55fdeSJanie Lu fail:
27394df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
27404df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_iptun_class: FAILED"));
27414df55fdeSJanie Lu }
27424df55fdeSJanie Lu 
27434df55fdeSJanie Lu static boolean_t
nxge_is_iptun_cls_present(p_nxge_t nxgep,uint8_t cls_id,int * idx)27444df55fdeSJanie Lu nxge_is_iptun_cls_present(p_nxge_t nxgep, uint8_t cls_id, int *idx)
27454df55fdeSJanie Lu {
27464df55fdeSJanie Lu 	int i;
27474df55fdeSJanie Lu 	p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
27484df55fdeSJanie Lu 
27494df55fdeSJanie Lu 	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
27504df55fdeSJanie Lu 	for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
27514df55fdeSJanie Lu 		if (hw_p->tcam_l3_prog_cls[i].valid &&
27524df55fdeSJanie Lu 		    hw_p->tcam_l3_prog_cls[i].flow_pkt_type != 0) {
27534df55fdeSJanie Lu 			if (hw_p->tcam_l3_prog_cls[i].cls == cls_id)
27544df55fdeSJanie Lu 				break;
27554df55fdeSJanie Lu 		}
27564df55fdeSJanie Lu 	}
27574df55fdeSJanie Lu 	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
27584df55fdeSJanie Lu 
27594df55fdeSJanie Lu 	if (i == NXGE_L3_PROG_CLS) {
27604df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27614df55fdeSJanie Lu 		    "nxge_is_iptun_cls_present: Invalid class %d", cls_id));
27624df55fdeSJanie Lu 		return (B_FALSE);
27634df55fdeSJanie Lu 	} else {
27644df55fdeSJanie Lu 		*idx = i;
27654df55fdeSJanie Lu 		return (B_TRUE);
27664df55fdeSJanie Lu 	}
27674df55fdeSJanie Lu }
27684df55fdeSJanie Lu 
27694df55fdeSJanie Lu void
nxge_cfg_iptun_hash(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t cls_id)27704df55fdeSJanie Lu nxge_cfg_iptun_hash(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
27714df55fdeSJanie Lu {
27724df55fdeSJanie Lu 	int idx;
27734df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
27744df55fdeSJanie Lu 	flow_key_cfg_t cfg;
27754df55fdeSJanie Lu 
27764df55fdeSJanie Lu 	/* check to see that this is a valid class ID */
27774df55fdeSJanie Lu 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &idx)) {
27784df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27794df55fdeSJanie Lu 		    "nxge_cfg_iptun_hash: nxge_is_iptun_cls_present "
27804df55fdeSJanie Lu 		    "failed for cls_id %d", cls_id));
27814df55fdeSJanie Lu 		return;
27824df55fdeSJanie Lu 	}
27834df55fdeSJanie Lu 
27844df55fdeSJanie Lu 	bzero((void *)&cfg, sizeof (flow_key_cfg_t));
27854df55fdeSJanie Lu 
27864df55fdeSJanie Lu 	/*
27874df55fdeSJanie Lu 	 * This ensures that all 4 bytes of the XOR value are loaded to the
27884df55fdeSJanie Lu 	 * hash key.
27894df55fdeSJanie Lu 	 */
27904df55fdeSJanie Lu 	cfg.use_dport = cfg.use_sport = cfg.ip_opts_exist = 1;
27914df55fdeSJanie Lu 
27924df55fdeSJanie Lu 	cfg.l4_xor_sel = (iptunp->l4xor_sel & FL_KEY_USR_L4XOR_MSK);
27934df55fdeSJanie Lu 	cfg.use_l4_md = 1;
27944df55fdeSJanie Lu 
27954df55fdeSJanie Lu 	if (iptunp->hash_flags & HASH_L3PROTO)
27964df55fdeSJanie Lu 		cfg.use_proto = 1;
27974df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_IPDA)
27984df55fdeSJanie Lu 		cfg.use_daddr = 1;
27994df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_IPSA)
28004df55fdeSJanie Lu 		cfg.use_saddr = 1;
28014df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_VLAN)
28024df55fdeSJanie Lu 		cfg.use_vlan = 1;
28034df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_L2DA)
28044df55fdeSJanie Lu 		cfg.use_l2da = 1;
28054df55fdeSJanie Lu 	else if (iptunp->hash_flags & HASH_IFPORT)
28064df55fdeSJanie Lu 		cfg.use_portnum = 1;
28074df55fdeSJanie Lu 
28084df55fdeSJanie Lu 	(void) npi_fflp_cfg_ip_cls_flow_key_rfnl(handle, (tcam_class_t)cls_id,
28094df55fdeSJanie Lu 	    &cfg);
28104df55fdeSJanie Lu }
28114df55fdeSJanie Lu 
28124df55fdeSJanie Lu void
nxge_del_iptun_class(p_nxge_t nxgep,uint8_t cls_id)28134df55fdeSJanie Lu nxge_del_iptun_class(p_nxge_t nxgep, uint8_t cls_id)
28144df55fdeSJanie Lu {
28154df55fdeSJanie Lu 	int i;
28164df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
28174df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
28184df55fdeSJanie Lu 
28194df55fdeSJanie Lu 
28204df55fdeSJanie Lu 	/* check to see that this is a valid class ID */
28214df55fdeSJanie Lu 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) {
28224df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
28234df55fdeSJanie Lu 		    "nxge_del_iptun_class: Invalid class ID 0x%x", cls_id));
28244df55fdeSJanie Lu 		return;
28254df55fdeSJanie Lu 	}
28264df55fdeSJanie Lu 
28274df55fdeSJanie Lu 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
28284df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_usr_cls_disable(handle, (tcam_class_t)cls_id);
28294df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
28304df55fdeSJanie Lu 		goto fail;
28314df55fdeSJanie Lu 	nxgep->nxge_hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 0;
28324df55fdeSJanie Lu 	if (nxgep->nxge_hw_p->tcam_l3_prog_cls[i].tcam_ref_cnt == 0)
28334df55fdeSJanie Lu 		nxgep->nxge_hw_p->tcam_l3_prog_cls[i].valid = 0;
28344df55fdeSJanie Lu 
28354df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
28364df55fdeSJanie Lu 	return;
28374df55fdeSJanie Lu fail:
28384df55fdeSJanie Lu 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
28394df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_iptun_class: FAILED"));
28404df55fdeSJanie Lu }
28414df55fdeSJanie Lu 
28424df55fdeSJanie Lu void
nxge_get_iptun_class(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t cls_id)28434df55fdeSJanie Lu nxge_get_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
28444df55fdeSJanie Lu {
28454df55fdeSJanie Lu 	int i;
28464df55fdeSJanie Lu 	uint8_t pid;
28474df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
28484df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
28494df55fdeSJanie Lu 	flow_key_cfg_t cfg;
2850e3d11eeeSToomas Soome 	uint8_t l4b0_val;
2851e3d11eeeSToomas Soome 	uint8_t l4b0_mask;
2852e3d11eeeSToomas Soome 	uint8_t l4b23_sel;
2853e3d11eeeSToomas Soome 	uint16_t l4b23_val;
28544df55fdeSJanie Lu 
28554df55fdeSJanie Lu 	/* check to see that this is a valid class ID */
28564df55fdeSJanie Lu 	if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i))
28574df55fdeSJanie Lu 		return;
28584df55fdeSJanie Lu 
28594df55fdeSJanie Lu 	bzero((void *)iptunp, sizeof (iptun_cfg_t));
28604df55fdeSJanie Lu 
28614df55fdeSJanie Lu 	pid = nxgep->nxge_hw_p->tcam_l3_prog_cls[i].pid;
28624df55fdeSJanie Lu 
28634df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_usr_cls_get_iptun(handle, (tcam_class_t)cls_id,
2864e3d11eeeSToomas Soome 	    &l4b0_val, &l4b0_mask, &l4b23_val, &l4b23_sel);
2865e3d11eeeSToomas Soome 	if (rs != NPI_SUCCESS)
2866e3d11eeeSToomas Soome 		goto fail;
2867e3d11eeeSToomas Soome 
2868e3d11eeeSToomas Soome 	iptunp->l4b0_val = l4b0_val;
2869e3d11eeeSToomas Soome 	iptunp->l4b0_mask = l4b0_mask;
2870e3d11eeeSToomas Soome 	iptunp->l4b23_val = l4b23_val;
2871e3d11eeeSToomas Soome 	iptunp->l4b23_sel = l4b23_sel;
2872e3d11eeeSToomas Soome 
28734df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
28744df55fdeSJanie Lu 		goto fail;
28754df55fdeSJanie Lu 
28764df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
28774df55fdeSJanie Lu 	    (tcam_class_t)cls_id, &cfg);
28784df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
28794df55fdeSJanie Lu 		goto fail;
28804df55fdeSJanie Lu 
28814df55fdeSJanie Lu 	iptunp->l4xor_sel = cfg.l4_xor_sel;
28824df55fdeSJanie Lu 	if (cfg.use_proto)
28834df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_L3PROTO;
28844df55fdeSJanie Lu 	else if (cfg.use_daddr)
28854df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_IPDA;
28864df55fdeSJanie Lu 	else if (cfg.use_saddr)
28874df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_IPSA;
28884df55fdeSJanie Lu 	else if (cfg.use_vlan)
28894df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_VLAN;
28904df55fdeSJanie Lu 	else if (cfg.use_l2da)
28914df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_L2DA;
28924df55fdeSJanie Lu 	else if (cfg.use_portnum)
28934df55fdeSJanie Lu 		iptunp->hash_flags |= HASH_IFPORT;
28944df55fdeSJanie Lu 
28954df55fdeSJanie Lu 	switch (pid) {
28964df55fdeSJanie Lu 	case 4:
28974df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_IPV4;
28984df55fdeSJanie Lu 		break;
28994df55fdeSJanie Lu 	case 41:
29004df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_IPV6;
29014df55fdeSJanie Lu 		break;
29024df55fdeSJanie Lu 	case 47:
29034df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_GRE;
29044df55fdeSJanie Lu 		break;
29054df55fdeSJanie Lu 	case 17:
29064df55fdeSJanie Lu 		iptunp->in_pkt_type = IPTUN_PKT_GTP;
29074df55fdeSJanie Lu 		break;
29084df55fdeSJanie Lu 	default:
29094df55fdeSJanie Lu 		iptunp->in_pkt_type = 0;
29104df55fdeSJanie Lu 		break;
29114df55fdeSJanie Lu 	}
29124df55fdeSJanie Lu 
29134df55fdeSJanie Lu 	return;
29144df55fdeSJanie Lu fail:
29154df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_iptun_class: FAILED"));
29164df55fdeSJanie Lu }
29174df55fdeSJanie Lu 
29184df55fdeSJanie Lu void
nxge_set_ip_cls_sym(p_nxge_t nxgep,uint8_t cls_id,uint8_t sym)29194df55fdeSJanie Lu nxge_set_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t sym)
29204df55fdeSJanie Lu {
29214df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
29224df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
29234df55fdeSJanie Lu 	boolean_t sym_en = (sym == 1) ? B_TRUE : B_FALSE;
29244df55fdeSJanie Lu 
29254df55fdeSJanie Lu 	rs = npi_fflp_cfg_sym_ip_cls_flow_key(handle, (tcam_class_t)cls_id,
29264df55fdeSJanie Lu 	    sym_en);
29274df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
29284df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
29294df55fdeSJanie Lu 		    "nxge_set_ip_cls_sym: FAILED"));
29304df55fdeSJanie Lu }
29314df55fdeSJanie Lu 
29324df55fdeSJanie Lu void
nxge_get_ip_cls_sym(p_nxge_t nxgep,uint8_t cls_id,uint8_t * sym)29334df55fdeSJanie Lu nxge_get_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t *sym)
29344df55fdeSJanie Lu {
29354df55fdeSJanie Lu 	npi_handle_t handle = nxgep->npi_reg_handle;
29364df55fdeSJanie Lu 	npi_status_t rs = NPI_SUCCESS;
29374df55fdeSJanie Lu 	flow_key_cfg_t cfg;
29384df55fdeSJanie Lu 
29394df55fdeSJanie Lu 	rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
29404df55fdeSJanie Lu 	    (tcam_class_t)cls_id, &cfg);
29414df55fdeSJanie Lu 	if (rs != NPI_SUCCESS)
29424df55fdeSJanie Lu 		goto fail;
29434df55fdeSJanie Lu 
29444df55fdeSJanie Lu 	if (cfg.use_sym)
29454df55fdeSJanie Lu 		*sym = 1;
29464df55fdeSJanie Lu 	else
29474df55fdeSJanie Lu 		*sym = 0;
29484df55fdeSJanie Lu 	return;
29494df55fdeSJanie Lu fail:
29504df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_ip_cls_sym: FAILED"));
29514df55fdeSJanie Lu }
2952