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