14496171girish/*
24496171girish * CDDL HEADER START
34496171girish *
44496171girish * The contents of this file are subject to the terms of the
54496171girish * Common Development and Distribution License (the "License").
64496171girish * You may not use this file except in compliance with the License.
74496171girish *
84496171girish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94496171girish * or http://www.opensolaris.org/os/licensing.
104496171girish * See the License for the specific language governing permissions
114496171girish * and limitations under the License.
124496171girish *
134496171girish * When distributing Covered Code, include this CDDL HEADER in each
144496171girish * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154496171girish * If applicable, add the following below this CDDL HEADER, with the
164496171girish * fields enclosed by brackets "[]" replaced with your own identifying
174496171girish * information: Portions Copyright [yyyy] [name of copyright owner]
184496171girish *
194496171girish * CDDL HEADER END
204496171girish */
210dc2366Venugopal Iyer
224496171girish/*
230dc2366Venugopal Iyer * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
244496171girish * Use is subject to license terms.
254496171girish */
264496171girish
274496171girish#include <npi_fflp.h>
284496171girish#include <npi_mac.h>
294496171girish#include <nxge_defs.h>
304496171girish#include <nxge_flow.h>
314496171girish#include <nxge_fflp.h>
324496171girish#include <nxge_impl.h>
334496171girish#include <nxge_fflp_hash.h>
344496171girish#include <nxge_common.h>
354496171girish
364496171girish
37a3c5bd6speer/*
38a3c5bd6speer * Function prototypes
39a3c5bd6speer */
404496171girishstatic nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t);
414496171girishstatic nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t);
424496171girishstatic nxge_status_t nxge_fflp_tcam_init(p_nxge_t);
434496171girishstatic nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t);
444496171girishstatic nxge_status_t nxge_fflp_fcram_init(p_nxge_t);
454496171girishstatic int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *);
46a3c5bd6speerstatic void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
47a3c5bd6speerstatic void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
48a3c5bd6speerstatic void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
494496171girishstatic void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *,
50a3c5bd6speer	tcam_entry_t *);
51a3c5bd6speerstatic void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *,
52a3c5bd6speer	tcam_entry_t *);
53a3c5bd6speerstatic void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *,
54a3c5bd6speer	tcam_entry_t *);
554df55fdJanie Lustatic uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t);
564df55fdJanie Lustatic uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t);
574df55fdJanie Lustatic uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t);
584df55fdJanie Lustatic uint32_t nxge_tcam_cls_to_flow(uint32_t);
594df55fdJanie Lustatic uint8_t nxge_iptun_pkt_type_to_pid(uint8_t);
604df55fdJanie Lustatic npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t,
614df55fdJanie Lu					iptun_cfg_t *);
624df55fdJanie Lustatic boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *);
634496171girish
64a3c5bd6speer/*
65a3c5bd6speer * functions used outside this file
66a3c5bd6speer */
674496171girishnxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t);
684496171girishnxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t);
694496171girishnxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *);
7014ea4bbsdstatic nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t);
714496171girishnxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *);
724496171girishnxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *);
734496171girishnxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *,
74a3c5bd6speer	uint32_t *, uint16_t *);
754df55fdJanie Luint nxge_get_valid_tcam_cnt(p_nxge_t);
764df55fdJanie Luvoid nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *);
774df55fdJanie Luvoid nxge_get_tcam_entry(p_nxge_t, flow_resource_t *);
784df55fdJanie Luvoid nxge_del_tcam_entry(p_nxge_t, uint32_t);
794df55fdJanie Luvoid nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *);
804df55fdJanie Luvoid nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t);
814df55fdJanie Luvoid nxge_del_iptun_class(p_nxge_t, uint8_t);
824df55fdJanie Luvoid nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t);
834df55fdJanie Luvoid nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t);
844df55fdJanie Luvoid nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *);
854df55fdJanie Lu
864496171girish
874496171girishnxge_status_t
884496171girishnxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location)
894496171girish{
904496171girish	tcam_entry_t tcam_rdptr;
914496171girish	uint64_t asc_ram = 0;
924496171girish	npi_handle_t handle;
934496171girish	npi_status_t status;
944496171girish
954496171girish	handle = nxgep->npi_reg_handle;
964496171girish
974496171girish	bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry));
984496171girish	status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location,
9952ccf84misaki	    (struct tcam_entry *)&tcam_rdptr);
1004496171girish	if (status & NPI_FAILURE) {
1014496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
10252ccf84misaki		    " nxge_tcam_dump_entry:"
10352ccf84misaki		    "  tcam read failed at location %d ", location));
1044496171girish		return (NXGE_ERROR);
1054496171girish	}
1064496171girish	status = npi_fflp_tcam_asc_ram_entry_read(handle,
10752ccf84misaki	    (tcam_location_t)location, &asc_ram);
1084496171girish
1094496171girish	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n"
11052ccf84misaki	    " key:  %llx %llx %llx %llx \n"
11152ccf84misaki	    " mask: %llx %llx %llx %llx \n"
11252ccf84misaki	    " ASC RAM %llx \n", location,
11352ccf84misaki	    tcam_rdptr.key0, tcam_rdptr.key1,
11452ccf84misaki	    tcam_rdptr.key2, tcam_rdptr.key3,
11552ccf84misaki	    tcam_rdptr.mask0, tcam_rdptr.mask1,
11652ccf84misaki	    tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram));
1174496171girish	return (NXGE_OK);
1184496171girish}
1194496171girish
1204496171girishvoid
1214496171girishnxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp)
1224496171girish{
1234496171girish	uint32_t tcam_loc;
1244496171girish	int *lptr;
1254496171girish	int location;
1264496171girish
1274496171girish	uint32_t start_location = 0;
1284496171girish	uint32_t stop_location = nxgep->classifier.tcam_size;
1294496171girish	lptr = (int *)mp->b_rptr;
1304496171girish	location = *lptr;
1314496171girish
1324496171girish	if ((location >= nxgep->classifier.tcam_size) || (location < -1)) {
1334496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
13452ccf84misaki		    "nxge_tcam_dump: Invalid location %d \n", location));
1354496171girish		return;
1364496171girish	}
1374496171girish	if (location == -1) {
1384496171girish		start_location = 0;
1394496171girish		stop_location = nxgep->classifier.tcam_size;
1404496171girish	} else {
1414496171girish		start_location = location;
142a3c5bd6speer		stop_location = location + 1;
1434496171girish	}
1444496171girish	for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++)
1454496171girish		(void) nxge_tcam_dump_entry(nxgep, tcam_loc);
1464496171girish}
1474496171girish
1484496171girish/*
1494496171girish * nxge_fflp_vlan_table_invalidate_all
1504496171girish * invalidates the vlan RDC table entries.
1514496171girish * INPUT
1524496171girish * nxge    soft state data structure
1534496171girish * Return
1544496171girish *      NXGE_OK
1554496171girish *      NXGE_ERROR
1564496171girish *
1574496171girish */
158a3c5bd6speer
1594496171girishstatic nxge_status_t
1604496171girishnxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)
1614496171girish{
1624496171girish	vlan_id_t vlan_id;
1634496171girish	npi_handle_t handle;
1644496171girish	npi_status_t rs = NPI_SUCCESS;
1654496171girish	vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
1664496171girish
1674496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all "));
1684496171girish	handle = nxgep->npi_reg_handle;
1694496171girish	for (vlan_id = start; vlan_id < stop; vlan_id++) {
1704496171girish		rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id);
1714496171girish		if (rs != NPI_SUCCESS) {
1724496171girish			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17352ccf84misaki			    "VLAN Table invalidate failed for vlan id %d ",
17452ccf84misaki			    vlan_id));
1754496171girish			return (NXGE_ERROR | rs);
1764496171girish		}
1774496171girish	}
1784496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all "));
1794496171girish	return (NXGE_OK);
1804496171girish}
1814496171girish
1824496171girish/*
1834496171girish * The following functions are used by other modules to init
1844496171girish * the fflp module.
1854496171girish * these functions are the basic API used to init
1864496171girish * the fflp modules (tcam, fcram etc ......)
1874496171girish *
1884496171girish * The TCAM search future would be disabled  by default.
1894496171girish */
1904496171girish
1914496171girishstatic nxge_status_t
1924496171girishnxge_fflp_tcam_init(p_nxge_t nxgep)
1934496171girish{
1944496171girish	uint8_t access_ratio;
1954496171girish	tcam_class_t class;
1964496171girish	npi_status_t rs = NPI_SUCCESS;
1974496171girish	npi_handle_t handle;
1984496171girish
1994496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init"));
2004496171girish	handle = nxgep->npi_reg_handle;
2014496171girish
2024496171girish	rs = npi_fflp_cfg_tcam_disable(handle);
2034496171girish	if (rs != NPI_SUCCESS) {
2044496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n"));
2054496171girish		return (NXGE_ERROR | rs);
2064496171girish	}
2074496171girish
2084496171girish	access_ratio = nxgep->param_arr[param_tcam_access_ratio].value;
2094496171girish	rs = npi_fflp_cfg_tcam_access(handle, access_ratio);
2104496171girish	if (rs != NPI_SUCCESS) {
2114496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21252ccf84misaki		    "failed TCAM Access cfg\n"));
2134496171girish		return (NXGE_ERROR | rs);
2144496171girish	}
2154496171girish
216a3c5bd6speer	/* disable configurable classes */
217a3c5bd6speer	/* disable the configurable ethernet classes; */
2184496171girish	for (class = TCAM_CLASS_ETYPE_1;
21952ccf84misaki	    class <= TCAM_CLASS_ETYPE_2; class++) {
2204496171girish		rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class);
2214496171girish		if (rs != NPI_SUCCESS) {
2224496171girish			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
22352ccf84misaki			    "TCAM USR Ether Class config failed."));
2244496171girish			return (NXGE_ERROR | rs);
2254496171girish		}
2264496171girish	}
2274496171girish
228a3c5bd6speer	/* disable the configurable ip classes; */
2294496171girish	for (class = TCAM_CLASS_IP_USER_4;
23052ccf84misaki	    class <= TCAM_CLASS_IP_USER_7; class++) {
2314496171girish		rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
2324496171girish		if (rs != NPI_SUCCESS) {
2334496171girish			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
23452ccf84misaki			    "TCAM USR IP Class cnfg failed."));
2354496171girish			return (NXGE_ERROR | rs);
2364496171girish		}
2374496171girish	}
2384496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init"));
2394496171girish	return (NXGE_OK);
2404496171girish}
2414496171girish
2424496171girish/*
2434496171girish * nxge_fflp_tcam_invalidate_all
2444496171girish * invalidates all the tcam entries.
2454496171girish * INPUT
2464496171girish * nxge    soft state data structure
2474496171girish * Return
2484496171girish *      NXGE_OK
2494496171girish *      NXGE_ERROR
2504496171girish *
2514496171girish */
252a3c5bd6speer
253a3c5bd6speer
2544496171girishstatic nxge_status_t
2554496171girishnxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)
2564496171girish{
2574496171girish	uint16_t location;
2584496171girish	npi_status_t rs = NPI_SUCCESS;
2594496171girish	npi_handle_t handle;
2604496171girish	uint16_t start = 0, stop = nxgep->classifier.tcam_size;
261a3c5bd6speer	p_nxge_hw_list_t hw_p;
2624496171girish
2634496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
26452ccf84misaki	    "==> nxge_fflp_tcam_invalidate_all"));
2654496171girish	handle = nxgep->npi_reg_handle;
2664496171girish	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
2674496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
26852ccf84misaki		    " nxge_fflp_tcam_invalidate_all:"
26952ccf84misaki		    " common hardware not set", nxgep->niu_type));
2704496171girish		return (NXGE_ERROR);
2714496171girish	}
2724496171girish	MUTEX_ENTER(&hw_p->nxge_tcam_lock);
2734496171girish	for (location = start; location < stop; location++) {
2744496171girish		rs = npi_fflp_tcam_entry_invalidate(handle, location);
2754496171girish		if (rs != NPI_SUCCESS) {
2764496171girish			MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2774496171girish			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27852ccf84misaki			    "TCAM invalidate failed at loc %d ", location));
2794496171girish			return (NXGE_ERROR | rs);
2804496171girish		}
2814496171girish	}
2824496171girish	MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2834496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
28452ccf84misaki	    "<== nxge_fflp_tcam_invalidate_all"));
2854496171girish	return (NXGE_OK);
2864496171girish}
2874496171girish
2884496171girish/*
2894496171girish * nxge_fflp_fcram_entry_invalidate_all
2904496171girish * invalidates all the FCRAM entries.
2914496171girish * INPUT
2924496171girish * nxge    soft state data structure
2934496171girish * Return
2944496171girish *      NXGE_OK
2954496171girish *      NXGE_ERROR
2964496171girish *
2974496171girish */
298a3c5bd6speer
2994496171girishstatic nxge_status_t
3004496171girishnxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)
3014496171girish{
302a3c5bd6speer	npi_handle_t handle;
303a3c5bd6speer	npi_status_t rs = NPI_SUCCESS;
304a3c5bd6speer	part_id_t pid = 0;
305a3c5bd6speer	uint8_t base_mask, base_reloc;
306a3c5bd6speer	fcram_entry_t fc;
307a3c5bd6speer	uint32_t location;
308a3c5bd6speer	uint32_t increment, last_location;
3094496171girish
310a3c5bd6speer	/*
311a3c5bd6speer	 * (1) configure and enable partition 0 with no relocation
312a3c5bd6speer	 * (2) Assume the FCRAM is used as IPv4 exact match entry cells
313a3c5bd6speer	 * (3) Invalidate these cells by clearing the valid bit in
314a3c5bd6speer	 * the subareas 0 and 4
315a3c5bd6speer	 * (4) disable the partition
316a3c5bd6speer	 *
317a3c5bd6speer	 */
3184496171girish
3194496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all"));
3204496171girish
3214496171girish	base_mask = base_reloc = 0x0;
3224496171girish	handle = nxgep->npi_reg_handle;
323a3c5bd6speer	rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc);
3244496171girish
3254496171girish	if (rs != NPI_SUCCESS) {
326a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n"));
3274496171girish		return (NXGE_ERROR | rs);
3284496171girish	}
329a3c5bd6speer	rs = npi_fflp_cfg_fcram_partition_disable(handle, pid);
3304496171girish
3314496171girish	if (rs != NPI_SUCCESS) {
3324496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
33352ccf84misaki		    "failed partition enable\n"));
3344496171girish		return (NXGE_ERROR | rs);
3354496171girish	}
336a3c5bd6speer	fc.dreg[0].value = 0;
337a3c5bd6speer	fc.hash_hdr_valid = 0;
338a3c5bd6speer	fc.hash_hdr_ext = 1;	/* specify as IPV4 exact match entry */
339a3c5bd6speer	increment = sizeof (hash_ipv4_t);
340a3c5bd6speer	last_location = FCRAM_SIZE * 0x40;
3414496171girish
342a3c5bd6speer	for (location = 0; location < last_location; location += increment) {
3434496171girish		rs = npi_fflp_fcram_subarea_write(handle, pid,
34452ccf84misaki		    location, fc.value[0]);
3454496171girish		if (rs != NPI_SUCCESS) {
3464496171girish			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
34752ccf84misaki			    "failed write at location %x ", location));
3484496171girish			return (NXGE_ERROR | rs);
3494496171girish		}
3504496171girish	}
3514496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all"));
352a3c5bd6speer	return (NXGE_OK);
3534496171girish}
3544496171girish
3554496171girishstatic nxge_status_t
3564496171girishnxge_fflp_fcram_init(p_nxge_t nxgep)
3574496171girish{
3584496171girish	fflp_fcram_output_drive_t strength;
3594496171girish	fflp_fcram_qs_t qs;
3604496171girish	npi_status_t rs = NPI_SUCCESS;
3614496171girish	uint8_t access_ratio;
362a3c5bd6speer	int partition;
3634496171girish	npi_handle_t handle;
364a3c5bd6speer	uint32_t min_time, max_time, sys_time;
3654496171girish
3664496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init"));
3674496171girish
368a3c5bd6speer	/*
369a3c5bd6speer	 * Recommended values are needed.
370a3c5bd6speer	 */
3714496171girish	min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME;
3724496171girish	max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME;
3734496171girish	sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME;
374a3c5bd6speer
3754496171girish	handle = nxgep->npi_reg_handle;
3764496171girish	strength = FCRAM_OUTDR_NORMAL;
3774496171girish	qs = FCRAM_QS_MODE_QS;
3784496171girish	rs = npi_fflp_cfg_fcram_reset(handle, strength, qs);
3794496171girish	if (rs != NPI_SUCCESS) {
3804496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. "));
3814496171girish		return (NXGE_ERROR | rs);
3824496171girish	}
3834496171girish
384a3c5bd6speer	access_ratio = nxgep->param_arr[param_fcram_access_ratio].value;
385a3c5bd6speer	rs = npi_fflp_cfg_fcram_access(handle, access_ratio);
386a3c5bd6speer	if (rs != NPI_SUCCESS) {
3874496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio"
38852ccf84misaki		    "configuration \n"));
3894496171girish		return (NXGE_ERROR | rs);
3904496171girish	}
3914496171girish	rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time,
39252ccf84misaki	    max_time, sys_time);
3934496171girish	if (rs != NPI_SUCCESS) {
3944496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
39552ccf84misaki		    "failed FCRAM refresh cfg"));
3964496171girish		return (NXGE_ERROR);
3974496171girish	}
3984496171girish
3994496171girish	/* disable all the partitions until explicitly enabled */
4004496171girish	for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) {
401a3c5bd6speer		rs = npi_fflp_cfg_fcram_partition_disable(handle, partition);
4024496171girish		if (rs != NPI_SUCCESS) {
4034496171girish			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
40452ccf84misaki			    "failed FCRAM partition"
40552ccf84misaki			    " enable for partition %d ", partition));
4064496171girish			return (NXGE_ERROR | rs);
4074496171girish		}
4084496171girish	}
4094496171girish
4104496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init"));
411a3c5bd6speer	return (NXGE_OK);
4124496171girish}
4134496171girish
4144496171girishnxge_status_t
4154496171girishnxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac)
4164496171girish{
4174496171girish	npi_status_t rs = NPI_SUCCESS;
4184496171girish	hostinfo_t mac_rdc;
4194496171girish	npi_handle_t handle;
420a3c5bd6speer	p_nxge_class_pt_cfg_t p_class_cfgp;
4214496171girish
422a3c5bd6speer	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
4234496171girish	if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) {
424a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
42552ccf84misaki		    " nxge_logical_mac_assign_rdc_table"
42652ccf84misaki		    " unconfigured alt MAC addr %d ", alt_mac));
4274496171girish		return (NXGE_ERROR);
4284496171girish	}
4294496171girish	handle = nxgep->npi_reg_handle;
4304496171girish	mac_rdc.value = 0;
4314496171girish	mac_rdc.bits.w0.rdc_tbl_num =
43252ccf84misaki	    p_class_cfgp->mac_host_info[alt_mac].rdctbl;
4334496171girish	mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr;
4344496171girish
4354496171girish	rs = npi_mac_hostinfo_entry(handle, OP_SET,
43652ccf84misaki	    nxgep->function_num, alt_mac, &mac_rdc);
4374496171girish
4384496171girish	if (rs != NPI_SUCCESS) {
4394496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44052ccf84misaki		    "failed Assign RDC table"));
4414496171girish		return (NXGE_ERROR | rs);
4424496171girish	}
4434496171girish	return (NXGE_OK);
4444496171girish}
4454496171girish
4464496171girishnxge_status_t
4474496171girishnxge_main_mac_assign_rdc_table(p_nxge_t nxgep)
4484496171girish{
4494496171girish	npi_status_t rs = NPI_SUCCESS;
4504496171girish	hostinfo_t mac_rdc;
4514496171girish	npi_handle_t handle;
4520dc2366Venugopal Iyer	int i;
4534496171girish
4544496171girish	handle = nxgep->npi_reg_handle;
4554496171girish	mac_rdc.value = 0;
4564496171girish	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp;
4574496171girish	mac_rdc.bits.w0.mac_pref = 1;
4584496171girish	switch (nxgep->function_num) {
459a3c5bd6speer	case 0:
460a3c5bd6speer	case 1:
4610dc2366Venugopal Iyer		/*
4620dc2366Venugopal Iyer		 * Tests indicate that it is OK not to re-initialize the
4630dc2366Venugopal Iyer		 * hostinfo registers for the XMAC's alternate MAC
4640dc2366Venugopal Iyer		 * addresses. But that is necessary for BMAC (case 2
4650dc2366Venugopal Iyer		 * and case 3 below)
4660dc2366Venugopal Iyer		 */
467a3c5bd6speer		rs = npi_mac_hostinfo_entry(handle, OP_SET,
46852ccf84misaki		    nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
469a3c5bd6speer		break;
470a3c5bd6speer	case 2:
471a3c5bd6speer	case 3:
472a3c5bd6speer		rs = npi_mac_hostinfo_entry(handle, OP_SET,
47352ccf84misaki		    nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
4740dc2366Venugopal Iyer		for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
4750dc2366Venugopal Iyer			rs |= npi_mac_hostinfo_entry(handle, OP_SET,
4760dc2366Venugopal Iyer			    nxgep->function_num, i, &mac_rdc);
477a3c5bd6speer		break;
478a3c5bd6speer	default:
479a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
48052ccf84misaki		    "failed Assign RDC table (invalid function #)"));
481a3c5bd6speer		return (NXGE_ERROR);
4824496171girish	}
4834496171girish
4844496171girish	if (rs != NPI_SUCCESS) {
4854496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
48652ccf84misaki		    "failed Assign RDC table"));
4874496171girish		return (NXGE_ERROR | rs);
4884496171girish	}
4894496171girish	return (NXGE_OK);
4904496171girish}
4914496171girish
49258324dfspeer/*
49358324dfspeer * Initialize hostinfo registers for alternate MAC addresses and
49458324dfspeer * multicast MAC address.
49558324dfspeer */
4964496171girishnxge_status_t
49758324dfspeernxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)
4984496171girish{
4994496171girish	npi_status_t rs = NPI_SUCCESS;
5004496171girish	hostinfo_t mac_rdc;
5014496171girish	npi_handle_t handle;
5024496171girish
5034496171girish	handle = nxgep->npi_reg_handle;
5044496171girish	mac_rdc.value = 0;
5054496171girish	mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp;
5064496171girish	mac_rdc.bits.w0.mac_pref = 1;
5074496171girish	switch (nxgep->function_num) {
508a3c5bd6speer	case 0:
509a3c5bd6speer	case 1:
510a3c5bd6speer		rs = npi_mac_hostinfo_entry(handle, OP_SET,
5110dc2366Venugopal Iyer		    nxgep->function_num, XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
512a3c5bd6speer		break;
513a3c5bd6speer	case 2:
514a3c5bd6speer	case 3:
5150dc2366Venugopal Iyer		rs = npi_mac_hostinfo_entry(handle, OP_SET,
5160dc2366Venugopal Iyer		    nxgep->function_num, BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
517a3c5bd6speer		break;
518a3c5bd6speer	default:
519a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52052ccf84misaki		    "failed Assign RDC table (invalid function #)"));
521a3c5bd6speer		return (NXGE_ERROR);
5224496171girish	}
5234496171girish
5244496171girish	if (rs != NPI_SUCCESS) {
5254496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52652ccf84misaki		    "failed Assign RDC table"));
5274496171girish		return (NXGE_ERROR | rs);
5284496171girish	}
5294496171girish	return (NXGE_OK);
5304496171girish}
5314496171girish
5324496171girishnxge_status_t
5334496171girishnxge_fflp_init_hostinfo(p_nxge_t nxgep)
5344496171girish{
5354496171girish	nxge_status_t status = NXGE_OK;
536a3c5bd6speer
53758324dfspeer	status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
53858324dfspeer	status |= nxge_main_mac_assign_rdc_table(nxgep);
5394496171girish	return (status);
5404496171girish}
5414496171girish
5424496171girishnxge_status_t
5434496171girishnxge_fflp_hw_reset(p_nxge_t nxgep)
5444496171girish{
5454496171girish	npi_handle_t handle;
5464496171girish	npi_status_t rs = NPI_SUCCESS;
5474496171girish	nxge_status_t status = NXGE_OK;
5484496171girish
5494496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
5504496171girish
5512e59129raghus	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
5524496171girish		status = nxge_fflp_fcram_init(nxgep);
553a3c5bd6speer		if (status != NXGE_OK) {
5544496171girish			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55552ccf84misaki			    " failed FCRAM init. "));
5564496171girish			return (status);
5574496171girish		}
5584496171girish	}
5594496171girish
5604496171girish	status = nxge_fflp_tcam_init(nxgep);
5614496171girish	if (status != NXGE_OK) {
562a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
56352ccf84misaki		    "failed TCAM init."));
564a3c5bd6speer		return (status);
5654496171girish	}
5664496171girish
5674496171girish	handle = nxgep->npi_reg_handle;
5684496171girish	rs = npi_fflp_cfg_llcsnap_enable(handle);
5694496171girish	if (rs != NPI_SUCCESS) {
570a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
57152ccf84misaki		    "failed LLCSNAP enable. "));
572a3c5bd6speer		return (NXGE_ERROR | rs);
5734496171girish	}
5744496171girish
5754496171girish	rs = npi_fflp_cfg_cam_errorcheck_disable(handle);
5764496171girish	if (rs != NPI_SUCCESS) {
5774496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
57852ccf84misaki		    "failed CAM Error Check enable. "));
5794496171girish		return (NXGE_ERROR | rs);
5804496171girish	}
5814496171girish
582a3c5bd6speer	/* init the hash generators */
5834496171girish	rs = npi_fflp_cfg_hash_h1poly(handle, 0);
5844496171girish	if (rs != NPI_SUCCESS) {
585a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
58652ccf84misaki		    "failed H1 Poly Init. "));
587a3c5bd6speer		return (NXGE_ERROR | rs);
5884496171girish	}
5894496171girish
5904496171girish	rs = npi_fflp_cfg_hash_h2poly(handle, 0);
5914496171girish	if (rs != NPI_SUCCESS) {
592a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
59352ccf84misaki		    "failed H2 Poly Init. "));
594a3c5bd6speer		return (NXGE_ERROR | rs);
5954496171girish	}
5964496171girish
597a3c5bd6speer	/* invalidate TCAM entries */
5984496171girish	status = nxge_fflp_tcam_invalidate_all(nxgep);
5994496171girish	if (status != NXGE_OK) {
6004496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
60152ccf84misaki		    "failed TCAM Entry Invalidate. "));
6024496171girish		return (status);
6034496171girish	}
6044496171girish
605a3c5bd6speer	/* invalidate FCRAM entries */
6062e59129raghus	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6074496171girish		status = nxge_fflp_fcram_invalidate_all(nxgep);
6084496171girish		if (status != NXGE_OK) {
6094496171girish			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
61052ccf84misaki			    "failed FCRAM Entry Invalidate."));
6114496171girish			return (status);
6124496171girish		}
6134496171girish	}
6144496171girish
615a3c5bd6speer	/* invalidate VLAN RDC tables */
6164496171girish	status = nxge_fflp_vlan_tbl_clear_all(nxgep);
6174496171girish	if (status != NXGE_OK) {
6184496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
61952ccf84misaki		    "failed VLAN Table Invalidate. "));
6204496171girish		return (status);
6214496171girish	}
6224496171girish	nxgep->classifier.state |= NXGE_FFLP_HW_RESET;
6234496171girish
6244496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset"));
6254496171girish	return (NXGE_OK);
6264496171girish}
6274496171girish
6284496171girishnxge_status_t
6294496171girishnxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class,
630a3c5bd6speer	uint32_t class_config)
6314496171girish{
6324496171girish	flow_key_cfg_t fcfg;
6334496171girish	npi_handle_t handle;
6344496171girish	npi_status_t rs = NPI_SUCCESS;
6354496171girish
6364496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key"));
6374496171girish	handle = nxgep->npi_reg_handle;
6384496171girish	bzero(&fcfg, sizeof (flow_key_cfg_t));
6394496171girish
640a3c5bd6speer	if (class_config & NXGE_CLASS_FLOW_USE_PROTO)
6414496171girish		fcfg.use_proto = 1;
6424496171girish	if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT)
6434496171girish		fcfg.use_dport = 1;
6444496171girish	if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT)
6454496171girish		fcfg.use_sport = 1;
6464496171girish	if (class_config & NXGE_CLASS_FLOW_USE_IPDST)
6474496171girish		fcfg.use_daddr = 1;
6484496171girish	if (class_config & NXGE_CLASS_FLOW_USE_IPSRC)
6494496171girish		fcfg.use_saddr = 1;
6504496171girish	if (class_config & NXGE_CLASS_FLOW_USE_VLAN)
6514496171girish		fcfg.use_vlan = 1;
6524496171girish	if (class_config & NXGE_CLASS_FLOW_USE_L2DA)
6534496171girish		fcfg.use_l2da = 1;
6544496171girish	if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM)
6554496171girish		fcfg.use_portnum = 1;
6564496171girish	fcfg.ip_opts_exist = 0;
6574496171girish
6584496171girish	rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg);
6594496171girish	if (rs & NPI_FFLP_ERROR) {
6604496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
66152ccf84misaki		    " opt %x for class %d failed ", class_config, l3_class));
6624496171girish		return (NXGE_ERROR | rs);
6634496171girish	}
6644496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key"));
6654496171girish	return (NXGE_OK);
6664496171girish}
6674496171girish
6684496171girishnxge_status_t
6694496171girishnxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class,
670a3c5bd6speer	uint32_t *class_config)
6714496171girish{
6724496171girish	flow_key_cfg_t fcfg;
6734496171girish	npi_handle_t handle;
6744496171girish	npi_status_t rs = NPI_SUCCESS;
6754496171girish	uint32_t ccfg = 0;
676a3c5bd6speer
6774496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get"));
6784496171girish	handle = nxgep->npi_reg_handle;
6794496171girish	bzero(&fcfg, sizeof (flow_key_cfg_t));
6804496171girish
6814496171girish	rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg);
6824496171girish	if (rs & NPI_FFLP_ERROR) {
6834496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
68452ccf84misaki		    " opt %x for class %d failed ", class_config, l3_class));
6854496171girish		return (NXGE_ERROR | rs);
6864496171girish	}
6874496171girish
6884496171girish	if (fcfg.use_proto)
6894496171girish		ccfg |= NXGE_CLASS_FLOW_USE_PROTO;
6904496171girish	if (fcfg.use_dport)
6914496171girish		ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT;
6924496171girish	if (fcfg.use_sport)
6934496171girish		ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT;
6944496171girish	if (fcfg.use_daddr)
6954496171girish		ccfg |= NXGE_CLASS_FLOW_USE_IPDST;
6964496171girish	if (fcfg.use_saddr)
6974496171girish		ccfg |= NXGE_CLASS_FLOW_USE_IPSRC;
6984496171girish	if (fcfg.use_vlan)
6994496171girish		ccfg |= NXGE_CLASS_FLOW_USE_VLAN;
7004496171girish	if (fcfg.use_l2da)
7014496171girish		ccfg |= NXGE_CLASS_FLOW_USE_L2DA;
7024496171girish	if (fcfg.use_portnum)
703a3c5bd6speer		ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM;
7044496171girish
7054496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
70652ccf84misaki	    " nxge_cfg_ip_cls_flow_key_get %x", ccfg));
7074496171girish	*class_config = ccfg;
7084496171girish
7094496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
71052ccf84misaki	    " <== nxge_cfg_ip_cls_flow_key_get"));
7114496171girish	return (NXGE_OK);
7124496171girish}
7134496171girish
7144496171girishstatic nxge_status_t
7154496171girishnxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class,
716a3c5bd6speer	uint32_t *class_config)
7174496171girish{
7184496171girish	npi_status_t rs = NPI_SUCCESS;
7194496171girish	tcam_key_cfg_t cfg;
7204496171girish	npi_handle_t handle;
7214496171girish	uint32_t ccfg = 0;
7224496171girish
7234496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
7244496171girish
7254496171girish	bzero(&cfg, sizeof (tcam_key_cfg_t));
7264496171girish	handle = nxgep->npi_reg_handle;
7274496171girish
7284496171girish	rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg);
7294496171girish	if (rs & NPI_FFLP_ERROR) {
7304496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
73152ccf84misaki		    " opt %x for class %d failed ", class_config, class));
7324496171girish		return (NXGE_ERROR | rs);
7334496171girish	}
7344496171girish	if (cfg.discard)
735a3c5bd6speer		ccfg |= NXGE_CLASS_DISCARD;
7364496171girish	if (cfg.lookup_enable)
7374496171girish		ccfg |= NXGE_CLASS_TCAM_LOOKUP;
7384496171girish	if (cfg.use_ip_daddr)
739a3c5bd6speer		ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR;
7404496171girish	*class_config = ccfg;
7414496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
74252ccf84misaki	    " ==> nxge_cfg_tcam_ip_class %x", ccfg));
7434496171girish	return (NXGE_OK);
7444496171girish}
7454496171girish
7464496171girishstatic nxge_status_t
7474496171girishnxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class,
748a3c5bd6speer	uint32_t class_config)
7494496171girish{
7504496171girish	npi_status_t rs = NPI_SUCCESS;
7514496171girish	tcam_key_cfg_t cfg;
7524496171girish	npi_handle_t handle;
753a3c5bd6speer	p_nxge_class_pt_cfg_t p_class_cfgp;
7544496171girish
7554496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
756a3c5bd6speer
7574496171girish	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7584496171girish	p_class_cfgp->class_cfg[class] = class_config;
7594496171girish
7604496171girish	bzero(&cfg, sizeof (tcam_key_cfg_t));
7614496171girish	handle = nxgep->npi_reg_handle;
7624496171girish	cfg.discard = 0;
7634496171girish	cfg.lookup_enable = 0;
7644496171girish	cfg.use_ip_daddr = 0;
7654496171girish	if (class_config & NXGE_CLASS_DISCARD)
7664496171girish		cfg.discard = 1;
7674496171girish	if (class_config & NXGE_CLASS_TCAM_LOOKUP)
7684496171girish		cfg.lookup_enable = 1;
769a3c5bd6speer	if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR)
7704496171girish		cfg.use_ip_daddr = 1;
7714496171girish
7724496171girish	rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg);
7734496171girish	if (rs & NPI_FFLP_ERROR) {
7744496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
77552ccf84misaki		    " opt %x for class %d failed ", class_config, class));
7764496171girish		return (NXGE_ERROR | rs);
7774496171girish	}
7784496171girish	return (NXGE_OK);
7794496171girish}
7804496171girish
7814496171girishnxge_status_t
7824496171girishnxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1)
7834496171girish{
7844496171girish	npi_status_t rs = NPI_SUCCESS;
7854496171girish	npi_handle_t handle;
786a3c5bd6speer	p_nxge_class_pt_cfg_t p_class_cfgp;
7874496171girish
7884496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1"));
7894496171girish	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7904496171girish	p_class_cfgp->init_h1 = h1;
7914496171girish	handle = nxgep->npi_reg_handle;
7924496171girish	rs = npi_fflp_cfg_hash_h1poly(handle, h1);
7934496171girish	if (rs & NPI_FFLP_ERROR) {
794a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
79552ccf84misaki		    " nxge_fflp_init_h1 %x failed ", h1));
7964496171girish		return (NXGE_ERROR | rs);
7974496171girish	}
7984496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1"));
7994496171girish	return (NXGE_OK);
8004496171girish}
8014496171girish
8024496171girishnxge_status_t
8034496171girishnxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2)
8044496171girish{
8054496171girish	npi_status_t rs = NPI_SUCCESS;
8064496171girish	npi_handle_t handle;
807a3c5bd6speer	p_nxge_class_pt_cfg_t p_class_cfgp;
8084496171girish
8094496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2"));
8104496171girish	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
8114496171girish	p_class_cfgp->init_h2 = h2;
8124496171girish
8134496171girish	handle = nxgep->npi_reg_handle;
8144496171girish	rs = npi_fflp_cfg_hash_h2poly(handle, h2);
8154496171girish	if (rs & NPI_FFLP_ERROR) {
816a3c5bd6speer		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
81752ccf84misaki		    " nxge_fflp_init_h2 %x failed ", h2));
8184496171girish		return (NXGE_ERROR | rs);
8194496171girish	}
8204496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2"));
8214496171girish	return (NXGE_OK);
8224496171girish}
8234496171girish
8244496171girishnxge_status_t
8254496171girishnxge_classify_init_sw(p_nxge_t nxgep)
8264496171girish{
8274496171girish	nxge_classify_t *classify_ptr;
8284496171girish
8294496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw"));
8304496171girish	classify_ptr = &nxgep->classifier;
8314496171girish
8324496171girish	if (classify_ptr->state & NXGE_FFLP_SW_INIT) {
8334496171girish		NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
83452ccf84misaki		    "nxge_classify_init_sw already init"));
8354496171girish		return (NXGE_OK);
8364496171girish	}
837a3c5bd6speer
8384df55fdJanie Lu	classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports;
8394df55fdJanie Lu	classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam;
8404df55fdJanie Lu	classify_ptr->tcam_top = nxgep->function_num;
8414496171girish
842a3c5bd6speer	/* Init defaults */
843a3c5bd6speer	/*
844a3c5bd6speer	 * add hacks required for HW shortcomings for example, code to handle
845a3c5bd6speer	 * fragmented packets
846a3c5bd6speer	 */
8474496171girish	nxge_init_h1_table();
8484496171girish	nxge_crc_ccitt_init();
8494496171girish	nxgep->classifier.tcam_location = nxgep->function_num;
8504496171girish	nxgep->classifier.fragment_bug = 1;
8514496171girish	classify_ptr->state |= NXGE_FFLP_SW_INIT;
8524496171girish
8534496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw"));
8544496171girish	return (NXGE_OK);
8554496171girish}
8564496171girish
8574496171girishnxge_status_t
8584496171girishnxge_classify_exit_sw(p_nxge_t nxgep)
8594496171girish{
8604496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw"));
861b37cc45Toomas Soome	nxgep->classifier.state = 0;
8624496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw"));
8634496171girish	return (NXGE_OK);
8644496171girish}
8654496171girish
8664496171girish/*
8674496171girish * Figures out the RDC Group for the entry
8684496171girish *
8694496171girish * The current implementation is just a place holder and it
8704496171girish * returns 0.
8714496171girish * The real location determining algorithm would consider
8724496171girish * the partition etc ... before deciding w
8734496171girish *
8744496171girish */
875a3c5bd6speer
8760a8e077speer/* ARGSUSED */
8774496171girishstatic uint8_t
8784df55fdJanie Lunxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
8794496171girish{
8804496171girish	int use_port_rdc_grp = 0;
8814496171girish	uint8_t rdc_grp = 0;
882a3c5bd6speer	p_nxge_dma_pt_cfg_t p_dma_cfgp;
883a3c5bd6speer	p_nxge_hw_pt_cfg_t p_cfgp;
884a3c5bd6speer	p_nxge_rdc_grp_t rdc_grp_p;
885a3c5bd6speer
8864496171girish	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
8874496171girish	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
8884496171girish	rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp];
889678453aspeer	rdc_grp = p_cfgp->def_mac_rxdma_grpid;
890a3c5bd6speer
8914496171girish	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
89252ccf84misaki	    "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
89352ccf84misaki	    cookie, rdc_grp, rdc_grp_p));
8944496171girish	return (rdc_grp);
8954496171girish}
8964496171girish
8974496171girish/* ARGSUSED */
8984496171girishstatic uint8_t
8994df55fdJanie Lunxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
9004496171girish{
9014496171girish	return ((uint8_t)cookie);
9024496171girish}
9034496171girish
9040a8e077speer/* ARGSUSED */
9054496171girishstatic void
9064496171girishnxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec,
907a3c5bd6speer	tcam_entry_t *tcam_ptr)
9084496171girish{
9094496171girish	udpip4_spec_t *fspec_key;
9104496171girish	udpip4_spec_t *fspec_mask;
9114496171girish
9124496171girish	fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec;
9134496171girish	fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec;
9144496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
9154496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
9164496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
9174496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
9184496171girish	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
91952ccf84misaki	    fspec_key->pdst, fspec_key->psrc);
9204496171girish	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
92152ccf84misaki	    fspec_mask->pdst, fspec_mask->psrc);
9224496171girish	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
92352ccf84misaki	    tcam_ptr->ip4_class_mask,
92452ccf84misaki	    TCAM_CLASS_UDP_IPV4);
9254496171girish	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
92652ccf84misaki	    tcam_ptr->ip4_proto_mask,
92752ccf84misaki	    IPPROTO_UDP);
9284df55fdJanie Lu	tcam_ptr->ip4_tos_key = fspec_key->tos;
9294df55fdJanie Lu	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
9304496171girish}
9314496171girish
9324496171girishstatic void
9334496171girishnxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
934a3c5bd6speer	tcam_entry_t *tcam_ptr)
9354496171girish{
9364496171girish	udpip6_spec_t *fspec_key;
9374496171girish	udpip6_spec_t *fspec_mask;
938a3c5bd6speer	p_nxge_class_pt_cfg_t p_class_cfgp;
9394496171girish
9404496171girish	fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec;
9414496171girish	fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec;
9424496171girish	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
9434496171girish	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
94452ccf84misaki	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
9454496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
9464496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
9474496171girish	} else {
9484496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
9494496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
9504496171girish	}
9514496171girish
9524496171girish	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
95352ccf84misaki	    tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6);
9544496171girish	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
95552ccf84misaki	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP);
9564496171girish	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
95752ccf84misaki	    fspec_key->pdst, fspec_key->psrc);
9584496171girish	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
95952ccf84misaki	    fspec_mask->pdst, fspec_mask->psrc);
9604df55fdJanie Lu	tcam_ptr->ip6_tos_key = fspec_key->tos;
9614df55fdJanie Lu	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
9624496171girish}
9634496171girish
9640a8e077speer/* ARGSUSED */
9654496171girishstatic void
9664496171girishnxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec,
967a3c5bd6speer	tcam_entry_t *tcam_ptr)
9684496171girish{
9694496171girish	tcpip4_spec_t *fspec_key;
9704496171girish	tcpip4_spec_t *fspec_mask;
9714496171girish
9724496171girish	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
9734496171girish	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
9744496171girish
9754496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
9764496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
9774496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
9784496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
9794496171girish	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
98052ccf84misaki	    fspec_key->pdst, fspec_key->psrc);
9814496171girish	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
98252ccf84misaki	    fspec_mask->pdst, fspec_mask->psrc);
9834496171girish	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
98452ccf84misaki	    tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4);
9854496171girish	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
98652ccf84misaki	    tcam_ptr->ip4_proto_mask, IPPROTO_TCP);
9874df55fdJanie Lu	tcam_ptr->ip4_tos_key = fspec_key->tos;
9884df55fdJanie Lu	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
9894496171girish}
9904496171girish
9910a8e077speer/* ARGSUSED */
9924496171girishstatic void
9934496171girishnxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec,
994a3c5bd6speer	tcam_entry_t *tcam_ptr)
9954496171girish{
9964496171girish	tcpip4_spec_t *fspec_key;
9974496171girish	tcpip4_spec_t *fspec_mask;
9984496171girish
9994496171girish	fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
10004496171girish	fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
10014496171girish
10024496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
10034496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
10044496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
10054496171girish	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
10064496171girish	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
100752ccf84misaki	    tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4);
10084496171girish	TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
100952ccf84misaki	    tcam_ptr->ip4_proto_mask, IPPROTO_SCTP);
10104496171girish	TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
101152ccf84misaki	    fspec_key->pdst, fspec_key->psrc);
10124496171girish	TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
101352ccf84misaki	    fspec_mask->pdst, fspec_mask->psrc);
10144df55fdJanie Lu	tcam_ptr->ip4_tos_key = fspec_key->tos;
10154df55fdJanie Lu	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
10164496171girish}
10174496171girish
10184496171girishstatic void
10194496171girishnxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1020a3c5bd6speer	tcam_entry_t *tcam_ptr)
10214496171girish{
10224496171girish	tcpip6_spec_t *fspec_key;
10234496171girish	tcpip6_spec_t *fspec_mask;
1024a3c5bd6speer	p_nxge_class_pt_cfg_t p_class_cfgp;
1025a3c5bd6speer
10264496171girish	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10274496171girish	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10284496171girish
10294496171girish	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10304496171girish	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
103152ccf84misaki	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
10324496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
10334496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
10344496171girish	} else {
10354496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
10364496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
10374496171girish	}
10384496171girish
10394496171girish	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
104052ccf84misaki	    tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6);
10414496171girish	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
104252ccf84misaki	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP);
10434496171girish	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
104452ccf84misaki	    fspec_key->pdst, fspec_key->psrc);
10454496171girish	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
104652ccf84misaki	    fspec_mask->pdst, fspec_mask->psrc);
10474df55fdJanie Lu	tcam_ptr->ip6_tos_key = fspec_key->tos;
10484df55fdJanie Lu	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
10494496171girish}
10504496171girish
10514496171girishstatic void
10524496171girishnxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
1053a3c5bd6speer	tcam_entry_t *tcam_ptr)
10544496171girish{
10554496171girish	tcpip6_spec_t *fspec_key;
10564496171girish	tcpip6_spec_t *fspec_mask;
1057a3c5bd6speer	p_nxge_class_pt_cfg_t p_class_cfgp;
10584496171girish
10594496171girish	fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10604496171girish	fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10614496171girish	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10624496171girish
10634496171girish	if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
106452ccf84misaki	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
10654496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
10664496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
10674496171girish	} else {
10684496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
10694496171girish		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
10704496171girish	}
10714496171girish
10724496171girish	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
107352ccf84misaki	    tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6);
10744496171girish	TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
107552ccf84misaki	    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP);
10764496171girish	TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
107752ccf84misaki	    fspec_key->pdst, fspec_key->psrc);
10784496171girish	TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
107952ccf84misaki	    fspec_mask->pdst, fspec_mask->psrc);
10804df55fdJanie Lu	tcam_ptr->ip6_tos_key = fspec_key->tos;
10814df55fdJanie Lu	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
10824df55fdJanie Lu}
10834df55fdJanie Lu
10844df55fdJanie Lu/* ARGSUSED */
10854df55fdJanie Lustatic void
10864df55fdJanie Lunxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec,
10874df55fdJanie Lu	tcam_entry_t *tcam_ptr)
10884df55fdJanie Lu{
10894df55fdJanie Lu	ahip4_spec_t *fspec_key;
10904df55fdJanie Lu	ahip4_spec_t *fspec_mask;
10914df55fdJanie Lu
10924df55fdJanie Lu	fspec_key = (ahip4_spec_t *)&flow_spec->uh.ahip4spec;
10934df55fdJanie Lu	fspec_mask = (ahip4_spec_t *)&flow_spec->um.ahip4spec;
10944df55fdJanie Lu
10954df55fdJanie Lu	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
10964df55fdJanie Lu	TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
10974df55fdJanie Lu	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
10984df55fdJanie Lu	TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
10994df55fdJanie Lu
11004df55fdJanie Lu	tcam_ptr->ip4_port_key = fspec_key->spi;
11014df55fdJanie Lu	tcam_ptr->ip4_port_mask = fspec_mask->spi;
11024df55fdJanie Lu
11034df55fdJanie Lu	TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
11044df55fdJanie Lu	    tcam_ptr->ip4_class_mask,
11054df55fdJanie Lu	    TCAM_CLASS_AH_ESP_IPV4);
11064df55fdJanie Lu
11074df55fdJanie Lu	if (flow_spec->flow_type == FSPEC_AHIP4) {
11084df55fdJanie Lu		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
11094df55fdJanie Lu		    tcam_ptr->ip4_proto_mask, IPPROTO_AH);
11104df55fdJanie Lu	} else {
11114df55fdJanie Lu		TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
11124df55fdJanie Lu		    tcam_ptr->ip4_proto_mask, IPPROTO_ESP);
11134df55fdJanie Lu	}
11144df55fdJanie Lu	tcam_ptr->ip4_tos_key = fspec_key->tos;
11154df55fdJanie Lu	tcam_ptr->ip4_tos_mask = fspec_mask->tos;
11164496171girish}
11174496171girish
11184df55fdJanie Lustatic void
11194df55fdJanie Lunxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
11204df55fdJanie Lu	tcam_entry_t *tcam_ptr)
11214df55fdJanie Lu{
11224df55fdJanie Lu	ahip6_spec_t *fspec_key;
11234df55fdJanie Lu	ahip6_spec_t *fspec_mask;
11244df55fdJanie Lu	p_nxge_class_pt_cfg_t p_class_cfgp;
11254df55fdJanie Lu
11264df55fdJanie Lu	fspec_key = (ahip6_spec_t *)&flow_spec->uh.ahip6spec;
11274df55fdJanie Lu	fspec_mask = (ahip6_spec_t *)&flow_spec->um.ahip6spec;
11284df55fdJanie Lu
11294df55fdJanie Lu	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
11304df55fdJanie Lu	if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] &
11314df55fdJanie Lu	    NXGE_CLASS_TCAM_USE_SRC_ADDR) {
11324df55fdJanie Lu		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
11334df55fdJanie Lu		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
11344df55fdJanie Lu	} else {
11354df55fdJanie Lu		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
11364df55fdJanie Lu		TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
11374df55fdJanie Lu	}
11384df55fdJanie Lu
11394df55fdJanie Lu	TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
11404df55fdJanie Lu	    tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6);
11414df55fdJanie Lu
11424df55fdJanie Lu	if (flow_spec->flow_type == FSPEC_AHIP6) {
11434df55fdJanie Lu		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
11444df55fdJanie Lu		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH);
11454df55fdJanie Lu	} else {
11464df55fdJanie Lu		TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
11474df55fdJanie Lu		    tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP);
11484df55fdJanie Lu	}
11494df55fdJanie Lu	tcam_ptr->ip6_port_key = fspec_key->spi;
11504df55fdJanie Lu	tcam_ptr->ip6_port_mask = fspec_mask->spi;
11514df55fdJanie Lu	tcam_ptr->ip6_tos_key = fspec_key->tos;
11524df55fdJanie Lu	tcam_ptr->ip6_tos_mask = fspec_mask->tos;
11534df55fdJanie Lu}
11544df55fdJanie Lu
11554df55fdJanie Lu/* ARGSUSED */
11564df55fdJanie Lustatic void
11574df55fdJanie Lunxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec,
11584df55fdJanie Lu	tcam_entry_t *tcam_ptr, tcam_class_t class)
11594df55fdJanie Lu{
11604df55fdJanie Lu	ip_user_spec_t *fspec_key;
11614df55fdJanie Lu	ip_user_spec_t *fspec_mask;
11624df55fdJanie Lu
11634df55fdJanie Lu	fspec_key = (ip_user_spec_t *)&flow_spec->uh.ip_usr_spec;
11644df55fdJanie Lu	fspec_mask = (ip_user_spec_t *)&flow_spec->um.ip_usr_spec;
11654df55fdJanie Lu
11664df55fdJanie Lu	if (fspec_key->ip_ver == FSPEC_IP4) {
11674df55fdJanie Lu		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
11684df55fdJanie Lu		TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
11694df55fdJanie Lu		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
11704df55fdJanie Lu		TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
11714df55fdJanie Lu
11724df55fdJanie Lu		tcam_ptr->ip4_port_key = fspec_key->l4_4_bytes;
11734df55fdJanie Lu		tcam_ptr->ip4_port_mask = fspec_mask->l4_4_bytes;
11744df55fdJanie Lu
11754df55fdJanie Lu		TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
11764df55fdJanie Lu		    tcam_ptr->ip4_class_mask, class);
11774df55fdJanie Lu
11784df55fdJanie Lu		tcam_ptr->ip4_proto_key = fspec_key->proto;
11794df55fdJanie Lu		tcam_ptr->ip4_proto_mask = fspec_mask->proto;
11804df55fdJanie Lu
11814df55fdJanie Lu		tcam_ptr->ip4_tos_key = fspec_key->tos;
11824df55fdJanie Lu		tcam_ptr->ip4_tos_mask = fspec_mask->tos;
11834df55fdJanie Lu	}
11844df55fdJanie Lu}
11854df55fdJanie Lu
11864df55fdJanie Lu
11874496171girishnxge_status_t
11884496171girishnxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res,
1189a3c5bd6speer	uint32_t *H1, uint16_t *H2)
11904496171girish{
11914496171girish	flow_spec_t *flow_spec;
11924496171girish	uint32_t class_cfg;
11934496171girish	flow_template_t ft;
1194a3c5bd6speer	p_nxge_class_pt_cfg_t p_class_cfgp;
11954496171girish
11964496171girish	int ft_size = sizeof (flow_template_t);
1197a3c5bd6speer
11984496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash"));
11994496171girish
12004496171girish	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
12014496171girish	bzero((char *)&ft, ft_size);
12024496171girish	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1203a3c5bd6speer
12044496171girish	switch (flow_spec->flow_type) {
1205a3c5bd6speer	case FSPEC_TCPIP4:
1206a3c5bd6speer		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4];
1207a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1208a3c5bd6speer			ft.ip_proto = IPPROTO_TCP;
1209a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1210a3c5bd6speer			ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src;
1211a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1212a3c5bd6speer			ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst;
1213a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1214a3c5bd6speer			ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc;
1215a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1216a3c5bd6speer			ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst;
1217a3c5bd6speer		break;
1218a3c5bd6speer
1219a3c5bd6speer	case FSPEC_UDPIP4:
1220a3c5bd6speer		class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4];
1221a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
1222a3c5bd6speer			ft.ip_proto = IPPROTO_UDP;
1223a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
1224a3c5bd6speer			ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src;
1225a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
1226a3c5bd6speer			ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst;
1227a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
1228a3c5bd6speer			ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc;
1229a3c5bd6speer		if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
1230a3c5bd6speer			ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst;
1231a3c5bd6speer		break;
1232a3c5bd6speer
1233a3c5bd6speer	default:
1234a3c5bd6speer		return (NXGE_ERROR);
12354496171girish	}
12364496171girish
12374496171girish	*H1 = nxge_compute_h1(p_class_cfgp->init_h1,
123852ccf84misaki	    (uint32_t *)&ft, ft_size) & 0xfffff;
12394496171girish	*H2 = nxge_compute_h2(p_class_cfgp->init_h2,
124052ccf84misaki	    (uint8_t *)&ft, ft_size);
12414496171girish
12424496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash"));
12434496171girish	return (NXGE_OK);
12444496171girish}
12454496171girish
12464496171girishnxge_status_t
12474496171girishnxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
12484496171girish{
12494496171girish	uint32_t H1;
12504496171girish	uint16_t H2;
12514496171girish	nxge_status_t status = NXGE_OK;
12524496171girish
12534496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry"));
12544496171girish	status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2);
12554496171girish	if (status != NXGE_OK) {
12564496171girish		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
125752ccf84misaki		    " nxge_add_fcram_entry failed "));
12584496171girish		return (status);
12594496171girish	}
12604496171girish
12614496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry"));
12624496171girish	return (NXGE_OK);
12634496171girish}
12644496171girish
12654496171girish/*
12664496171girish * Already decided this flow goes into the tcam
12674496171girish */
12684496171girish
12694496171girishnxge_status_t
12704496171girishnxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
12714496171girish{
12724496171girish	npi_handle_t handle;
12734df55fdJanie Lu	uint64_t channel_cookie;
12744df55fdJanie Lu	uint64_t flow_cookie;
12754496171girish	flow_spec_t *flow_spec;
12764496171girish	npi_status_t rs = NPI_SUCCESS;
12774496171girish	tcam_entry_t tcam_ptr;
12784df55fdJanie Lu	tcam_location_t location;
12794496171girish	uint8_t offset, rdc_grp;
1280a3c5bd6speer	p_nxge_hw_list_t hw_p;
12814df55fdJanie Lu	uint64_t class;
12824496171girish
12834496171girish	NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry"));
12844496171girish	handle = nxgep->npi_reg_handle;
12854496171girish
1286a3c5bd6speer	bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
12874496171girish	flow_spec = (flow_spec_t *)&flow_res->flow_spec;
12884496171girish	flow_cookie = flow_res->flow_cookie;
12894496171girish	channel_cookie = flow_res->channel_cookie;
12904df55fdJanie Lu	location = (tcam_location_t)nxge_tcam_get_index(nxgep,
12914df55fdJanie Lu	    (uint16_t)flow_res->location);
12924df55fdJanie Lu
12934df55fdJanie Lu	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
12944df55fdJanie Lu		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
12954df55fdJanie Lu		    " nxge_add_tcam_entry: common hardware not set",
12964df55fdJanie Lu		    nxgep->niu_type));
12974df55fdJanie Lu		return (NXGE_ERROR);
12984df55fdJanie Lu	}
12994df55fdJanie Lu
13004df55fdJanie Lu	if (flow_spec->flow_type == FSPEC_IP_USR) {
13014df55fdJanie Lu		int i;
13024df55fdJanie Lu		int add_usr_cls = 0;
13034df55fdJanie Lu		int ipv6 = 0;
13044df55fdJanie Lu		ip_user_spec_t *uspec = &flow_spec->uh.ip_usr_spec;
13054df55fdJanie Lu		ip_user_spec_t *umask = &flow_spec->um.ip_usr_spec;
13064df55fdJanie Lu		nxge_usr_l3_cls_t *l3_ucls_p;
13074df55fdJanie Lu
13084df55fdJanie Lu		MUTEX_ENTER(&hw_p->nxge_tcam_lock);
13094df55fdJanie Lu
13104df55fdJanie Lu		for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
13114df55fdJanie Lu			l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
13124df55fdJanie Lu			if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) {
13134df55fdJanie Lu				if (uspec->proto == l3_ucls_p->pid) {
13144df55fdJanie Lu					class = l3_ucls_p->cls;
13154df55fdJanie Lu					l3_ucls_p->tcam_ref_cnt++;
13164df55fdJanie Lu					add_usr_cls = 1;
13174df55fdJanie Lu					break;
13184df55fdJanie Lu				}
13194df55fdJanie Lu			} else if (l3_ucls_p->valid == 0) {
13204df55fdJanie Lu				/* Program new user IP class */
13214df55fdJanie Lu				switch (i) {
13224df55fdJanie Lu				case 0:
13234df55fdJanie Lu					class = TCAM_CLASS_IP_USER_4;
13244df55fdJanie Lu					break;
13254df55fdJanie Lu				case 1:
13264df55fdJanie Lu					class = TCAM_CLASS_IP_USER_5;
13274df55fdJanie Lu					break;
13284df55fdJanie Lu				case 2:
13294df55fdJanie Lu					class = TCAM_CLASS_IP_USER_6;
13304df55fdJanie Lu					break;
13314df55fdJanie Lu				case 3:
13324df55fdJanie Lu					class = TCAM_CLASS_IP_USER_7;
13334df55fdJanie Lu					break;
13344df55fdJanie Lu				default:
13354df55fdJanie Lu					break;
13364df55fdJanie Lu				}
13374df55fdJanie Lu				if (uspec->ip_ver == FSPEC_IP6)
13384df55fdJanie Lu					ipv6 = 1;
13394df55fdJanie Lu				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
13404df55fdJanie Lu				    (tcam_class_t)class, uspec->tos,
13414df55fdJanie Lu				    umask->tos, uspec->proto, ipv6);
13424df55fdJanie Lu				if (rs != NPI_SUCCESS)
13434df55fdJanie Lu					goto fail;
13444df55fdJanie Lu
13454df55fdJanie Lu				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
13464df55fdJanie Lu				    (tcam_class_t)class);
13474df55fdJanie Lu				if (rs != NPI_SUCCESS)
13484df55fdJanie Lu					goto fail;
13494df55fdJanie Lu
13504df55fdJanie Lu				l3_ucls_p->cls = class;
13514df55fdJanie Lu				l3_ucls_p->pid = uspec->proto;
13524df55fdJanie Lu				l3_ucls_p->tcam_ref_cnt++;
13534df55fdJanie Lu				l3_ucls_p->valid = 1;
13544df55fdJanie Lu				add_usr_cls = 1;
13554df55fdJanie Lu				break;
13564df55fdJanie Lu			} else if (l3_ucls_p->tcam_ref_cnt == 0 &&
13574df55fdJanie Lu			    uspec->proto == l3_ucls_p->pid) {
13584df55fdJanie Lu				/*
13594df55fdJanie Lu				 * The class has already been programmed,
13604df55fdJanie Lu				 * probably for flow hash
13614df55fdJanie Lu				 */
13624df55fdJanie Lu				class = l3_ucls_p->cls;
13634df55fdJanie Lu				if (uspec->ip_ver == FSPEC_IP6)
13644df55fdJanie Lu					ipv6 = 1;
13654df55fdJanie Lu				rs = npi_fflp_cfg_ip_usr_cls_set(handle,
13664df55fdJanie Lu				    (tcam_class_t)class, uspec->tos,
13674df55fdJanie Lu				    umask->tos, uspec->proto, ipv6);
13684df55fdJanie Lu				if (rs != NPI_SUCCESS)
13694df55fdJanie Lu					goto fail;
13704df55fdJanie Lu
13714df55fdJanie Lu				rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
1372