13859Sml29623 /*
23859Sml29623 * CDDL HEADER START
33859Sml29623 *
43859Sml29623 * The contents of this file are subject to the terms of the
53859Sml29623 * Common Development and Distribution License (the "License").
63859Sml29623 * You may not use this file except in compliance with the License.
73859Sml29623 *
83859Sml29623 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93859Sml29623 * or http://www.opensolaris.org/os/licensing.
103859Sml29623 * See the License for the specific language governing permissions
113859Sml29623 * and limitations under the License.
123859Sml29623 *
133859Sml29623 * When distributing Covered Code, include this CDDL HEADER in each
143859Sml29623 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153859Sml29623 * If applicable, add the following below this CDDL HEADER, with the
163859Sml29623 * fields enclosed by brackets "[]" replaced with your own identifying
173859Sml29623 * information: Portions Copyright [yyyy] [name of copyright owner]
183859Sml29623 *
193859Sml29623 * CDDL HEADER END
203859Sml29623 */
21*11878SVenu.Iyer@Sun.COM
223859Sml29623 /*
23*11878SVenu.Iyer@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
243859Sml29623 * Use is subject to license terms.
253859Sml29623 */
263859Sml29623
273859Sml29623 #include <npi_fflp.h>
283859Sml29623 #include <npi_mac.h>
293859Sml29623 #include <nxge_defs.h>
303859Sml29623 #include <nxge_flow.h>
313859Sml29623 #include <nxge_fflp.h>
323859Sml29623 #include <nxge_impl.h>
333859Sml29623 #include <nxge_fflp_hash.h>
343859Sml29623 #include <nxge_common.h>
353859Sml29623
363859Sml29623
373859Sml29623 /*
383859Sml29623 * Function prototypes
393859Sml29623 */
403859Sml29623 static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t);
413859Sml29623 static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t);
423859Sml29623 static nxge_status_t nxge_fflp_tcam_init(p_nxge_t);
433859Sml29623 static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t);
443859Sml29623 static nxge_status_t nxge_fflp_fcram_init(p_nxge_t);
453859Sml29623 static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *);
463859Sml29623 static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
473859Sml29623 static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
483859Sml29623 static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *);
493859Sml29623 static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *,
503859Sml29623 tcam_entry_t *);
513859Sml29623 static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *,
523859Sml29623 tcam_entry_t *);
533859Sml29623 static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *,
543859Sml29623 tcam_entry_t *);
5511304SJanie.Lu@Sun.COM static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t);
5611304SJanie.Lu@Sun.COM static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t);
5711304SJanie.Lu@Sun.COM static uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t);
5811304SJanie.Lu@Sun.COM static uint32_t nxge_tcam_cls_to_flow(uint32_t);
5911304SJanie.Lu@Sun.COM static uint8_t nxge_iptun_pkt_type_to_pid(uint8_t);
6011304SJanie.Lu@Sun.COM static npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t,
6111304SJanie.Lu@Sun.COM iptun_cfg_t *);
6211304SJanie.Lu@Sun.COM static boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *);
633859Sml29623
643859Sml29623 /*
653859Sml29623 * functions used outside this file
663859Sml29623 */
673859Sml29623 nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t);
683859Sml29623 nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t);
693859Sml29623 nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *);
703859Sml29623 static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t);
713859Sml29623 nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *);
723859Sml29623 nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *);
733859Sml29623 nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *,
743859Sml29623 uint32_t *, uint16_t *);
7511304SJanie.Lu@Sun.COM int nxge_get_valid_tcam_cnt(p_nxge_t);
7611304SJanie.Lu@Sun.COM void nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *);
7711304SJanie.Lu@Sun.COM void nxge_get_tcam_entry(p_nxge_t, flow_resource_t *);
7811304SJanie.Lu@Sun.COM void nxge_del_tcam_entry(p_nxge_t, uint32_t);
7911304SJanie.Lu@Sun.COM void nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *);
8011304SJanie.Lu@Sun.COM void nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t);
8111304SJanie.Lu@Sun.COM void nxge_del_iptun_class(p_nxge_t, uint8_t);
8211304SJanie.Lu@Sun.COM void nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t);
8311304SJanie.Lu@Sun.COM void nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t);
8411304SJanie.Lu@Sun.COM void nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *);
8511304SJanie.Lu@Sun.COM
863859Sml29623
873859Sml29623 nxge_status_t
nxge_tcam_dump_entry(p_nxge_t nxgep,uint32_t location)883859Sml29623 nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location)
893859Sml29623 {
903859Sml29623 tcam_entry_t tcam_rdptr;
913859Sml29623 uint64_t asc_ram = 0;
923859Sml29623 npi_handle_t handle;
933859Sml29623 npi_status_t status;
943859Sml29623
953859Sml29623 handle = nxgep->npi_reg_handle;
963859Sml29623
973859Sml29623 bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry));
983859Sml29623 status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location,
996929Smisaki (struct tcam_entry *)&tcam_rdptr);
1003859Sml29623 if (status & NPI_FAILURE) {
1013859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1026929Smisaki " nxge_tcam_dump_entry:"
1036929Smisaki " tcam read failed at location %d ", location));
1043859Sml29623 return (NXGE_ERROR);
1053859Sml29623 }
1063859Sml29623 status = npi_fflp_tcam_asc_ram_entry_read(handle,
1076929Smisaki (tcam_location_t)location, &asc_ram);
1083859Sml29623
1093859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n"
1106929Smisaki " key: %llx %llx %llx %llx \n"
1116929Smisaki " mask: %llx %llx %llx %llx \n"
1126929Smisaki " ASC RAM %llx \n", location,
1136929Smisaki tcam_rdptr.key0, tcam_rdptr.key1,
1146929Smisaki tcam_rdptr.key2, tcam_rdptr.key3,
1156929Smisaki tcam_rdptr.mask0, tcam_rdptr.mask1,
1166929Smisaki tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram));
1173859Sml29623 return (NXGE_OK);
1183859Sml29623 }
1193859Sml29623
1203859Sml29623 void
nxge_get_tcam(p_nxge_t nxgep,p_mblk_t mp)1213859Sml29623 nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp)
1223859Sml29623 {
1233859Sml29623 uint32_t tcam_loc;
1243859Sml29623 int *lptr;
1253859Sml29623 int location;
1263859Sml29623
1273859Sml29623 uint32_t start_location = 0;
1283859Sml29623 uint32_t stop_location = nxgep->classifier.tcam_size;
1293859Sml29623 lptr = (int *)mp->b_rptr;
1303859Sml29623 location = *lptr;
1313859Sml29623
1323859Sml29623 if ((location >= nxgep->classifier.tcam_size) || (location < -1)) {
1333859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1346929Smisaki "nxge_tcam_dump: Invalid location %d \n", location));
1353859Sml29623 return;
1363859Sml29623 }
1373859Sml29623 if (location == -1) {
1383859Sml29623 start_location = 0;
1393859Sml29623 stop_location = nxgep->classifier.tcam_size;
1403859Sml29623 } else {
1413859Sml29623 start_location = location;
1423859Sml29623 stop_location = location + 1;
1433859Sml29623 }
1443859Sml29623 for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++)
1453859Sml29623 (void) nxge_tcam_dump_entry(nxgep, tcam_loc);
1463859Sml29623 }
1473859Sml29623
1483859Sml29623 /*
1493859Sml29623 * nxge_fflp_vlan_table_invalidate_all
1503859Sml29623 * invalidates the vlan RDC table entries.
1513859Sml29623 * INPUT
1523859Sml29623 * nxge soft state data structure
1533859Sml29623 * Return
1543859Sml29623 * NXGE_OK
1553859Sml29623 * NXGE_ERROR
1563859Sml29623 *
1573859Sml29623 */
1583859Sml29623
1593859Sml29623 static nxge_status_t
nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)1603859Sml29623 nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep)
1613859Sml29623 {
1623859Sml29623 vlan_id_t vlan_id;
1633859Sml29623 npi_handle_t handle;
1643859Sml29623 npi_status_t rs = NPI_SUCCESS;
1653859Sml29623 vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
1663859Sml29623
1673859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all "));
1683859Sml29623 handle = nxgep->npi_reg_handle;
1693859Sml29623 for (vlan_id = start; vlan_id < stop; vlan_id++) {
1703859Sml29623 rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id);
1713859Sml29623 if (rs != NPI_SUCCESS) {
1723859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1736929Smisaki "VLAN Table invalidate failed for vlan id %d ",
1746929Smisaki vlan_id));
1753859Sml29623 return (NXGE_ERROR | rs);
1763859Sml29623 }
1773859Sml29623 }
1783859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all "));
1793859Sml29623 return (NXGE_OK);
1803859Sml29623 }
1813859Sml29623
1823859Sml29623 /*
1833859Sml29623 * The following functions are used by other modules to init
1843859Sml29623 * the fflp module.
1853859Sml29623 * these functions are the basic API used to init
1863859Sml29623 * the fflp modules (tcam, fcram etc ......)
1873859Sml29623 *
1883859Sml29623 * The TCAM search future would be disabled by default.
1893859Sml29623 */
1903859Sml29623
1913859Sml29623 static nxge_status_t
nxge_fflp_tcam_init(p_nxge_t nxgep)1923859Sml29623 nxge_fflp_tcam_init(p_nxge_t nxgep)
1933859Sml29623 {
1943859Sml29623 uint8_t access_ratio;
1953859Sml29623 tcam_class_t class;
1963859Sml29623 npi_status_t rs = NPI_SUCCESS;
1973859Sml29623 npi_handle_t handle;
1983859Sml29623
1993859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init"));
2003859Sml29623 handle = nxgep->npi_reg_handle;
2013859Sml29623
2023859Sml29623 rs = npi_fflp_cfg_tcam_disable(handle);
2033859Sml29623 if (rs != NPI_SUCCESS) {
2043859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n"));
2053859Sml29623 return (NXGE_ERROR | rs);
2063859Sml29623 }
2073859Sml29623
2083859Sml29623 access_ratio = nxgep->param_arr[param_tcam_access_ratio].value;
2093859Sml29623 rs = npi_fflp_cfg_tcam_access(handle, access_ratio);
2103859Sml29623 if (rs != NPI_SUCCESS) {
2113859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2126929Smisaki "failed TCAM Access cfg\n"));
2133859Sml29623 return (NXGE_ERROR | rs);
2143859Sml29623 }
2153859Sml29623
2163859Sml29623 /* disable configurable classes */
2173859Sml29623 /* disable the configurable ethernet classes; */
2183859Sml29623 for (class = TCAM_CLASS_ETYPE_1;
2196929Smisaki class <= TCAM_CLASS_ETYPE_2; class++) {
2203859Sml29623 rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class);
2213859Sml29623 if (rs != NPI_SUCCESS) {
2223859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2236929Smisaki "TCAM USR Ether Class config failed."));
2243859Sml29623 return (NXGE_ERROR | rs);
2253859Sml29623 }
2263859Sml29623 }
2273859Sml29623
2283859Sml29623 /* disable the configurable ip classes; */
2293859Sml29623 for (class = TCAM_CLASS_IP_USER_4;
2306929Smisaki class <= TCAM_CLASS_IP_USER_7; class++) {
2313859Sml29623 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
2323859Sml29623 if (rs != NPI_SUCCESS) {
2333859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2346929Smisaki "TCAM USR IP Class cnfg failed."));
2353859Sml29623 return (NXGE_ERROR | rs);
2363859Sml29623 }
2373859Sml29623 }
2383859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init"));
2393859Sml29623 return (NXGE_OK);
2403859Sml29623 }
2413859Sml29623
2423859Sml29623 /*
2433859Sml29623 * nxge_fflp_tcam_invalidate_all
2443859Sml29623 * invalidates all the tcam entries.
2453859Sml29623 * INPUT
2463859Sml29623 * nxge soft state data structure
2473859Sml29623 * Return
2483859Sml29623 * NXGE_OK
2493859Sml29623 * NXGE_ERROR
2503859Sml29623 *
2513859Sml29623 */
2523859Sml29623
2533859Sml29623
2543859Sml29623 static nxge_status_t
nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)2553859Sml29623 nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep)
2563859Sml29623 {
2573859Sml29623 uint16_t location;
2583859Sml29623 npi_status_t rs = NPI_SUCCESS;
2593859Sml29623 npi_handle_t handle;
2603859Sml29623 uint16_t start = 0, stop = nxgep->classifier.tcam_size;
2613859Sml29623 p_nxge_hw_list_t hw_p;
2623859Sml29623
2633859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
2646929Smisaki "==> nxge_fflp_tcam_invalidate_all"));
2653859Sml29623 handle = nxgep->npi_reg_handle;
2663859Sml29623 if ((hw_p = nxgep->nxge_hw_p) == NULL) {
2673859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2686929Smisaki " nxge_fflp_tcam_invalidate_all:"
2696929Smisaki " common hardware not set", nxgep->niu_type));
2703859Sml29623 return (NXGE_ERROR);
2713859Sml29623 }
2723859Sml29623 MUTEX_ENTER(&hw_p->nxge_tcam_lock);
2733859Sml29623 for (location = start; location < stop; location++) {
2743859Sml29623 rs = npi_fflp_tcam_entry_invalidate(handle, location);
2753859Sml29623 if (rs != NPI_SUCCESS) {
2763859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2773859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2786929Smisaki "TCAM invalidate failed at loc %d ", location));
2793859Sml29623 return (NXGE_ERROR | rs);
2803859Sml29623 }
2813859Sml29623 }
2823859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock);
2833859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
2846929Smisaki "<== nxge_fflp_tcam_invalidate_all"));
2853859Sml29623 return (NXGE_OK);
2863859Sml29623 }
2873859Sml29623
2883859Sml29623 /*
2893859Sml29623 * nxge_fflp_fcram_entry_invalidate_all
2903859Sml29623 * invalidates all the FCRAM entries.
2913859Sml29623 * INPUT
2923859Sml29623 * nxge soft state data structure
2933859Sml29623 * Return
2943859Sml29623 * NXGE_OK
2953859Sml29623 * NXGE_ERROR
2963859Sml29623 *
2973859Sml29623 */
2983859Sml29623
2993859Sml29623 static nxge_status_t
nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)3003859Sml29623 nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep)
3013859Sml29623 {
3023859Sml29623 npi_handle_t handle;
3033859Sml29623 npi_status_t rs = NPI_SUCCESS;
3043859Sml29623 part_id_t pid = 0;
3053859Sml29623 uint8_t base_mask, base_reloc;
3063859Sml29623 fcram_entry_t fc;
3073859Sml29623 uint32_t location;
3083859Sml29623 uint32_t increment, last_location;
3093859Sml29623
3103859Sml29623 /*
3113859Sml29623 * (1) configure and enable partition 0 with no relocation
3123859Sml29623 * (2) Assume the FCRAM is used as IPv4 exact match entry cells
3133859Sml29623 * (3) Invalidate these cells by clearing the valid bit in
3143859Sml29623 * the subareas 0 and 4
3153859Sml29623 * (4) disable the partition
3163859Sml29623 *
3173859Sml29623 */
3183859Sml29623
3193859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all"));
3203859Sml29623
3213859Sml29623 base_mask = base_reloc = 0x0;
3223859Sml29623 handle = nxgep->npi_reg_handle;
3233859Sml29623 rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc);
3243859Sml29623
3253859Sml29623 if (rs != NPI_SUCCESS) {
3263859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n"));
3273859Sml29623 return (NXGE_ERROR | rs);
3283859Sml29623 }
3293859Sml29623 rs = npi_fflp_cfg_fcram_partition_disable(handle, pid);
3303859Sml29623
3313859Sml29623 if (rs != NPI_SUCCESS) {
3323859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3336929Smisaki "failed partition enable\n"));
3343859Sml29623 return (NXGE_ERROR | rs);
3353859Sml29623 }
3363859Sml29623 fc.dreg[0].value = 0;
3373859Sml29623 fc.hash_hdr_valid = 0;
3383859Sml29623 fc.hash_hdr_ext = 1; /* specify as IPV4 exact match entry */
3393859Sml29623 increment = sizeof (hash_ipv4_t);
3403859Sml29623 last_location = FCRAM_SIZE * 0x40;
3413859Sml29623
3423859Sml29623 for (location = 0; location < last_location; location += increment) {
3433859Sml29623 rs = npi_fflp_fcram_subarea_write(handle, pid,
3446929Smisaki location, fc.value[0]);
3453859Sml29623 if (rs != NPI_SUCCESS) {
3463859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3476929Smisaki "failed write at location %x ", location));
3483859Sml29623 return (NXGE_ERROR | rs);
3493859Sml29623 }
3503859Sml29623 }
3513859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all"));
3523859Sml29623 return (NXGE_OK);
3533859Sml29623 }
3543859Sml29623
3553859Sml29623 static nxge_status_t
nxge_fflp_fcram_init(p_nxge_t nxgep)3563859Sml29623 nxge_fflp_fcram_init(p_nxge_t nxgep)
3573859Sml29623 {
3583859Sml29623 fflp_fcram_output_drive_t strength;
3593859Sml29623 fflp_fcram_qs_t qs;
3603859Sml29623 npi_status_t rs = NPI_SUCCESS;
3613859Sml29623 uint8_t access_ratio;
3623859Sml29623 int partition;
3633859Sml29623 npi_handle_t handle;
3643859Sml29623 uint32_t min_time, max_time, sys_time;
3653859Sml29623
3663859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init"));
3673859Sml29623
3683859Sml29623 /*
3693859Sml29623 * Recommended values are needed.
3703859Sml29623 */
3713859Sml29623 min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME;
3723859Sml29623 max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME;
3733859Sml29623 sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME;
3743859Sml29623
3753859Sml29623 handle = nxgep->npi_reg_handle;
3763859Sml29623 strength = FCRAM_OUTDR_NORMAL;
3773859Sml29623 qs = FCRAM_QS_MODE_QS;
3783859Sml29623 rs = npi_fflp_cfg_fcram_reset(handle, strength, qs);
3793859Sml29623 if (rs != NPI_SUCCESS) {
3803859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. "));
3813859Sml29623 return (NXGE_ERROR | rs);
3823859Sml29623 }
3833859Sml29623
3843859Sml29623 access_ratio = nxgep->param_arr[param_fcram_access_ratio].value;
3853859Sml29623 rs = npi_fflp_cfg_fcram_access(handle, access_ratio);
3863859Sml29623 if (rs != NPI_SUCCESS) {
3873859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio"
3886929Smisaki "configuration \n"));
3893859Sml29623 return (NXGE_ERROR | rs);
3903859Sml29623 }
3913859Sml29623 rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time,
3926929Smisaki max_time, sys_time);
3933859Sml29623 if (rs != NPI_SUCCESS) {
3943859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3956929Smisaki "failed FCRAM refresh cfg"));
3963859Sml29623 return (NXGE_ERROR);
3973859Sml29623 }
3983859Sml29623
3993859Sml29623 /* disable all the partitions until explicitly enabled */
4003859Sml29623 for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) {
4013859Sml29623 rs = npi_fflp_cfg_fcram_partition_disable(handle, partition);
4023859Sml29623 if (rs != NPI_SUCCESS) {
4033859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4046929Smisaki "failed FCRAM partition"
4056929Smisaki " enable for partition %d ", partition));
4063859Sml29623 return (NXGE_ERROR | rs);
4073859Sml29623 }
4083859Sml29623 }
4093859Sml29623
4103859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init"));
4113859Sml29623 return (NXGE_OK);
4123859Sml29623 }
4133859Sml29623
4143859Sml29623 nxge_status_t
nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep,uint8_t alt_mac)4153859Sml29623 nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac)
4163859Sml29623 {
4173859Sml29623 npi_status_t rs = NPI_SUCCESS;
4183859Sml29623 hostinfo_t mac_rdc;
4193859Sml29623 npi_handle_t handle;
4203859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
4213859Sml29623
4223859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
4233859Sml29623 if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) {
4243859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4256929Smisaki " nxge_logical_mac_assign_rdc_table"
4266929Smisaki " unconfigured alt MAC addr %d ", alt_mac));
4273859Sml29623 return (NXGE_ERROR);
4283859Sml29623 }
4293859Sml29623 handle = nxgep->npi_reg_handle;
4303859Sml29623 mac_rdc.value = 0;
4313859Sml29623 mac_rdc.bits.w0.rdc_tbl_num =
4326929Smisaki p_class_cfgp->mac_host_info[alt_mac].rdctbl;
4333859Sml29623 mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr;
4343859Sml29623
4353859Sml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET,
4366929Smisaki nxgep->function_num, alt_mac, &mac_rdc);
4373859Sml29623
4383859Sml29623 if (rs != NPI_SUCCESS) {
4393859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4406929Smisaki "failed Assign RDC table"));
4413859Sml29623 return (NXGE_ERROR | rs);
4423859Sml29623 }
4433859Sml29623 return (NXGE_OK);
4443859Sml29623 }
4453859Sml29623
4463859Sml29623 nxge_status_t
nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)4473859Sml29623 nxge_main_mac_assign_rdc_table(p_nxge_t nxgep)
4483859Sml29623 {
4493859Sml29623 npi_status_t rs = NPI_SUCCESS;
4503859Sml29623 hostinfo_t mac_rdc;
4513859Sml29623 npi_handle_t handle;
452*11878SVenu.Iyer@Sun.COM int i;
4533859Sml29623
4543859Sml29623 handle = nxgep->npi_reg_handle;
4553859Sml29623 mac_rdc.value = 0;
4563859Sml29623 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp;
4573859Sml29623 mac_rdc.bits.w0.mac_pref = 1;
4583859Sml29623 switch (nxgep->function_num) {
4593859Sml29623 case 0:
4603859Sml29623 case 1:
461*11878SVenu.Iyer@Sun.COM /*
462*11878SVenu.Iyer@Sun.COM * Tests indicate that it is OK not to re-initialize the
463*11878SVenu.Iyer@Sun.COM * hostinfo registers for the XMAC's alternate MAC
464*11878SVenu.Iyer@Sun.COM * addresses. But that is necessary for BMAC (case 2
465*11878SVenu.Iyer@Sun.COM * and case 3 below)
466*11878SVenu.Iyer@Sun.COM */
4673859Sml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET,
4686929Smisaki nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
4693859Sml29623 break;
4703859Sml29623 case 2:
4713859Sml29623 case 3:
4723859Sml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET,
4736929Smisaki nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc);
474*11878SVenu.Iyer@Sun.COM for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++)
475*11878SVenu.Iyer@Sun.COM rs |= npi_mac_hostinfo_entry(handle, OP_SET,
476*11878SVenu.Iyer@Sun.COM nxgep->function_num, i, &mac_rdc);
4773859Sml29623 break;
4783859Sml29623 default:
4793859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4806929Smisaki "failed Assign RDC table (invalid function #)"));
4813859Sml29623 return (NXGE_ERROR);
4823859Sml29623 }
4833859Sml29623
4843859Sml29623 if (rs != NPI_SUCCESS) {
4853859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4866929Smisaki "failed Assign RDC table"));
4873859Sml29623 return (NXGE_ERROR | rs);
4883859Sml29623 }
4893859Sml29623 return (NXGE_OK);
4903859Sml29623 }
4913859Sml29623
4923859Sml29623 /*
4933859Sml29623 * Initialize hostinfo registers for alternate MAC addresses and
4943859Sml29623 * multicast MAC address.
4953859Sml29623 */
4963859Sml29623 nxge_status_t
nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)4973859Sml29623 nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep)
4983859Sml29623 {
4993859Sml29623 npi_status_t rs = NPI_SUCCESS;
5003859Sml29623 hostinfo_t mac_rdc;
5013859Sml29623 npi_handle_t handle;
5023859Sml29623
5033859Sml29623 handle = nxgep->npi_reg_handle;
5043859Sml29623 mac_rdc.value = 0;
5053859Sml29623 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp;
5063859Sml29623 mac_rdc.bits.w0.mac_pref = 1;
5073859Sml29623 switch (nxgep->function_num) {
5083859Sml29623 case 0:
5093859Sml29623 case 1:
5103859Sml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET,
511*11878SVenu.Iyer@Sun.COM nxgep->function_num, XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
5123859Sml29623 break;
5133859Sml29623 case 2:
5143859Sml29623 case 3:
515*11878SVenu.Iyer@Sun.COM rs = npi_mac_hostinfo_entry(handle, OP_SET,
516*11878SVenu.Iyer@Sun.COM nxgep->function_num, BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc);
5173859Sml29623 break;
5183859Sml29623 default:
5193859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5206929Smisaki "failed Assign RDC table (invalid function #)"));
5213859Sml29623 return (NXGE_ERROR);
5223859Sml29623 }
5233859Sml29623
5243859Sml29623 if (rs != NPI_SUCCESS) {
5253859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5266929Smisaki "failed Assign RDC table"));
5273859Sml29623 return (NXGE_ERROR | rs);
5283859Sml29623 }
5293859Sml29623 return (NXGE_OK);
5303859Sml29623 }
5313859Sml29623
5323859Sml29623 nxge_status_t
nxge_fflp_init_hostinfo(p_nxge_t nxgep)5333859Sml29623 nxge_fflp_init_hostinfo(p_nxge_t nxgep)
5343859Sml29623 {
5353859Sml29623 nxge_status_t status = NXGE_OK;
5363859Sml29623
5373859Sml29623 status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
5383859Sml29623 status |= nxge_main_mac_assign_rdc_table(nxgep);
5393859Sml29623 return (status);
5403859Sml29623 }
5413859Sml29623
5423859Sml29623 nxge_status_t
nxge_fflp_hw_reset(p_nxge_t nxgep)5433859Sml29623 nxge_fflp_hw_reset(p_nxge_t nxgep)
5443859Sml29623 {
5453859Sml29623 npi_handle_t handle;
5463859Sml29623 npi_status_t rs = NPI_SUCCESS;
5473859Sml29623 nxge_status_t status = NXGE_OK;
5483859Sml29623
5493859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset"));
5503859Sml29623
5514977Sraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
5523859Sml29623 status = nxge_fflp_fcram_init(nxgep);
5533859Sml29623 if (status != NXGE_OK) {
5543859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5556929Smisaki " failed FCRAM init. "));
5563859Sml29623 return (status);
5573859Sml29623 }
5583859Sml29623 }
5593859Sml29623
5603859Sml29623 status = nxge_fflp_tcam_init(nxgep);
5613859Sml29623 if (status != NXGE_OK) {
5623859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5636929Smisaki "failed TCAM init."));
5643859Sml29623 return (status);
5653859Sml29623 }
5663859Sml29623
5673859Sml29623 handle = nxgep->npi_reg_handle;
5683859Sml29623 rs = npi_fflp_cfg_llcsnap_enable(handle);
5693859Sml29623 if (rs != NPI_SUCCESS) {
5703859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5716929Smisaki "failed LLCSNAP enable. "));
5723859Sml29623 return (NXGE_ERROR | rs);
5733859Sml29623 }
5743859Sml29623
5753859Sml29623 rs = npi_fflp_cfg_cam_errorcheck_disable(handle);
5763859Sml29623 if (rs != NPI_SUCCESS) {
5773859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5786929Smisaki "failed CAM Error Check enable. "));
5793859Sml29623 return (NXGE_ERROR | rs);
5803859Sml29623 }
5813859Sml29623
5823859Sml29623 /* init the hash generators */
5833859Sml29623 rs = npi_fflp_cfg_hash_h1poly(handle, 0);
5843859Sml29623 if (rs != NPI_SUCCESS) {
5853859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5866929Smisaki "failed H1 Poly Init. "));
5873859Sml29623 return (NXGE_ERROR | rs);
5883859Sml29623 }
5893859Sml29623
5903859Sml29623 rs = npi_fflp_cfg_hash_h2poly(handle, 0);
5913859Sml29623 if (rs != NPI_SUCCESS) {
5923859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5936929Smisaki "failed H2 Poly Init. "));
5943859Sml29623 return (NXGE_ERROR | rs);
5953859Sml29623 }
5963859Sml29623
5973859Sml29623 /* invalidate TCAM entries */
5983859Sml29623 status = nxge_fflp_tcam_invalidate_all(nxgep);
5993859Sml29623 if (status != NXGE_OK) {
6003859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6016929Smisaki "failed TCAM Entry Invalidate. "));
6023859Sml29623 return (status);
6033859Sml29623 }
6043859Sml29623
6053859Sml29623 /* invalidate FCRAM entries */
6064977Sraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6073859Sml29623 status = nxge_fflp_fcram_invalidate_all(nxgep);
6083859Sml29623 if (status != NXGE_OK) {
6093859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6106929Smisaki "failed FCRAM Entry Invalidate."));
6113859Sml29623 return (status);
6123859Sml29623 }
6133859Sml29623 }
6143859Sml29623
6153859Sml29623 /* invalidate VLAN RDC tables */
6163859Sml29623 status = nxge_fflp_vlan_tbl_clear_all(nxgep);
6173859Sml29623 if (status != NXGE_OK) {
6183859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6196929Smisaki "failed VLAN Table Invalidate. "));
6203859Sml29623 return (status);
6213859Sml29623 }
6223859Sml29623 nxgep->classifier.state |= NXGE_FFLP_HW_RESET;
6233859Sml29623
6243859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset"));
6253859Sml29623 return (NXGE_OK);
6263859Sml29623 }
6273859Sml29623
6283859Sml29623 nxge_status_t
nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep,tcam_class_t l3_class,uint32_t class_config)6293859Sml29623 nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class,
6303859Sml29623 uint32_t class_config)
6313859Sml29623 {
6323859Sml29623 flow_key_cfg_t fcfg;
6333859Sml29623 npi_handle_t handle;
6343859Sml29623 npi_status_t rs = NPI_SUCCESS;
6353859Sml29623
6363859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key"));
6373859Sml29623 handle = nxgep->npi_reg_handle;
6383859Sml29623 bzero(&fcfg, sizeof (flow_key_cfg_t));
6393859Sml29623
6403859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_PROTO)
6413859Sml29623 fcfg.use_proto = 1;
6423859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT)
6433859Sml29623 fcfg.use_dport = 1;
6443859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT)
6453859Sml29623 fcfg.use_sport = 1;
6463859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_IPDST)
6473859Sml29623 fcfg.use_daddr = 1;
6483859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_IPSRC)
6493859Sml29623 fcfg.use_saddr = 1;
6503859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_VLAN)
6513859Sml29623 fcfg.use_vlan = 1;
6523859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_L2DA)
6533859Sml29623 fcfg.use_l2da = 1;
6543859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM)
6553859Sml29623 fcfg.use_portnum = 1;
6563859Sml29623 fcfg.ip_opts_exist = 0;
6573859Sml29623
6583859Sml29623 rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg);
6593859Sml29623 if (rs & NPI_FFLP_ERROR) {
6603859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
6616929Smisaki " opt %x for class %d failed ", class_config, l3_class));
6623859Sml29623 return (NXGE_ERROR | rs);
6633859Sml29623 }
6643859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key"));
6653859Sml29623 return (NXGE_OK);
6663859Sml29623 }
6673859Sml29623
6683859Sml29623 nxge_status_t
nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep,tcam_class_t l3_class,uint32_t * class_config)6693859Sml29623 nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class,
6703859Sml29623 uint32_t *class_config)
6713859Sml29623 {
6723859Sml29623 flow_key_cfg_t fcfg;
6733859Sml29623 npi_handle_t handle;
6743859Sml29623 npi_status_t rs = NPI_SUCCESS;
6753859Sml29623 uint32_t ccfg = 0;
6763859Sml29623
6773859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get"));
6783859Sml29623 handle = nxgep->npi_reg_handle;
6793859Sml29623 bzero(&fcfg, sizeof (flow_key_cfg_t));
6803859Sml29623
6813859Sml29623 rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg);
6823859Sml29623 if (rs & NPI_FFLP_ERROR) {
6833859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key"
6846929Smisaki " opt %x for class %d failed ", class_config, l3_class));
6853859Sml29623 return (NXGE_ERROR | rs);
6863859Sml29623 }
6873859Sml29623
6883859Sml29623 if (fcfg.use_proto)
6893859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_PROTO;
6903859Sml29623 if (fcfg.use_dport)
6913859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT;
6923859Sml29623 if (fcfg.use_sport)
6933859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT;
6943859Sml29623 if (fcfg.use_daddr)
6953859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_IPDST;
6963859Sml29623 if (fcfg.use_saddr)
6973859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_IPSRC;
6983859Sml29623 if (fcfg.use_vlan)
6993859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_VLAN;
7003859Sml29623 if (fcfg.use_l2da)
7013859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_L2DA;
7023859Sml29623 if (fcfg.use_portnum)
7033859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM;
7043859Sml29623
7053859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7066929Smisaki " nxge_cfg_ip_cls_flow_key_get %x", ccfg));
7073859Sml29623 *class_config = ccfg;
7083859Sml29623
7093859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7106929Smisaki " <== nxge_cfg_ip_cls_flow_key_get"));
7113859Sml29623 return (NXGE_OK);
7123859Sml29623 }
7133859Sml29623
7143859Sml29623 static nxge_status_t
nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep,tcam_class_t class,uint32_t * class_config)7153859Sml29623 nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class,
7163859Sml29623 uint32_t *class_config)
7173859Sml29623 {
7183859Sml29623 npi_status_t rs = NPI_SUCCESS;
7193859Sml29623 tcam_key_cfg_t cfg;
7203859Sml29623 npi_handle_t handle;
7213859Sml29623 uint32_t ccfg = 0;
7223859Sml29623
7233859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
7243859Sml29623
7253859Sml29623 bzero(&cfg, sizeof (tcam_key_cfg_t));
7263859Sml29623 handle = nxgep->npi_reg_handle;
7273859Sml29623
7283859Sml29623 rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg);
7293859Sml29623 if (rs & NPI_FFLP_ERROR) {
7303859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
7316929Smisaki " opt %x for class %d failed ", class_config, class));
7323859Sml29623 return (NXGE_ERROR | rs);
7333859Sml29623 }
7343859Sml29623 if (cfg.discard)
7353859Sml29623 ccfg |= NXGE_CLASS_DISCARD;
7363859Sml29623 if (cfg.lookup_enable)
7373859Sml29623 ccfg |= NXGE_CLASS_TCAM_LOOKUP;
7383859Sml29623 if (cfg.use_ip_daddr)
7393859Sml29623 ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR;
7403859Sml29623 *class_config = ccfg;
7413859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
7426929Smisaki " ==> nxge_cfg_tcam_ip_class %x", ccfg));
7433859Sml29623 return (NXGE_OK);
7443859Sml29623 }
7453859Sml29623
7463859Sml29623 static nxge_status_t
nxge_cfg_tcam_ip_class(p_nxge_t nxgep,tcam_class_t class,uint32_t class_config)7473859Sml29623 nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class,
7483859Sml29623 uint32_t class_config)
7493859Sml29623 {
7503859Sml29623 npi_status_t rs = NPI_SUCCESS;
7513859Sml29623 tcam_key_cfg_t cfg;
7523859Sml29623 npi_handle_t handle;
7533859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
7543859Sml29623
7553859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class"));
7563859Sml29623
7573859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7583859Sml29623 p_class_cfgp->class_cfg[class] = class_config;
7593859Sml29623
7603859Sml29623 bzero(&cfg, sizeof (tcam_key_cfg_t));
7613859Sml29623 handle = nxgep->npi_reg_handle;
7623859Sml29623 cfg.discard = 0;
7633859Sml29623 cfg.lookup_enable = 0;
7643859Sml29623 cfg.use_ip_daddr = 0;
7653859Sml29623 if (class_config & NXGE_CLASS_DISCARD)
7663859Sml29623 cfg.discard = 1;
7673859Sml29623 if (class_config & NXGE_CLASS_TCAM_LOOKUP)
7683859Sml29623 cfg.lookup_enable = 1;
7693859Sml29623 if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR)
7703859Sml29623 cfg.use_ip_daddr = 1;
7713859Sml29623
7723859Sml29623 rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg);
7733859Sml29623 if (rs & NPI_FFLP_ERROR) {
7743859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class"
7756929Smisaki " opt %x for class %d failed ", class_config, class));
7763859Sml29623 return (NXGE_ERROR | rs);
7773859Sml29623 }
7783859Sml29623 return (NXGE_OK);
7793859Sml29623 }
7803859Sml29623
7813859Sml29623 nxge_status_t
nxge_fflp_set_hash1(p_nxge_t nxgep,uint32_t h1)7823859Sml29623 nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1)
7833859Sml29623 {
7843859Sml29623 npi_status_t rs = NPI_SUCCESS;
7853859Sml29623 npi_handle_t handle;
7863859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
7873859Sml29623
7883859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1"));
7893859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
7903859Sml29623 p_class_cfgp->init_h1 = h1;
7913859Sml29623 handle = nxgep->npi_reg_handle;
7923859Sml29623 rs = npi_fflp_cfg_hash_h1poly(handle, h1);
7933859Sml29623 if (rs & NPI_FFLP_ERROR) {
7943859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
7956929Smisaki " nxge_fflp_init_h1 %x failed ", h1));
7963859Sml29623 return (NXGE_ERROR | rs);
7973859Sml29623 }
7983859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1"));
7993859Sml29623 return (NXGE_OK);
8003859Sml29623 }
8013859Sml29623
8023859Sml29623 nxge_status_t
nxge_fflp_set_hash2(p_nxge_t nxgep,uint16_t h2)8033859Sml29623 nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2)
8043859Sml29623 {
8053859Sml29623 npi_status_t rs = NPI_SUCCESS;
8063859Sml29623 npi_handle_t handle;
8073859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
8083859Sml29623
8093859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2"));
8103859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
8113859Sml29623 p_class_cfgp->init_h2 = h2;
8123859Sml29623
8133859Sml29623 handle = nxgep->npi_reg_handle;
8143859Sml29623 rs = npi_fflp_cfg_hash_h2poly(handle, h2);
8153859Sml29623 if (rs & NPI_FFLP_ERROR) {
8163859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8176929Smisaki " nxge_fflp_init_h2 %x failed ", h2));
8183859Sml29623 return (NXGE_ERROR | rs);
8193859Sml29623 }
8203859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2"));
8213859Sml29623 return (NXGE_OK);
8223859Sml29623 }
8233859Sml29623
8243859Sml29623 nxge_status_t
nxge_classify_init_sw(p_nxge_t nxgep)8253859Sml29623 nxge_classify_init_sw(p_nxge_t nxgep)
8263859Sml29623 {
8273859Sml29623 nxge_classify_t *classify_ptr;
8283859Sml29623
8293859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw"));
8303859Sml29623 classify_ptr = &nxgep->classifier;
8313859Sml29623
8323859Sml29623 if (classify_ptr->state & NXGE_FFLP_SW_INIT) {
8333859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
8346929Smisaki "nxge_classify_init_sw already init"));
8353859Sml29623 return (NXGE_OK);
8363859Sml29623 }
83711304SJanie.Lu@Sun.COM
83811304SJanie.Lu@Sun.COM classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports;
83911304SJanie.Lu@Sun.COM classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam;
84011304SJanie.Lu@Sun.COM classify_ptr->tcam_top = nxgep->function_num;
8413859Sml29623
8423859Sml29623 /* Init defaults */
8433859Sml29623 /*
8443859Sml29623 * add hacks required for HW shortcomings for example, code to handle
8453859Sml29623 * fragmented packets
8463859Sml29623 */
8473859Sml29623 nxge_init_h1_table();
8483859Sml29623 nxge_crc_ccitt_init();
8493859Sml29623 nxgep->classifier.tcam_location = nxgep->function_num;
8503859Sml29623 nxgep->classifier.fragment_bug = 1;
8513859Sml29623 classify_ptr->state |= NXGE_FFLP_SW_INIT;
8523859Sml29623
8533859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw"));
8543859Sml29623 return (NXGE_OK);
8553859Sml29623 }
8563859Sml29623
8573859Sml29623 nxge_status_t
nxge_classify_exit_sw(p_nxge_t nxgep)8583859Sml29623 nxge_classify_exit_sw(p_nxge_t nxgep)
8593859Sml29623 {
8603859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw"));
8613859Sml29623 nxgep->classifier.state = NULL;
8623859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw"));
8633859Sml29623 return (NXGE_OK);
8643859Sml29623 }
8653859Sml29623
8663859Sml29623 /*
8673859Sml29623 * Figures out the RDC Group for the entry
8683859Sml29623 *
8693859Sml29623 * The current implementation is just a place holder and it
8703859Sml29623 * returns 0.
8713859Sml29623 * The real location determining algorithm would consider
8723859Sml29623 * the partition etc ... before deciding w
8733859Sml29623 *
8743859Sml29623 */
8753859Sml29623
8763859Sml29623 /* ARGSUSED */
8773859Sml29623 static uint8_t
nxge_get_rdc_group(p_nxge_t nxgep,uint8_t class,uint64_t cookie)87811304SJanie.Lu@Sun.COM nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
8793859Sml29623 {
8803859Sml29623 int use_port_rdc_grp = 0;
8813859Sml29623 uint8_t rdc_grp = 0;
8823859Sml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp;
8833859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp;
8843859Sml29623 p_nxge_rdc_grp_t rdc_grp_p;
8853859Sml29623
8863859Sml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
8873859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
8883859Sml29623 rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp];
8896495Sspeer rdc_grp = p_cfgp->def_mac_rxdma_grpid;
8903859Sml29623
8913859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8926929Smisaki "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n",
8936929Smisaki cookie, rdc_grp, rdc_grp_p));
8943859Sml29623 return (rdc_grp);
8953859Sml29623 }
8963859Sml29623
8973859Sml29623 /* ARGSUSED */
8983859Sml29623 static uint8_t
nxge_get_rdc_offset(p_nxge_t nxgep,uint8_t class,uint64_t cookie)89911304SJanie.Lu@Sun.COM nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie)
9003859Sml29623 {
9013859Sml29623 return ((uint8_t)cookie);
9023859Sml29623 }
9033859Sml29623
9043859Sml29623 /* ARGSUSED */
9053859Sml29623 static void
nxge_fill_tcam_entry_udp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9063859Sml29623 nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9073859Sml29623 tcam_entry_t *tcam_ptr)
9083859Sml29623 {
9093859Sml29623 udpip4_spec_t *fspec_key;
9103859Sml29623 udpip4_spec_t *fspec_mask;
9113859Sml29623
9123859Sml29623 fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec;
9133859Sml29623 fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec;
9143859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
9153859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
9163859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
9173859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
9183859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
9196929Smisaki fspec_key->pdst, fspec_key->psrc);
9203859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
9216929Smisaki fspec_mask->pdst, fspec_mask->psrc);
9223859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
9236929Smisaki tcam_ptr->ip4_class_mask,
9246929Smisaki TCAM_CLASS_UDP_IPV4);
9253859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
9266929Smisaki tcam_ptr->ip4_proto_mask,
9276929Smisaki IPPROTO_UDP);
92811304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos;
92911304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos;
9303859Sml29623 }
9313859Sml29623
9323859Sml29623 static void
nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9333859Sml29623 nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
9343859Sml29623 tcam_entry_t *tcam_ptr)
9353859Sml29623 {
9363859Sml29623 udpip6_spec_t *fspec_key;
9373859Sml29623 udpip6_spec_t *fspec_mask;
9383859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
9393859Sml29623
9403859Sml29623 fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec;
9413859Sml29623 fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec;
9423859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
9433859Sml29623 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
9446929Smisaki NXGE_CLASS_TCAM_USE_SRC_ADDR) {
9453859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
9463859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
9473859Sml29623 } else {
9483859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
9493859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
9503859Sml29623 }
9513859Sml29623
9523859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
9536929Smisaki tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6);
9543859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
9556929Smisaki tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP);
9563859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
9576929Smisaki fspec_key->pdst, fspec_key->psrc);
9583859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
9596929Smisaki fspec_mask->pdst, fspec_mask->psrc);
96011304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_key = fspec_key->tos;
96111304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_mask = fspec_mask->tos;
9623859Sml29623 }
9633859Sml29623
9643859Sml29623 /* ARGSUSED */
9653859Sml29623 static void
nxge_fill_tcam_entry_tcp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9663859Sml29623 nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9673859Sml29623 tcam_entry_t *tcam_ptr)
9683859Sml29623 {
9693859Sml29623 tcpip4_spec_t *fspec_key;
9703859Sml29623 tcpip4_spec_t *fspec_mask;
9713859Sml29623
9723859Sml29623 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
9733859Sml29623 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
9743859Sml29623
9753859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
9763859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
9773859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
9783859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
9793859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
9806929Smisaki fspec_key->pdst, fspec_key->psrc);
9813859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
9826929Smisaki fspec_mask->pdst, fspec_mask->psrc);
9833859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
9846929Smisaki tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4);
9853859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
9866929Smisaki tcam_ptr->ip4_proto_mask, IPPROTO_TCP);
98711304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos;
98811304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos;
9893859Sml29623 }
9903859Sml29623
9913859Sml29623 /* ARGSUSED */
9923859Sml29623 static void
nxge_fill_tcam_entry_sctp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)9933859Sml29623 nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec,
9943859Sml29623 tcam_entry_t *tcam_ptr)
9953859Sml29623 {
9963859Sml29623 tcpip4_spec_t *fspec_key;
9973859Sml29623 tcpip4_spec_t *fspec_mask;
9983859Sml29623
9993859Sml29623 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec;
10003859Sml29623 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec;
10013859Sml29623
10023859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
10033859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
10043859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
10053859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
10063859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
10076929Smisaki tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4);
10083859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
10096929Smisaki tcam_ptr->ip4_proto_mask, IPPROTO_SCTP);
10103859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_key,
10116929Smisaki fspec_key->pdst, fspec_key->psrc);
10123859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask,
10136929Smisaki fspec_mask->pdst, fspec_mask->psrc);
101411304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos;
101511304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos;
10163859Sml29623 }
10173859Sml29623
10183859Sml29623 static void
nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)10193859Sml29623 nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
10203859Sml29623 tcam_entry_t *tcam_ptr)
10213859Sml29623 {
10223859Sml29623 tcpip6_spec_t *fspec_key;
10233859Sml29623 tcpip6_spec_t *fspec_mask;
10243859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
10253859Sml29623
10263859Sml29623 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10273859Sml29623 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10283859Sml29623
10293859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10303859Sml29623 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
10316929Smisaki NXGE_CLASS_TCAM_USE_SRC_ADDR) {
10323859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
10333859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
10343859Sml29623 } else {
10353859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
10363859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
10373859Sml29623 }
10383859Sml29623
10393859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
10406929Smisaki tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6);
10413859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
10426929Smisaki tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP);
10433859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
10446929Smisaki fspec_key->pdst, fspec_key->psrc);
10453859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
10466929Smisaki fspec_mask->pdst, fspec_mask->psrc);
104711304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_key = fspec_key->tos;
104811304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_mask = fspec_mask->tos;
10493859Sml29623 }
10503859Sml29623
10513859Sml29623 static void
nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)10523859Sml29623 nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
10533859Sml29623 tcam_entry_t *tcam_ptr)
10543859Sml29623 {
10553859Sml29623 tcpip6_spec_t *fspec_key;
10563859Sml29623 tcpip6_spec_t *fspec_mask;
10573859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
10583859Sml29623
10593859Sml29623 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec;
10603859Sml29623 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec;
10613859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
10623859Sml29623
10633859Sml29623 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] &
10646929Smisaki NXGE_CLASS_TCAM_USE_SRC_ADDR) {
10653859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
10663859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
10673859Sml29623 } else {
10683859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
10693859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
10703859Sml29623 }
10713859Sml29623
10723859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
10736929Smisaki tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6);
10743859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
10756929Smisaki tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP);
10763859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_key,
10776929Smisaki fspec_key->pdst, fspec_key->psrc);
10783859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask,
10796929Smisaki fspec_mask->pdst, fspec_mask->psrc);
108011304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_key = fspec_key->tos;
108111304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_mask = fspec_mask->tos;
10823859Sml29623 }
10833859Sml29623
108411304SJanie.Lu@Sun.COM /* ARGSUSED */
108511304SJanie.Lu@Sun.COM static void
nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)108611304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec,
108711304SJanie.Lu@Sun.COM tcam_entry_t *tcam_ptr)
108811304SJanie.Lu@Sun.COM {
108911304SJanie.Lu@Sun.COM ahip4_spec_t *fspec_key;
109011304SJanie.Lu@Sun.COM ahip4_spec_t *fspec_mask;
109111304SJanie.Lu@Sun.COM
109211304SJanie.Lu@Sun.COM fspec_key = (ahip4_spec_t *)&flow_spec->uh.ahip4spec;
109311304SJanie.Lu@Sun.COM fspec_mask = (ahip4_spec_t *)&flow_spec->um.ahip4spec;
109411304SJanie.Lu@Sun.COM
109511304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
109611304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
109711304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
109811304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
109911304SJanie.Lu@Sun.COM
110011304SJanie.Lu@Sun.COM tcam_ptr->ip4_port_key = fspec_key->spi;
110111304SJanie.Lu@Sun.COM tcam_ptr->ip4_port_mask = fspec_mask->spi;
110211304SJanie.Lu@Sun.COM
110311304SJanie.Lu@Sun.COM TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
110411304SJanie.Lu@Sun.COM tcam_ptr->ip4_class_mask,
110511304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV4);
110611304SJanie.Lu@Sun.COM
110711304SJanie.Lu@Sun.COM if (flow_spec->flow_type == FSPEC_AHIP4) {
110811304SJanie.Lu@Sun.COM TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
110911304SJanie.Lu@Sun.COM tcam_ptr->ip4_proto_mask, IPPROTO_AH);
111011304SJanie.Lu@Sun.COM } else {
111111304SJanie.Lu@Sun.COM TCAM_IP_PROTO(tcam_ptr->ip4_proto_key,
111211304SJanie.Lu@Sun.COM tcam_ptr->ip4_proto_mask, IPPROTO_ESP);
111311304SJanie.Lu@Sun.COM }
111411304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos;
111511304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos;
111611304SJanie.Lu@Sun.COM }
111711304SJanie.Lu@Sun.COM
111811304SJanie.Lu@Sun.COM static void
nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep,flow_spec_t * flow_spec,tcam_entry_t * tcam_ptr)111911304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec,
112011304SJanie.Lu@Sun.COM tcam_entry_t *tcam_ptr)
112111304SJanie.Lu@Sun.COM {
112211304SJanie.Lu@Sun.COM ahip6_spec_t *fspec_key;
112311304SJanie.Lu@Sun.COM ahip6_spec_t *fspec_mask;
112411304SJanie.Lu@Sun.COM p_nxge_class_pt_cfg_t p_class_cfgp;
112511304SJanie.Lu@Sun.COM
112611304SJanie.Lu@Sun.COM fspec_key = (ahip6_spec_t *)&flow_spec->uh.ahip6spec;
112711304SJanie.Lu@Sun.COM fspec_mask = (ahip6_spec_t *)&flow_spec->um.ahip6spec;
112811304SJanie.Lu@Sun.COM
112911304SJanie.Lu@Sun.COM p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
113011304SJanie.Lu@Sun.COM if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] &
113111304SJanie.Lu@Sun.COM NXGE_CLASS_TCAM_USE_SRC_ADDR) {
113211304SJanie.Lu@Sun.COM TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src);
113311304SJanie.Lu@Sun.COM TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src);
113411304SJanie.Lu@Sun.COM } else {
113511304SJanie.Lu@Sun.COM TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst);
113611304SJanie.Lu@Sun.COM TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst);
113711304SJanie.Lu@Sun.COM }
113811304SJanie.Lu@Sun.COM
113911304SJanie.Lu@Sun.COM TCAM_IP_CLASS(tcam_ptr->ip6_class_key,
114011304SJanie.Lu@Sun.COM tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6);
114111304SJanie.Lu@Sun.COM
114211304SJanie.Lu@Sun.COM if (flow_spec->flow_type == FSPEC_AHIP6) {
114311304SJanie.Lu@Sun.COM TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
114411304SJanie.Lu@Sun.COM tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH);
114511304SJanie.Lu@Sun.COM } else {
114611304SJanie.Lu@Sun.COM TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key,
114711304SJanie.Lu@Sun.COM tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP);
114811304SJanie.Lu@Sun.COM }
114911304SJanie.Lu@Sun.COM tcam_ptr->ip6_port_key = fspec_key->spi;
115011304SJanie.Lu@Sun.COM tcam_ptr->ip6_port_mask = fspec_mask->spi;
115111304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_key = fspec_key->tos;
115211304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_mask = fspec_mask->tos;
115311304SJanie.Lu@Sun.COM }
115411304SJanie.Lu@Sun.COM
115511304SJanie.Lu@Sun.COM /* ARGSUSED */
115611304SJanie.Lu@Sun.COM 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)115711304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec,
115811304SJanie.Lu@Sun.COM tcam_entry_t *tcam_ptr, tcam_class_t class)
115911304SJanie.Lu@Sun.COM {
116011304SJanie.Lu@Sun.COM ip_user_spec_t *fspec_key;
116111304SJanie.Lu@Sun.COM ip_user_spec_t *fspec_mask;
116211304SJanie.Lu@Sun.COM
116311304SJanie.Lu@Sun.COM fspec_key = (ip_user_spec_t *)&flow_spec->uh.ip_usr_spec;
116411304SJanie.Lu@Sun.COM fspec_mask = (ip_user_spec_t *)&flow_spec->um.ip_usr_spec;
116511304SJanie.Lu@Sun.COM
116611304SJanie.Lu@Sun.COM if (fspec_key->ip_ver == FSPEC_IP4) {
116711304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst);
116811304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst);
116911304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src);
117011304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src);
117111304SJanie.Lu@Sun.COM
117211304SJanie.Lu@Sun.COM tcam_ptr->ip4_port_key = fspec_key->l4_4_bytes;
117311304SJanie.Lu@Sun.COM tcam_ptr->ip4_port_mask = fspec_mask->l4_4_bytes;
117411304SJanie.Lu@Sun.COM
117511304SJanie.Lu@Sun.COM TCAM_IP_CLASS(tcam_ptr->ip4_class_key,
117611304SJanie.Lu@Sun.COM tcam_ptr->ip4_class_mask, class);
117711304SJanie.Lu@Sun.COM
117811304SJanie.Lu@Sun.COM tcam_ptr->ip4_proto_key = fspec_key->proto;
117911304SJanie.Lu@Sun.COM tcam_ptr->ip4_proto_mask = fspec_mask->proto;
118011304SJanie.Lu@Sun.COM
118111304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos;
118211304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos;
118311304SJanie.Lu@Sun.COM }
118411304SJanie.Lu@Sun.COM }
118511304SJanie.Lu@Sun.COM
118611304SJanie.Lu@Sun.COM
11873859Sml29623 nxge_status_t
nxge_flow_get_hash(p_nxge_t nxgep,flow_resource_t * flow_res,uint32_t * H1,uint16_t * H2)11883859Sml29623 nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res,
11893859Sml29623 uint32_t *H1, uint16_t *H2)
11903859Sml29623 {
11913859Sml29623 flow_spec_t *flow_spec;
11923859Sml29623 uint32_t class_cfg;
11933859Sml29623 flow_template_t ft;
11943859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
11953859Sml29623
11963859Sml29623 int ft_size = sizeof (flow_template_t);
11973859Sml29623
11983859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash"));
11993859Sml29623
12003859Sml29623 flow_spec = (flow_spec_t *)&flow_res->flow_spec;
12013859Sml29623 bzero((char *)&ft, ft_size);
12023859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
12033859Sml29623
12043859Sml29623 switch (flow_spec->flow_type) {
12053859Sml29623 case FSPEC_TCPIP4:
12063859Sml29623 class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4];
12073859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
12083859Sml29623 ft.ip_proto = IPPROTO_TCP;
12093859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
12103859Sml29623 ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src;
12113859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
12123859Sml29623 ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst;
12133859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
12143859Sml29623 ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc;
12153859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
12163859Sml29623 ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst;
12173859Sml29623 break;
12183859Sml29623
12193859Sml29623 case FSPEC_UDPIP4:
12203859Sml29623 class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4];
12213859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO)
12223859Sml29623 ft.ip_proto = IPPROTO_UDP;
12233859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC)
12243859Sml29623 ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src;
12253859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST)
12263859Sml29623 ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst;
12273859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT)
12283859Sml29623 ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc;
12293859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT)
12303859Sml29623 ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst;
12313859Sml29623 break;
12323859Sml29623
12333859Sml29623 default:
12343859Sml29623 return (NXGE_ERROR);
12353859Sml29623 }
12363859Sml29623
12373859Sml29623 *H1 = nxge_compute_h1(p_class_cfgp->init_h1,
12386929Smisaki (uint32_t *)&ft, ft_size) & 0xfffff;
12393859Sml29623 *H2 = nxge_compute_h2(p_class_cfgp->init_h2,
12406929Smisaki (uint8_t *)&ft, ft_size);
12413859Sml29623
12423859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash"));
12433859Sml29623 return (NXGE_OK);
12443859Sml29623 }
12453859Sml29623
12463859Sml29623 nxge_status_t
nxge_add_fcram_entry(p_nxge_t nxgep,flow_resource_t * flow_res)12473859Sml29623 nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
12483859Sml29623 {
12493859Sml29623 uint32_t H1;
12503859Sml29623 uint16_t H2;
12513859Sml29623 nxge_status_t status = NXGE_OK;
12523859Sml29623
12533859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry"));
12543859Sml29623 status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2);
12553859Sml29623 if (status != NXGE_OK) {
12563859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
12576929Smisaki " nxge_add_fcram_entry failed "));
12583859Sml29623 return (status);
12593859Sml29623 }
12603859Sml29623
12613859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry"));
12623859Sml29623 return (NXGE_OK);
12633859Sml29623 }
12643859Sml29623
12653859Sml29623 /*
12663859Sml29623 * Already decided this flow goes into the tcam
12673859Sml29623 */
12683859Sml29623
12693859Sml29623 nxge_status_t
nxge_add_tcam_entry(p_nxge_t nxgep,flow_resource_t * flow_res)12703859Sml29623 nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res)
12713859Sml29623 {
12723859Sml29623 npi_handle_t handle;
127311304SJanie.Lu@Sun.COM uint64_t channel_cookie;
127411304SJanie.Lu@Sun.COM uint64_t flow_cookie;
12753859Sml29623 flow_spec_t *flow_spec;
12763859Sml29623 npi_status_t rs = NPI_SUCCESS;
12773859Sml29623 tcam_entry_t tcam_ptr;
127811304SJanie.Lu@Sun.COM tcam_location_t location;
12793859Sml29623 uint8_t offset, rdc_grp;
12803859Sml29623 p_nxge_hw_list_t hw_p;
128111304SJanie.Lu@Sun.COM uint64_t class;
12823859Sml29623
12833859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry"));
12843859Sml29623 handle = nxgep->npi_reg_handle;
12853859Sml29623
12863859Sml29623 bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
12873859Sml29623 flow_spec = (flow_spec_t *)&flow_res->flow_spec;
12883859Sml29623 flow_cookie = flow_res->flow_cookie;
12893859Sml29623 channel_cookie = flow_res->channel_cookie;
129011304SJanie.Lu@Sun.COM location = (tcam_location_t)nxge_tcam_get_index(nxgep,
129111304SJanie.Lu@Sun.COM (uint16_t)flow_res->location);
129211304SJanie.Lu@Sun.COM
129311304SJanie.Lu@Sun.COM if ((hw_p = nxgep->nxge_hw_p) == NULL) {
129411304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
129511304SJanie.Lu@Sun.COM " nxge_add_tcam_entry: common hardware not set",
129611304SJanie.Lu@Sun.COM nxgep->niu_type));
129711304SJanie.Lu@Sun.COM return (NXGE_ERROR);
129811304SJanie.Lu@Sun.COM }
129911304SJanie.Lu@Sun.COM
130011304SJanie.Lu@Sun.COM if (flow_spec->flow_type == FSPEC_IP_USR) {
130111304SJanie.Lu@Sun.COM int i;
130211304SJanie.Lu@Sun.COM int add_usr_cls = 0;
130311304SJanie.Lu@Sun.COM int ipv6 = 0;
130411304SJanie.Lu@Sun.COM ip_user_spec_t *uspec = &flow_spec->uh.ip_usr_spec;
130511304SJanie.Lu@Sun.COM ip_user_spec_t *umask = &flow_spec->um.ip_usr_spec;
130611304SJanie.Lu@Sun.COM nxge_usr_l3_cls_t *l3_ucls_p;
130711304SJanie.Lu@Sun.COM
130811304SJanie.Lu@Sun.COM MUTEX_ENTER(&hw_p->nxge_tcam_lock);
130911304SJanie.Lu@Sun.COM
131011304SJanie.Lu@Sun.COM for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
131111304SJanie.Lu@Sun.COM l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
131211304SJanie.Lu@Sun.COM if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) {
131311304SJanie.Lu@Sun.COM if (uspec->proto == l3_ucls_p->pid) {
131411304SJanie.Lu@Sun.COM class = l3_ucls_p->cls;
131511304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt++;
131611304SJanie.Lu@Sun.COM add_usr_cls = 1;
131711304SJanie.Lu@Sun.COM break;
131811304SJanie.Lu@Sun.COM }
131911304SJanie.Lu@Sun.COM } else if (l3_ucls_p->valid == 0) {
132011304SJanie.Lu@Sun.COM /* Program new user IP class */
132111304SJanie.Lu@Sun.COM switch (i) {
132211304SJanie.Lu@Sun.COM case 0:
132311304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_4;
132411304SJanie.Lu@Sun.COM break;
132511304SJanie.Lu@Sun.COM case 1:
132611304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_5;
132711304SJanie.Lu@Sun.COM break;
132811304SJanie.Lu@Sun.COM case 2:
132911304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_6;
133011304SJanie.Lu@Sun.COM break;
133111304SJanie.Lu@Sun.COM case 3:
133211304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_7;
133311304SJanie.Lu@Sun.COM break;
133411304SJanie.Lu@Sun.COM default:
133511304SJanie.Lu@Sun.COM break;
133611304SJanie.Lu@Sun.COM }
133711304SJanie.Lu@Sun.COM if (uspec->ip_ver == FSPEC_IP6)
133811304SJanie.Lu@Sun.COM ipv6 = 1;
133911304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set(handle,
134011304SJanie.Lu@Sun.COM (tcam_class_t)class, uspec->tos,
134111304SJanie.Lu@Sun.COM umask->tos, uspec->proto, ipv6);
134211304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
134311304SJanie.Lu@Sun.COM goto fail;
134411304SJanie.Lu@Sun.COM
134511304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
134611304SJanie.Lu@Sun.COM (tcam_class_t)class);
134711304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
134811304SJanie.Lu@Sun.COM goto fail;
134911304SJanie.Lu@Sun.COM
135011304SJanie.Lu@Sun.COM l3_ucls_p->cls = class;
135111304SJanie.Lu@Sun.COM l3_ucls_p->pid = uspec->proto;
135211304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt++;
135311304SJanie.Lu@Sun.COM l3_ucls_p->valid = 1;
135411304SJanie.Lu@Sun.COM add_usr_cls = 1;
135511304SJanie.Lu@Sun.COM break;
135611304SJanie.Lu@Sun.COM } else if (l3_ucls_p->tcam_ref_cnt == 0 &&
135711304SJanie.Lu@Sun.COM uspec->proto == l3_ucls_p->pid) {
135811304SJanie.Lu@Sun.COM /*
135911304SJanie.Lu@Sun.COM * The class has already been programmed,
136011304SJanie.Lu@Sun.COM * probably for flow hash
136111304SJanie.Lu@Sun.COM */
136211304SJanie.Lu@Sun.COM class = l3_ucls_p->cls;
136311304SJanie.Lu@Sun.COM if (uspec->ip_ver == FSPEC_IP6)
136411304SJanie.Lu@Sun.COM ipv6 = 1;
136511304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set(handle,
136611304SJanie.Lu@Sun.COM (tcam_class_t)class, uspec->tos,
136711304SJanie.Lu@Sun.COM umask->tos, uspec->proto, ipv6);
136811304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
136911304SJanie.Lu@Sun.COM goto fail;
137011304SJanie.Lu@Sun.COM
137111304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
137211304SJanie.Lu@Sun.COM (tcam_class_t)class);
137311304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
137411304SJanie.Lu@Sun.COM goto fail;
137511304SJanie.Lu@Sun.COM
137611304SJanie.Lu@Sun.COM l3_ucls_p->pid = uspec->proto;
137711304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt++;
137811304SJanie.Lu@Sun.COM add_usr_cls = 1;
137911304SJanie.Lu@Sun.COM break;
138011304SJanie.Lu@Sun.COM }
138111304SJanie.Lu@Sun.COM }
138211304SJanie.Lu@Sun.COM if (!add_usr_cls) {
138311304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
138411304SJanie.Lu@Sun.COM "nxge_add_tcam_entry: Could not find/insert class"
138511304SJanie.Lu@Sun.COM "for pid %d", uspec->proto));
138611304SJanie.Lu@Sun.COM goto fail;
138711304SJanie.Lu@Sun.COM }
138811304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock);
138911304SJanie.Lu@Sun.COM }
13903859Sml29623
13913859Sml29623 switch (flow_spec->flow_type) {
13923859Sml29623 case FSPEC_TCPIP4:
13933859Sml29623 nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr);
13943859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4,
13956929Smisaki flow_cookie);
13963859Sml29623 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4,
13976929Smisaki channel_cookie);
13983859Sml29623 break;
13993859Sml29623
14003859Sml29623 case FSPEC_UDPIP4:
14013859Sml29623 nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr);
14023859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep,
14036929Smisaki TCAM_CLASS_UDP_IPV4,
14046929Smisaki flow_cookie);
14053859Sml29623 offset = nxge_get_rdc_offset(nxgep,
14066929Smisaki TCAM_CLASS_UDP_IPV4,
14076929Smisaki channel_cookie);
14083859Sml29623 break;
14093859Sml29623
14103859Sml29623 case FSPEC_TCPIP6:
14113859Sml29623 nxge_fill_tcam_entry_tcp_ipv6(nxgep,
14126929Smisaki flow_spec, &tcam_ptr);
14133859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6,
14146929Smisaki flow_cookie);
14153859Sml29623 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6,
14166929Smisaki channel_cookie);
14173859Sml29623 break;
14183859Sml29623
14193859Sml29623 case FSPEC_UDPIP6:
14203859Sml29623 nxge_fill_tcam_entry_udp_ipv6(nxgep,
14216929Smisaki flow_spec, &tcam_ptr);
14223859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep,
14236929Smisaki TCAM_CLASS_UDP_IPV6,
142411304SJanie.Lu@Sun.COM flow_cookie);
14253859Sml29623 offset = nxge_get_rdc_offset(nxgep,
14266929Smisaki TCAM_CLASS_UDP_IPV6,
142711304SJanie.Lu@Sun.COM channel_cookie);
14283859Sml29623 break;
14293859Sml29623
14303859Sml29623 case FSPEC_SCTPIP4:
14313859Sml29623 nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr);
14323859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep,
14336929Smisaki TCAM_CLASS_SCTP_IPV4,
143411304SJanie.Lu@Sun.COM flow_cookie);
14353859Sml29623 offset = nxge_get_rdc_offset(nxgep,
14366929Smisaki TCAM_CLASS_SCTP_IPV4,
143711304SJanie.Lu@Sun.COM channel_cookie);
14383859Sml29623 break;
14393859Sml29623
14403859Sml29623 case FSPEC_SCTPIP6:
14413859Sml29623 nxge_fill_tcam_entry_sctp_ipv6(nxgep,
14426929Smisaki flow_spec, &tcam_ptr);
14433859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep,
14446929Smisaki TCAM_CLASS_SCTP_IPV6,
144511304SJanie.Lu@Sun.COM flow_cookie);
144611304SJanie.Lu@Sun.COM offset = nxge_get_rdc_offset(nxgep,
144711304SJanie.Lu@Sun.COM TCAM_CLASS_SCTP_IPV6,
14486929Smisaki channel_cookie);
144911304SJanie.Lu@Sun.COM break;
145011304SJanie.Lu@Sun.COM
145111304SJanie.Lu@Sun.COM case FSPEC_AHIP4:
145211304SJanie.Lu@Sun.COM case FSPEC_ESPIP4:
145311304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp(nxgep, flow_spec, &tcam_ptr);
145411304SJanie.Lu@Sun.COM rdc_grp = nxge_get_rdc_group(nxgep,
145511304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV4,
145611304SJanie.Lu@Sun.COM flow_cookie);
14573859Sml29623 offset = nxge_get_rdc_offset(nxgep,
145811304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV4,
145911304SJanie.Lu@Sun.COM channel_cookie);
14603859Sml29623 break;
14613859Sml29623
146211304SJanie.Lu@Sun.COM case FSPEC_AHIP6:
146311304SJanie.Lu@Sun.COM case FSPEC_ESPIP6:
146411304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp_ipv6(nxgep,
146511304SJanie.Lu@Sun.COM flow_spec, &tcam_ptr);
146611304SJanie.Lu@Sun.COM rdc_grp = nxge_get_rdc_group(nxgep,
146711304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV6,
146811304SJanie.Lu@Sun.COM flow_cookie);
146911304SJanie.Lu@Sun.COM offset = nxge_get_rdc_offset(nxgep,
147011304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV6,
147111304SJanie.Lu@Sun.COM channel_cookie);
147211304SJanie.Lu@Sun.COM break;
147311304SJanie.Lu@Sun.COM
147411304SJanie.Lu@Sun.COM case FSPEC_IP_USR:
147511304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ip_usr(nxgep, flow_spec, &tcam_ptr,
147611304SJanie.Lu@Sun.COM (tcam_class_t)class);
147711304SJanie.Lu@Sun.COM rdc_grp = nxge_get_rdc_group(nxgep,
147811304SJanie.Lu@Sun.COM (tcam_class_t)class, flow_cookie);
147911304SJanie.Lu@Sun.COM offset = nxge_get_rdc_offset(nxgep,
148011304SJanie.Lu@Sun.COM (tcam_class_t)class, channel_cookie);
148111304SJanie.Lu@Sun.COM break;
14823859Sml29623 default:
148311304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
148411304SJanie.Lu@Sun.COM "nxge_add_tcam_entry: Unknown flow spec 0x%x",
148511304SJanie.Lu@Sun.COM flow_spec->flow_type));
148611304SJanie.Lu@Sun.COM return (NXGE_ERROR);
14873859Sml29623 }
14883859Sml29623
14893859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
14906929Smisaki " nxge_add_tcam_entry write"
14916929Smisaki " for location %d offset %d", location, offset));
14923859Sml29623
14933859Sml29623 MUTEX_ENTER(&hw_p->nxge_tcam_lock);
14943859Sml29623 rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr);
14953859Sml29623
14963859Sml29623 if (rs & NPI_FFLP_ERROR) {
14973859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
14986929Smisaki " nxge_add_tcam_entry write"
14996929Smisaki " failed for location %d", location));
150011304SJanie.Lu@Sun.COM goto fail;
15013859Sml29623 }
15023859Sml29623
15033859Sml29623 tcam_ptr.match_action.value = 0;
15043859Sml29623 tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp;
15053859Sml29623 tcam_ptr.match_action.bits.ldw.offset = offset;
15063859Sml29623 tcam_ptr.match_action.bits.ldw.tres =
15076929Smisaki TRES_TERM_OVRD_L2RDC;
150811304SJanie.Lu@Sun.COM if (channel_cookie == NXGE_PKT_DISCARD)
15093859Sml29623 tcam_ptr.match_action.bits.ldw.disc = 1;
15103859Sml29623 rs = npi_fflp_tcam_asc_ram_entry_write(handle,
15116929Smisaki location, tcam_ptr.match_action.value);
15123859Sml29623 if (rs & NPI_FFLP_ERROR) {
15133859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15146929Smisaki " nxge_add_tcam_entry write"
15156929Smisaki " failed for ASC RAM location %d", location));
151611304SJanie.Lu@Sun.COM goto fail;
15173859Sml29623 }
15183859Sml29623 bcopy((void *) &tcam_ptr,
15196929Smisaki (void *) &nxgep->classifier.tcam_entries[location].tce,
15206929Smisaki sizeof (tcam_entry_t));
152111304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt++;
152211304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entries[location].valid = 1;
15233859Sml29623
15243859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15253859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry"));
15263859Sml29623 return (NXGE_OK);
152711304SJanie.Lu@Sun.COM fail:
152811304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock);
152911304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_tcam_entry FAILED"));
153011304SJanie.Lu@Sun.COM return (NXGE_ERROR);
15313859Sml29623 }
15323859Sml29623
15333859Sml29623 static nxge_status_t
nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)15343859Sml29623 nxge_tcam_handle_ip_fragment(p_nxge_t nxgep)
15353859Sml29623 {
15363859Sml29623 tcam_entry_t tcam_ptr;
15373859Sml29623 tcam_location_t location;
15383859Sml29623 uint8_t class;
15393859Sml29623 uint32_t class_config;
15403859Sml29623 npi_handle_t handle;
15413859Sml29623 npi_status_t rs = NPI_SUCCESS;
15423859Sml29623 p_nxge_hw_list_t hw_p;
15433859Sml29623 nxge_status_t status = NXGE_OK;
15443859Sml29623
15453859Sml29623 handle = nxgep->npi_reg_handle;
15463859Sml29623 class = 0;
15473859Sml29623 bzero((void *)&tcam_ptr, sizeof (tcam_entry_t));
15483859Sml29623 tcam_ptr.ip4_noport_key = 1;
15493859Sml29623 tcam_ptr.ip4_noport_mask = 1;
15503859Sml29623 location = nxgep->function_num;
15513859Sml29623 nxgep->classifier.fragment_bug_location = location;
15523859Sml29623
15533859Sml29623 if ((hw_p = nxgep->nxge_hw_p) == NULL) {
15543859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15556929Smisaki " nxge_tcam_handle_ip_fragment: common hardware not set",
15566929Smisaki nxgep->niu_type));
15573859Sml29623 return (NXGE_ERROR);
15583859Sml29623 }
15593859Sml29623 MUTEX_ENTER(&hw_p->nxge_tcam_lock);
15603859Sml29623 rs = npi_fflp_tcam_entry_write(handle,
15616929Smisaki location, &tcam_ptr);
15623859Sml29623
15633859Sml29623 if (rs & NPI_FFLP_ERROR) {
15643859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15653859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
15666929Smisaki " nxge_tcam_handle_ip_fragment "
15676929Smisaki " tcam_entry write"
15686929Smisaki " failed for location %d", location));
15693859Sml29623 return (NXGE_ERROR);
15703859Sml29623 }
15713859Sml29623 tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp;
15723859Sml29623 tcam_ptr.match_action.bits.ldw.offset = 0; /* use the default */
15733859Sml29623 tcam_ptr.match_action.bits.ldw.tres =
15746929Smisaki TRES_TERM_USE_OFFSET;
15753859Sml29623 rs = npi_fflp_tcam_asc_ram_entry_write(handle,
15766929Smisaki location, tcam_ptr.match_action.value);
15773859Sml29623
15783859Sml29623 if (rs & NPI_FFLP_ERROR) {
15793859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock);
15803859Sml29623 NXGE_DEBUG_MSG((nxgep,
15816929Smisaki FFLP_CTL,
15826929Smisaki " nxge_tcam_handle_ip_fragment "
15836929Smisaki " tcam_entry write"
15846929Smisaki " failed for ASC RAM location %d", location));
15853859Sml29623 return (NXGE_ERROR);
15863859Sml29623 }
15873859Sml29623 bcopy((void *) &tcam_ptr,
15886929Smisaki (void *) &nxgep->classifier.tcam_entries[location].tce,
15896929Smisaki sizeof (tcam_entry_t));
159011304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt++;
159111304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entries[location].valid = 1;
15923859Sml29623 for (class = TCAM_CLASS_TCP_IPV4;
15936929Smisaki class <= TCAM_CLASS_SCTP_IPV6; class++) {
15943859Sml29623 class_config = nxgep->class_config.class_cfg[class];
15953859Sml29623 class_config |= NXGE_CLASS_TCAM_LOOKUP;
15963859Sml29623 status = nxge_fflp_ip_class_config(nxgep, class, class_config);
15973859Sml29623
15983859Sml29623 if (status & NPI_FFLP_ERROR) {
15993859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock);
16003859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16016929Smisaki "nxge_tcam_handle_ip_fragment "
16026929Smisaki "nxge_fflp_ip_class_config failed "
16036929Smisaki " class %d config %x ", class, class_config));
16043859Sml29623 return (NXGE_ERROR);
16053859Sml29623 }
16063859Sml29623 }
16073859Sml29623
16083859Sml29623 rs = npi_fflp_cfg_tcam_enable(handle);
16093859Sml29623 if (rs & NPI_FFLP_ERROR) {
16103859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock);
16113859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16126929Smisaki "nxge_tcam_handle_ip_fragment "
16136929Smisaki " nxge_fflp_config_tcam_enable failed"));
16143859Sml29623 return (NXGE_ERROR);
16153859Sml29623 }
16163859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock);
16173859Sml29623 return (NXGE_OK);
16183859Sml29623 }
16193859Sml29623
16203859Sml29623 /* ARGSUSED */
16213859Sml29623 static int
nxge_flow_need_hash_lookup(p_nxge_t nxgep,flow_resource_t * flow_res)16223859Sml29623 nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res)
16233859Sml29623 {
16243859Sml29623 return (0);
16253859Sml29623 }
16263859Sml29623
16273859Sml29623 nxge_status_t
nxge_add_flow(p_nxge_t nxgep,flow_resource_t * flow_res)16283859Sml29623 nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res)
16293859Sml29623 {
16303859Sml29623
16313859Sml29623 int insert_hash = 0;
16323859Sml29623 nxge_status_t status = NXGE_OK;
16333859Sml29623
16344977Sraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
16353859Sml29623 /* determine whether to do TCAM or Hash flow */
16363859Sml29623 insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res);
16373859Sml29623 }
16383859Sml29623 if (insert_hash) {
16393859Sml29623 status = nxge_add_fcram_entry(nxgep, flow_res);
16403859Sml29623 } else {
16413859Sml29623 status = nxge_add_tcam_entry(nxgep, flow_res);
16423859Sml29623 }
16433859Sml29623 return (status);
16443859Sml29623 }
16453859Sml29623
16463859Sml29623 void
nxge_put_tcam(p_nxge_t nxgep,p_mblk_t mp)16473859Sml29623 nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp)
16483859Sml29623 {
16493859Sml29623 flow_resource_t *fs;
16503859Sml29623
16513859Sml29623 fs = (flow_resource_t *)mp->b_rptr;
16523859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16536929Smisaki "nxge_put_tcam addr fs $%p type %x offset %x",
16546929Smisaki fs, fs->flow_spec.flow_type, fs->channel_cookie));
16553859Sml29623 (void) nxge_add_tcam_entry(nxgep, fs);
16563859Sml29623 }
16573859Sml29623
16583859Sml29623 nxge_status_t
nxge_fflp_config_tcam_enable(p_nxge_t nxgep)16593859Sml29623 nxge_fflp_config_tcam_enable(p_nxge_t nxgep)
16603859Sml29623 {
16613859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle;
16623859Sml29623 npi_status_t rs = NPI_SUCCESS;
16633859Sml29623
16643859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable"));
16653859Sml29623 rs = npi_fflp_cfg_tcam_enable(handle);
16663859Sml29623 if (rs & NPI_FFLP_ERROR) {
16673859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16686929Smisaki " nxge_fflp_config_tcam_enable failed"));
16693859Sml29623 return (NXGE_ERROR | rs);
16703859Sml29623 }
16713859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable"));
16723859Sml29623 return (NXGE_OK);
16733859Sml29623 }
16743859Sml29623
16753859Sml29623 nxge_status_t
nxge_fflp_config_tcam_disable(p_nxge_t nxgep)16763859Sml29623 nxge_fflp_config_tcam_disable(p_nxge_t nxgep)
16773859Sml29623 {
16783859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle;
16793859Sml29623 npi_status_t rs = NPI_SUCCESS;
16803859Sml29623
16813859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
16826929Smisaki " ==> nxge_fflp_config_tcam_disable"));
16833859Sml29623 rs = npi_fflp_cfg_tcam_disable(handle);
16843859Sml29623 if (rs & NPI_FFLP_ERROR) {
16853859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16866929Smisaki " nxge_fflp_config_tcam_disable failed"));
16873859Sml29623 return (NXGE_ERROR | rs);
16883859Sml29623 }
16893859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
16906929Smisaki " <== nxge_fflp_config_tcam_disable"));
16913859Sml29623 return (NXGE_OK);
16923859Sml29623 }
16933859Sml29623
16943859Sml29623 nxge_status_t
nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)16953859Sml29623 nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep)
16963859Sml29623 {
16973859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle;
16983859Sml29623 npi_status_t rs = NPI_SUCCESS;
16993859Sml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp;
17003859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp;
17013859Sml29623 uint8_t partition;
17023859Sml29623
17033859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17046929Smisaki " ==> nxge_fflp_config_hash_lookup_enable"));
17053859Sml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
17063859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
17073859Sml29623
17086495Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
17096495Sspeer if (p_cfgp->grpids[partition]) {
17106495Sspeer rs = npi_fflp_cfg_fcram_partition_enable(
17116929Smisaki handle, partition);
17126495Sspeer if (rs != NPI_SUCCESS) {
17136495Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17146495Sspeer " nxge_fflp_config_hash_lookup_enable"
17156495Sspeer "failed FCRAM partition"
17166495Sspeer " enable for partition %d ", partition));
17176495Sspeer return (NXGE_ERROR | rs);
17186495Sspeer }
17193859Sml29623 }
17203859Sml29623 }
17213859Sml29623
17223859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17236929Smisaki " <== nxge_fflp_config_hash_lookup_enable"));
17243859Sml29623 return (NXGE_OK);
17253859Sml29623 }
17263859Sml29623
17273859Sml29623 nxge_status_t
nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)17283859Sml29623 nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep)
17293859Sml29623 {
17303859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle;
17313859Sml29623 npi_status_t rs = NPI_SUCCESS;
17323859Sml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp;
17333859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp;
17343859Sml29623 uint8_t partition;
17353859Sml29623
17363859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17376929Smisaki " ==> nxge_fflp_config_hash_lookup_disable"));
17383859Sml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
17393859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
17403859Sml29623
17416495Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) {
17426495Sspeer if (p_cfgp->grpids[partition]) {
17436495Sspeer rs = npi_fflp_cfg_fcram_partition_disable(handle,
17446495Sspeer partition);
17456495Sspeer if (rs != NPI_SUCCESS) {
17466495Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17476495Sspeer " nxge_fflp_config_hash_lookup_disable"
17486495Sspeer " failed FCRAM partition"
17496495Sspeer " disable for partition %d ", partition));
17506495Sspeer return (NXGE_ERROR | rs);
17516495Sspeer }
17523859Sml29623 }
17533859Sml29623 }
17543859Sml29623
17553859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17566929Smisaki " <== nxge_fflp_config_hash_lookup_disable"));
17573859Sml29623 return (NXGE_OK);
17583859Sml29623 }
17593859Sml29623
17603859Sml29623 nxge_status_t
nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)17613859Sml29623 nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep)
17623859Sml29623 {
17633859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle;
17643859Sml29623 npi_status_t rs = NPI_SUCCESS;
17653859Sml29623
17663859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17676929Smisaki " ==> nxge_fflp_config_llc_snap_enable"));
17683859Sml29623 rs = npi_fflp_cfg_llcsnap_enable(handle);
17693859Sml29623 if (rs & NPI_FFLP_ERROR) {
17703859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17716929Smisaki " nxge_fflp_config_llc_snap_enable failed"));
17723859Sml29623 return (NXGE_ERROR | rs);
17733859Sml29623 }
17743859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17756929Smisaki " <== nxge_fflp_config_llc_snap_enable"));
17763859Sml29623 return (NXGE_OK);
17773859Sml29623 }
17783859Sml29623
17793859Sml29623 nxge_status_t
nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)17803859Sml29623 nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep)
17813859Sml29623 {
17823859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle;
17833859Sml29623 npi_status_t rs = NPI_SUCCESS;
17843859Sml29623
17853859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17866929Smisaki " ==> nxge_fflp_config_llc_snap_disable"));
17873859Sml29623 rs = npi_fflp_cfg_llcsnap_disable(handle);
17883859Sml29623 if (rs & NPI_FFLP_ERROR) {
17893859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
17906929Smisaki " nxge_fflp_config_llc_snap_disable failed"));
17913859Sml29623 return (NXGE_ERROR | rs);
17923859Sml29623 }
17933859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
17946929Smisaki " <== nxge_fflp_config_llc_snap_disable"));
17953859Sml29623 return (NXGE_OK);
17963859Sml29623 }
17973859Sml29623
17983859Sml29623 nxge_status_t
nxge_fflp_ip_usr_class_config(p_nxge_t nxgep,tcam_class_t class,uint32_t config)17993859Sml29623 nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class,
18003859Sml29623 uint32_t config)
18013859Sml29623 {
18023859Sml29623 npi_status_t rs = NPI_SUCCESS;
18033859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle;
18043859Sml29623 uint8_t tos, tos_mask, proto, ver = 0;
18053859Sml29623 uint8_t class_enable = 0;
18063859Sml29623
18073859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config"));
18083859Sml29623
18093859Sml29623 tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >>
18106929Smisaki NXGE_CLASS_CFG_IP_TOS_SHIFT;
18113859Sml29623 tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >>
18126929Smisaki NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT;
18133859Sml29623 proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >>
18146929Smisaki NXGE_CLASS_CFG_IP_PROTO_SHIFT;
18153859Sml29623 if (config & NXGE_CLASS_CFG_IP_IPV6_MASK)
18163859Sml29623 ver = 1;
18173859Sml29623 if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK)
18183859Sml29623 class_enable = 1;
18193859Sml29623 rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask,
18206929Smisaki proto, ver);
18213859Sml29623 if (rs & NPI_FFLP_ERROR) {
18223859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18236929Smisaki " nxge_fflp_ip_usr_class_config"
18246929Smisaki " for class %d failed ", class));
18253859Sml29623 return (NXGE_ERROR | rs);
18263859Sml29623 }
18273859Sml29623 if (class_enable)
18283859Sml29623 rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class);
18293859Sml29623 else
18303859Sml29623 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class);
18313859Sml29623
18323859Sml29623 if (rs & NPI_FFLP_ERROR) {
18333859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18346929Smisaki " nxge_fflp_ip_usr_class_config"
18356929Smisaki " TCAM enable/disable for class %d failed ", class));
18363859Sml29623 return (NXGE_ERROR | rs);
18373859Sml29623 }
18383859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config"));
18393859Sml29623 return (NXGE_OK);
18403859Sml29623 }
18413859Sml29623
18423859Sml29623 nxge_status_t
nxge_fflp_ip_class_config(p_nxge_t nxgep,tcam_class_t class,uint32_t config)18433859Sml29623 nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config)
18443859Sml29623 {
18453859Sml29623 uint32_t class_config;
18463859Sml29623 nxge_status_t t_status = NXGE_OK;
18473859Sml29623 nxge_status_t f_status = NXGE_OK;
18483859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
18493859Sml29623
18503859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
18513859Sml29623
18523859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
18533859Sml29623 class_config = p_class_cfgp->class_cfg[class];
18543859Sml29623
18553859Sml29623 if (class_config != config) {
18563859Sml29623 p_class_cfgp->class_cfg[class] = config;
18573859Sml29623 class_config = config;
18583859Sml29623 }
18593859Sml29623
18603859Sml29623 t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config);
18613859Sml29623 f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config);
18623859Sml29623
18633859Sml29623 if (t_status & NPI_FFLP_ERROR) {
18643859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
18656929Smisaki " nxge_fflp_ip_class_config %x"
18666929Smisaki " for class %d tcam failed", config, class));
18673859Sml29623 return (t_status);
18683859Sml29623 }
18693859Sml29623 if (f_status & NPI_FFLP_ERROR) {
18703859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18716929Smisaki " nxge_fflp_ip_class_config %x"
18726929Smisaki " for class %d flow key failed", config, class));
18733859Sml29623 return (f_status);
18743859Sml29623 }
18753859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
18763859Sml29623 return (NXGE_OK);
18773859Sml29623 }
18783859Sml29623
18793859Sml29623 nxge_status_t
nxge_fflp_ip_class_config_get(p_nxge_t nxgep,tcam_class_t class,uint32_t * config)18803859Sml29623 nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class,
18813859Sml29623 uint32_t *config)
18823859Sml29623 {
18833859Sml29623 uint32_t t_class_config, f_class_config;
18843859Sml29623 int t_status = NXGE_OK;
18853859Sml29623 int f_status = NXGE_OK;
18863859Sml29623
18873859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config"));
18883859Sml29623
18893859Sml29623 t_class_config = f_class_config = 0;
18903859Sml29623 t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config);
18913859Sml29623 f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config);
18923859Sml29623
18933859Sml29623 if (t_status & NPI_FFLP_ERROR) {
18943859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18956929Smisaki " nxge_fflp_ip_class_config_get "
18966929Smisaki " for class %d tcam failed", class));
18973859Sml29623 return (t_status);
18983859Sml29623 }
18993859Sml29623
19003859Sml29623 if (f_status & NPI_FFLP_ERROR) {
19013859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
19026929Smisaki " nxge_fflp_ip_class_config_get "
19036929Smisaki " for class %d flow key failed", class));
19043859Sml29623 return (f_status);
19053859Sml29623 }
19063859Sml29623
19073859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
19086929Smisaki " nxge_fflp_ip_class_config tcam %x flow %x",
19096929Smisaki t_class_config, f_class_config));
19103859Sml29623
19113859Sml29623 *config = t_class_config | f_class_config;
19123859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get"));
19133859Sml29623 return (NXGE_OK);
19143859Sml29623 }
19153859Sml29623
19163859Sml29623 nxge_status_t
nxge_fflp_ip_class_config_all(p_nxge_t nxgep)19173859Sml29623 nxge_fflp_ip_class_config_all(p_nxge_t nxgep)
19183859Sml29623 {
19193859Sml29623 uint32_t class_config;
19203859Sml29623 tcam_class_t class;
19213859Sml29623
19223859Sml29623 #ifdef NXGE_DEBUG
19233859Sml29623 int status = NXGE_OK;
19243859Sml29623 #endif
19253859Sml29623
19263859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config"));
19273859Sml29623 for (class = TCAM_CLASS_TCP_IPV4;
19286929Smisaki class <= TCAM_CLASS_SCTP_IPV6; class++) {
19293859Sml29623 class_config = nxgep->class_config.class_cfg[class];
19303859Sml29623 #ifndef NXGE_DEBUG
19313859Sml29623 (void) nxge_fflp_ip_class_config(nxgep, class, class_config);
19323859Sml29623 #else
19333859Sml29623 status = nxge_fflp_ip_class_config(nxgep, class, class_config);
19343859Sml29623 if (status & NPI_FFLP_ERROR) {
19353859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19366929Smisaki "nxge_fflp_ip_class_config failed "
19376929Smisaki " class %d config %x ",
19386929Smisaki class, class_config));
19393859Sml29623 }
19403859Sml29623 #endif
19413859Sml29623 }
19423859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config"));
19433859Sml29623 return (NXGE_OK);
19443859Sml29623 }
19453859Sml29623
19463859Sml29623 nxge_status_t
nxge_fflp_config_vlan_table(p_nxge_t nxgep,uint16_t vlan_id)19473859Sml29623 nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id)
19483859Sml29623 {
19493859Sml29623 uint8_t port, rdc_grp;
19503859Sml29623 npi_handle_t handle;
19513859Sml29623 npi_status_t rs = NPI_SUCCESS;
19523859Sml29623 uint8_t priority = 1;
19533859Sml29623 p_nxge_mv_cfg_t vlan_table;
19543859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
19553859Sml29623 p_nxge_hw_list_t hw_p;
19563859Sml29623
19573859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table"));
19583859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
19593859Sml29623 handle = nxgep->npi_reg_handle;
19603859Sml29623 vlan_table = p_class_cfgp->vlan_tbl;
19613859Sml29623 port = nxgep->function_num;
19623859Sml29623
19633859Sml29623 if (vlan_table[vlan_id].flag == 0) {
19643859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19656929Smisaki " nxge_fflp_config_vlan_table"
19666929Smisaki " vlan id is not configured %d", vlan_id));
19673859Sml29623 return (NXGE_ERROR);
19683859Sml29623 }
19693859Sml29623
19703859Sml29623 if ((hw_p = nxgep->nxge_hw_p) == NULL) {
19713859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19726929Smisaki " nxge_fflp_config_vlan_table:"
19736929Smisaki " common hardware not set", nxgep->niu_type));
19743859Sml29623 return (NXGE_ERROR);
19753859Sml29623 }
19763859Sml29623 MUTEX_ENTER(&hw_p->nxge_vlan_lock);
19773859Sml29623 rdc_grp = vlan_table[vlan_id].rdctbl;
19783859Sml29623 rs = npi_fflp_cfg_enet_vlan_table_assoc(handle,
19796929Smisaki port, vlan_id,
19806929Smisaki rdc_grp, priority);
19813859Sml29623
19823859Sml29623 MUTEX_EXIT(&hw_p->nxge_vlan_lock);
19833859Sml29623 if (rs & NPI_FFLP_ERROR) {
19843859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19856929Smisaki "nxge_fflp_config_vlan_table failed "
19866929Smisaki " Port %d vlan_id %d rdc_grp %d",
19876929Smisaki port, vlan_id, rdc_grp));
19883859Sml29623 return (NXGE_ERROR | rs);
19893859Sml29623 }
19903859Sml29623
19913859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table"));
19923859Sml29623 return (NXGE_OK);
19933859Sml29623 }
19943859Sml29623
19953859Sml29623 nxge_status_t
nxge_fflp_update_hw(p_nxge_t nxgep)19963859Sml29623 nxge_fflp_update_hw(p_nxge_t nxgep)
19973859Sml29623 {
19983859Sml29623 nxge_status_t status = NXGE_OK;
19993859Sml29623 p_nxge_param_t pa;
20003859Sml29623 uint64_t cfgd_vlans;
20013859Sml29623 uint64_t *val_ptr;
20023859Sml29623 int i;
20033859Sml29623 int num_macs;
20043859Sml29623 uint8_t alt_mac;
20053859Sml29623 nxge_param_map_t *p_map;
20063859Sml29623 p_nxge_mv_cfg_t vlan_table;
20073859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp;
20083859Sml29623 p_nxge_dma_pt_cfg_t p_all_cfgp;
20093859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp;
20103859Sml29623
20113859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw"));
20123859Sml29623
20133859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
20143859Sml29623 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
20153859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config;
20163859Sml29623
20173859Sml29623 status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1);
20183859Sml29623 if (status != NXGE_OK) {
20193859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20206929Smisaki "nxge_fflp_set_hash1 Failed"));
20213859Sml29623 return (NXGE_ERROR);
20223859Sml29623 }
20233859Sml29623
20243859Sml29623 status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2);
20253859Sml29623 if (status != NXGE_OK) {
20263859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20276929Smisaki "nxge_fflp_set_hash2 Failed"));
20283859Sml29623 return (NXGE_ERROR);
20293859Sml29623 }
20303859Sml29623 vlan_table = p_class_cfgp->vlan_tbl;
20313859Sml29623
20323859Sml29623 /* configure vlan tables */
20333859Sml29623 pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp];
20345125Sjoycey #if defined(__i386)
20355125Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value;
20365125Sjoycey #else
20373859Sml29623 val_ptr = (uint64_t *)pa->value;
20385125Sjoycey #endif
20393859Sml29623 cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >>
20406929Smisaki NXGE_PARAM_ARRAY_CNT_SHIFT);
20413859Sml29623
20423859Sml29623 for (i = 0; i < cfgd_vlans; i++) {
20433859Sml29623 p_map = (nxge_param_map_t *)&val_ptr[i];
20443859Sml29623 if (vlan_table[p_map->param_id].flag) {
20453859Sml29623 status = nxge_fflp_config_vlan_table(nxgep,
20466929Smisaki p_map->param_id);
20473859Sml29623 if (status != NXGE_OK) {
20483859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20496929Smisaki "nxge_fflp_config_vlan_table Failed"));
20503859Sml29623 return (NXGE_ERROR);
20513859Sml29623 }
20523859Sml29623 }
20533859Sml29623 }
20543859Sml29623
20553859Sml29623 /* config MAC addresses */
20563859Sml29623 num_macs = p_cfgp->max_macs;
20573859Sml29623 pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp];
20585125Sjoycey #if defined(__i386)
20595125Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value;
20605125Sjoycey #else
20613859Sml29623 val_ptr = (uint64_t *)pa->value;
20625125Sjoycey #endif
20633859Sml29623
20643859Sml29623 for (alt_mac = 0; alt_mac < num_macs; alt_mac++) {
20653859Sml29623 if (p_class_cfgp->mac_host_info[alt_mac].flag) {
20663859Sml29623 status = nxge_logical_mac_assign_rdc_table(nxgep,
20676929Smisaki alt_mac);
20683859Sml29623 if (status != NXGE_OK) {
20693859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20706929Smisaki "nxge_logical_mac_assign_rdc_table"
20716929Smisaki " Failed"));
20723859Sml29623 return (NXGE_ERROR);
20733859Sml29623 }
20743859Sml29623 }
20753859Sml29623 }
20763859Sml29623
20773859Sml29623 /* Config Hash values */
20785523Syc148097 /* config classes */
20793859Sml29623 status = nxge_fflp_ip_class_config_all(nxgep);
20803859Sml29623 if (status != NXGE_OK) {
20813859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
20826929Smisaki "nxge_fflp_ip_class_config_all Failed"));
20833859Sml29623 return (NXGE_ERROR);
20843859Sml29623 }
20853859Sml29623 return (NXGE_OK);
20863859Sml29623 }
20873859Sml29623
20883859Sml29623 nxge_status_t
nxge_classify_init_hw(p_nxge_t nxgep)20893859Sml29623 nxge_classify_init_hw(p_nxge_t nxgep)
20903859Sml29623 {
20913859Sml29623 nxge_status_t status = NXGE_OK;
20923859Sml29623
20933859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw"));
20943859Sml29623
20953859Sml29623 if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) {
20963859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL,
20976929Smisaki "nxge_classify_init_hw already init"));
20983859Sml29623 return (NXGE_OK);
20993859Sml29623 }
21003859Sml29623
21013859Sml29623 /* Now do a real configuration */
21023859Sml29623 status = nxge_fflp_update_hw(nxgep);
21033859Sml29623 if (status != NXGE_OK) {
21043859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21056929Smisaki "nxge_fflp_update_hw failed"));
21063859Sml29623 return (NXGE_ERROR);
21073859Sml29623 }
21083859Sml29623
21093859Sml29623 /* Init RDC tables? ? who should do that? rxdma or fflp ? */
21103859Sml29623 /* attach rdc table to the MAC port. */
21113859Sml29623 status = nxge_main_mac_assign_rdc_table(nxgep);
21123859Sml29623 if (status != NXGE_OK) {
21133859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21146929Smisaki "nxge_main_mac_assign_rdc_table failed"));
21153859Sml29623 return (NXGE_ERROR);
21163859Sml29623 }
21173859Sml29623
21183859Sml29623 status = nxge_alt_mcast_mac_assign_rdc_table(nxgep);
21193859Sml29623 if (status != NXGE_OK) {
21203859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
21216929Smisaki "nxge_multicast_mac_assign_rdc_table failed"));
21223859Sml29623 return (NXGE_ERROR);
21233859Sml29623 }
21243859Sml29623
212511304SJanie.Lu@Sun.COM if (nxgep->classifier.fragment_bug == 1) {
212611304SJanie.Lu@Sun.COM status = nxge_tcam_handle_ip_fragment(nxgep);
212711304SJanie.Lu@Sun.COM if (status != NXGE_OK) {
212811304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
212911304SJanie.Lu@Sun.COM "nxge_tcam_handle_ip_fragment failed"));
213011304SJanie.Lu@Sun.COM return (NXGE_ERROR);
213111304SJanie.Lu@Sun.COM }
21323859Sml29623 }
21333859Sml29623
21343859Sml29623 nxgep->classifier.state |= NXGE_FFLP_HW_INIT;
21353859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw"));
21363859Sml29623 return (NXGE_OK);
21373859Sml29623 }
21383859Sml29623
21393859Sml29623 nxge_status_t
nxge_fflp_handle_sys_errors(p_nxge_t nxgep)21403859Sml29623 nxge_fflp_handle_sys_errors(p_nxge_t nxgep)
21413859Sml29623 {
21423859Sml29623 npi_handle_t handle;
21433859Sml29623 p_nxge_fflp_stats_t statsp;
21443859Sml29623 uint8_t portn, rdc_grp;
21453859Sml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp;
21463859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp;
21473859Sml29623 vlan_par_err_t vlan_err;
21483859Sml29623 tcam_err_t tcam_err;
21493859Sml29623 hash_lookup_err_log1_t fcram1_err;
21503859Sml29623 hash_lookup_err_log2_t fcram2_err;
21513859Sml29623 hash_tbl_data_log_t fcram_err;
21523859Sml29623
21533859Sml29623 handle = nxgep->npi_handle;
21543859Sml29623 statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats;
21553859Sml29623 portn = nxgep->mac.portnum;
21563859Sml29623
21573859Sml29623 /*
21583859Sml29623 * need to read the fflp error registers to figure out what the error
21593859Sml29623 * is
21603859Sml29623 */
21613859Sml29623 npi_fflp_vlan_error_get(handle, &vlan_err);
21623859Sml29623 npi_fflp_tcam_error_get(handle, &tcam_err);
21633859Sml29623
21643859Sml29623 if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) {
21653859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21666929Smisaki " vlan table parity error on port %d"
21676929Smisaki " addr: 0x%x data: 0x%x",
21686929Smisaki portn, vlan_err.bits.ldw.addr,
21696929Smisaki vlan_err.bits.ldw.data));
21703859Sml29623 statsp->vlan_parity_err++;
21713859Sml29623
21723859Sml29623 if (vlan_err.bits.ldw.m_err) {
21733859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21746929Smisaki " vlan table multiple errors on port %d",
21756929Smisaki portn));
21763859Sml29623 }
21773859Sml29623 statsp->errlog.vlan = (uint32_t)vlan_err.value;
21783859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
21796929Smisaki NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR);
21803859Sml29623 npi_fflp_vlan_error_clear(handle);
21813859Sml29623 }
21823859Sml29623
21833859Sml29623 if (tcam_err.bits.ldw.err) {
21843859Sml29623 if (tcam_err.bits.ldw.p_ecc != 0) {
21853859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21866929Smisaki " TCAM ECC error on port %d"
21876929Smisaki " TCAM entry: 0x%x syndrome: 0x%x",
21886929Smisaki portn, tcam_err.bits.ldw.addr,
21896929Smisaki tcam_err.bits.ldw.syndrome));
21903859Sml29623 statsp->tcam_ecc_err++;
21913859Sml29623 } else {
21923859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL,
21936929Smisaki " TCAM Parity error on port %d"
21946929Smisaki " addr: 0x%x parity value: 0x%x",
21956929Smisaki portn, tcam_err.bits.ldw.addr,
21966929Smisaki tcam_err.bits.ldw.syndrome));
21973859Sml29623 statsp->tcam_parity_err++;
21983859Sml29623 }
21993859Sml29623
22003859Sml29623 if (tcam_err.bits.ldw.mult) {
22013859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22026929Smisaki " TCAM Multiple errors on port %d", portn));
22033859Sml29623 } else {
22043859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22056929Smisaki " TCAM PIO error on port %d", portn));
22063859Sml29623 }
22073859Sml29623
22083859Sml29623 statsp->errlog.tcam = (uint32_t)tcam_err.value;
22093859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
22106929Smisaki NXGE_FM_EREPORT_FFLP_TCAM_ERR);
22113859Sml29623 npi_fflp_tcam_error_clear(handle);
22123859Sml29623 }
22133859Sml29623
22143859Sml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
22153859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
22163859Sml29623
22176495Sspeer for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) {
22186495Sspeer if (p_cfgp->grpids[rdc_grp]) {
22196495Sspeer npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp);
22206495Sspeer if (fcram_err.bits.ldw.pio_err) {
22216495Sspeer NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22226929Smisaki " FCRAM PIO ECC error on port %d"
22236929Smisaki " rdc group: %d Hash Table addr: 0x%x"
22246929Smisaki " syndrome: 0x%x",
22256929Smisaki portn, rdc_grp,
22266929Smisaki fcram_err.bits.ldw.fcram_addr,
22276929Smisaki fcram_err.bits.ldw.syndrome));
22286495Sspeer statsp->hash_pio_err[rdc_grp]++;
22296495Sspeer statsp->errlog.hash_pio[rdc_grp] =
22306495Sspeer (uint32_t)fcram_err.value;
22316495Sspeer NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
22326495Sspeer NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR);
22336495Sspeer npi_fflp_fcram_error_clear(handle, rdc_grp);
22346495Sspeer }
22353859Sml29623 }
22363859Sml29623 }
22373859Sml29623
22383859Sml29623 npi_fflp_fcram_error_log1_get(handle, &fcram1_err);
22393859Sml29623 if (fcram1_err.bits.ldw.ecc_err) {
22403859Sml29623 char *multi_str = "";
22413859Sml29623 char *multi_bit_str = "";
22423859Sml29623
22433859Sml29623 npi_fflp_fcram_error_log2_get(handle, &fcram2_err);
22443859Sml29623 if (fcram1_err.bits.ldw.mult_lk) {
22453859Sml29623 multi_str = "multiple";
22463859Sml29623 }
22473859Sml29623 if (fcram1_err.bits.ldw.mult_bit) {
22483859Sml29623 multi_bit_str = "multiple bits";
22493859Sml29623 }
22505523Syc148097 statsp->hash_lookup_err++;
22513859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL,
22526929Smisaki " FCRAM %s lookup %s ECC error on port %d"
22536929Smisaki " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x",
22546929Smisaki multi_str, multi_bit_str, portn,
22556929Smisaki fcram2_err.bits.ldw.h1,
22566929Smisaki fcram2_err.bits.ldw.subarea,
22576929Smisaki fcram2_err.bits.ldw.syndrome));
22583859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL,
22596929Smisaki NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR);
22603859Sml29623 }
22613859Sml29623 statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value;
22623859Sml29623 statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value;
22633859Sml29623 return (NXGE_OK);
22643859Sml29623 }
226511304SJanie.Lu@Sun.COM
226611304SJanie.Lu@Sun.COM int
nxge_get_valid_tcam_cnt(p_nxge_t nxgep)226711304SJanie.Lu@Sun.COM nxge_get_valid_tcam_cnt(p_nxge_t nxgep) {
226811304SJanie.Lu@Sun.COM return ((nxgep->classifier.fragment_bug == 1) ?
226911304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt - 1 :
227011304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt);
227111304SJanie.Lu@Sun.COM }
227211304SJanie.Lu@Sun.COM
227311304SJanie.Lu@Sun.COM int
nxge_rxdma_channel_cnt(p_nxge_t nxgep)227411304SJanie.Lu@Sun.COM nxge_rxdma_channel_cnt(p_nxge_t nxgep)
227511304SJanie.Lu@Sun.COM {
227611304SJanie.Lu@Sun.COM p_nxge_dma_pt_cfg_t p_dma_cfgp;
227711304SJanie.Lu@Sun.COM p_nxge_hw_pt_cfg_t p_cfgp;
227811304SJanie.Lu@Sun.COM
227911304SJanie.Lu@Sun.COM p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
228011304SJanie.Lu@Sun.COM p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
228111304SJanie.Lu@Sun.COM return (p_cfgp->max_rdcs);
228211304SJanie.Lu@Sun.COM }
228311304SJanie.Lu@Sun.COM
228411304SJanie.Lu@Sun.COM /* ARGSUSED */
228511304SJanie.Lu@Sun.COM int
nxge_rxclass_ioctl(p_nxge_t nxgep,queue_t * wq,mblk_t * mp)228611304SJanie.Lu@Sun.COM nxge_rxclass_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
228711304SJanie.Lu@Sun.COM {
228811304SJanie.Lu@Sun.COM uint32_t cmd;
228911304SJanie.Lu@Sun.COM rx_class_cfg_t *cfg_info = (rx_class_cfg_t *)mp->b_rptr;
229011304SJanie.Lu@Sun.COM
229111304SJanie.Lu@Sun.COM if (nxgep == NULL) {
229211304SJanie.Lu@Sun.COM return (-1);
229311304SJanie.Lu@Sun.COM }
229411304SJanie.Lu@Sun.COM cmd = cfg_info->cmd;
229511304SJanie.Lu@Sun.COM switch (cmd) {
229611304SJanie.Lu@Sun.COM default:
229711304SJanie.Lu@Sun.COM return (-1);
229811304SJanie.Lu@Sun.COM
229911304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_GCHAN:
230011304SJanie.Lu@Sun.COM cfg_info->data = nxge_rxdma_channel_cnt(nxgep);
230111304SJanie.Lu@Sun.COM break;
230211304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_GRULE_CNT:
230311304SJanie.Lu@Sun.COM MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
230411304SJanie.Lu@Sun.COM cfg_info->rule_cnt = nxge_get_valid_tcam_cnt(nxgep);
230511304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
230611304SJanie.Lu@Sun.COM break;
230711304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_GRULE:
230811304SJanie.Lu@Sun.COM nxge_get_tcam_entry(nxgep, &cfg_info->fs);
230911304SJanie.Lu@Sun.COM break;
231011304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_GRULE_ALL:
231111304SJanie.Lu@Sun.COM nxge_get_tcam_entry_all(nxgep, cfg_info);
231211304SJanie.Lu@Sun.COM break;
231311304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_RULE_DEL:
231411304SJanie.Lu@Sun.COM nxge_del_tcam_entry(nxgep, cfg_info->fs.location);
231511304SJanie.Lu@Sun.COM break;
231611304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_RULE_INS:
231711304SJanie.Lu@Sun.COM (void) nxge_add_tcam_entry(nxgep, &cfg_info->fs);
231811304SJanie.Lu@Sun.COM break;
231911304SJanie.Lu@Sun.COM }
232011304SJanie.Lu@Sun.COM return (0);
232111304SJanie.Lu@Sun.COM }
232211304SJanie.Lu@Sun.COM /* ARGSUSED */
232311304SJanie.Lu@Sun.COM int
nxge_rxhash_ioctl(p_nxge_t nxgep,queue_t * wq,mblk_t * mp)232411304SJanie.Lu@Sun.COM nxge_rxhash_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp)
232511304SJanie.Lu@Sun.COM {
232611304SJanie.Lu@Sun.COM uint32_t cmd;
232711304SJanie.Lu@Sun.COM cfg_cmd_t *cfg_info = (cfg_cmd_t *)mp->b_rptr;
232811304SJanie.Lu@Sun.COM
232911304SJanie.Lu@Sun.COM if (nxgep == NULL) {
233011304SJanie.Lu@Sun.COM return (-1);
233111304SJanie.Lu@Sun.COM }
233211304SJanie.Lu@Sun.COM cmd = cfg_info->cmd;
233311304SJanie.Lu@Sun.COM
233411304SJanie.Lu@Sun.COM switch (cmd) {
233511304SJanie.Lu@Sun.COM default:
233611304SJanie.Lu@Sun.COM return (-1);
233711304SJanie.Lu@Sun.COM case NXGE_IPTUN_CFG_ADD_CLS:
233811304SJanie.Lu@Sun.COM nxge_add_iptun_class(nxgep, &cfg_info->iptun_cfg,
233911304SJanie.Lu@Sun.COM &cfg_info->class_id);
234011304SJanie.Lu@Sun.COM break;
234111304SJanie.Lu@Sun.COM case NXGE_IPTUN_CFG_SET_HASH:
234211304SJanie.Lu@Sun.COM nxge_cfg_iptun_hash(nxgep, &cfg_info->iptun_cfg,
234311304SJanie.Lu@Sun.COM cfg_info->class_id);
234411304SJanie.Lu@Sun.COM break;
234511304SJanie.Lu@Sun.COM case NXGE_IPTUN_CFG_DEL_CLS:
234611304SJanie.Lu@Sun.COM nxge_del_iptun_class(nxgep, cfg_info->class_id);
234711304SJanie.Lu@Sun.COM break;
234811304SJanie.Lu@Sun.COM case NXGE_IPTUN_CFG_GET_CLS:
234911304SJanie.Lu@Sun.COM nxge_get_iptun_class(nxgep, &cfg_info->iptun_cfg,
235011304SJanie.Lu@Sun.COM cfg_info->class_id);
235111304SJanie.Lu@Sun.COM break;
235211304SJanie.Lu@Sun.COM case NXGE_CLS_CFG_SET_SYM:
235311304SJanie.Lu@Sun.COM nxge_set_ip_cls_sym(nxgep, cfg_info->class_id, cfg_info->sym);
235411304SJanie.Lu@Sun.COM break;
235511304SJanie.Lu@Sun.COM case NXGE_CLS_CFG_GET_SYM:
235611304SJanie.Lu@Sun.COM nxge_get_ip_cls_sym(nxgep, cfg_info->class_id, &cfg_info->sym);
235711304SJanie.Lu@Sun.COM break;
235811304SJanie.Lu@Sun.COM }
235911304SJanie.Lu@Sun.COM return (0);
236011304SJanie.Lu@Sun.COM }
236111304SJanie.Lu@Sun.COM
236211304SJanie.Lu@Sun.COM void
nxge_get_tcam_entry_all(p_nxge_t nxgep,rx_class_cfg_t * cfgp)236311304SJanie.Lu@Sun.COM nxge_get_tcam_entry_all(p_nxge_t nxgep, rx_class_cfg_t *cfgp)
236411304SJanie.Lu@Sun.COM {
236511304SJanie.Lu@Sun.COM nxge_classify_t *clasp = &nxgep->classifier;
236611304SJanie.Lu@Sun.COM uint16_t n_entries;
236711304SJanie.Lu@Sun.COM int i, j, k;
236811304SJanie.Lu@Sun.COM tcam_flow_spec_t *tcam_entryp;
236911304SJanie.Lu@Sun.COM
237011304SJanie.Lu@Sun.COM cfgp->data = clasp->tcam_size;
237111304SJanie.Lu@Sun.COM MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
237211304SJanie.Lu@Sun.COM n_entries = cfgp->rule_cnt;
237311304SJanie.Lu@Sun.COM
237411304SJanie.Lu@Sun.COM for (i = 0, j = 0; j < cfgp->data; j++) {
237511304SJanie.Lu@Sun.COM k = nxge_tcam_get_index(nxgep, j);
237611304SJanie.Lu@Sun.COM tcam_entryp = &clasp->tcam_entries[k];
237711304SJanie.Lu@Sun.COM if (tcam_entryp->valid != 1)
237811304SJanie.Lu@Sun.COM continue;
237911304SJanie.Lu@Sun.COM cfgp->rule_locs[i] = j;
238011304SJanie.Lu@Sun.COM i++;
238111304SJanie.Lu@Sun.COM };
238211304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
238311304SJanie.Lu@Sun.COM
238411304SJanie.Lu@Sun.COM if (n_entries != i) {
238511304SJanie.Lu@Sun.COM /* print warning, this should not happen */
238611304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry_all"
238711304SJanie.Lu@Sun.COM "n_entries[%d] != i[%d]!!!", n_entries, i));
238811304SJanie.Lu@Sun.COM }
238911304SJanie.Lu@Sun.COM }
239011304SJanie.Lu@Sun.COM
239111304SJanie.Lu@Sun.COM
239211304SJanie.Lu@Sun.COM /* Entries for the ports are interleaved in the TCAM */
239311304SJanie.Lu@Sun.COM static uint16_t
nxge_tcam_get_index(p_nxge_t nxgep,uint16_t index)239411304SJanie.Lu@Sun.COM nxge_tcam_get_index(p_nxge_t nxgep, uint16_t index)
239511304SJanie.Lu@Sun.COM {
239611304SJanie.Lu@Sun.COM /* One entry reserved for IP fragment rule */
239711304SJanie.Lu@Sun.COM if (index >= (nxgep->classifier.tcam_size - 1))
239811304SJanie.Lu@Sun.COM index = 0;
239911304SJanie.Lu@Sun.COM if (nxgep->classifier.fragment_bug == 1)
240011304SJanie.Lu@Sun.COM index++;
240111304SJanie.Lu@Sun.COM return (nxgep->classifier.tcam_top + (index * nxgep->nports));
240211304SJanie.Lu@Sun.COM }
240311304SJanie.Lu@Sun.COM
240411304SJanie.Lu@Sun.COM static uint32_t
nxge_tcam_cls_to_flow(uint32_t class_code)240511304SJanie.Lu@Sun.COM nxge_tcam_cls_to_flow(uint32_t class_code) {
240611304SJanie.Lu@Sun.COM switch (class_code) {
240711304SJanie.Lu@Sun.COM case TCAM_CLASS_TCP_IPV4:
240811304SJanie.Lu@Sun.COM return (FSPEC_TCPIP4);
240911304SJanie.Lu@Sun.COM case TCAM_CLASS_UDP_IPV4:
241011304SJanie.Lu@Sun.COM return (FSPEC_UDPIP4);
241111304SJanie.Lu@Sun.COM case TCAM_CLASS_AH_ESP_IPV4:
241211304SJanie.Lu@Sun.COM return (FSPEC_AHIP4);
241311304SJanie.Lu@Sun.COM case TCAM_CLASS_SCTP_IPV4:
241411304SJanie.Lu@Sun.COM return (FSPEC_SCTPIP4);
241511304SJanie.Lu@Sun.COM case TCAM_CLASS_TCP_IPV6:
241611304SJanie.Lu@Sun.COM return (FSPEC_TCPIP6);
241711304SJanie.Lu@Sun.COM case TCAM_CLASS_UDP_IPV6:
241811304SJanie.Lu@Sun.COM return (FSPEC_UDPIP6);
241911304SJanie.Lu@Sun.COM case TCAM_CLASS_AH_ESP_IPV6:
242011304SJanie.Lu@Sun.COM return (FSPEC_AHIP6);
242111304SJanie.Lu@Sun.COM case TCAM_CLASS_SCTP_IPV6:
242211304SJanie.Lu@Sun.COM return (FSPEC_SCTPIP6);
242311304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_4:
242411304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_5:
242511304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_6:
242611304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_7:
242711304SJanie.Lu@Sun.COM return (FSPEC_IP_USR);
242811304SJanie.Lu@Sun.COM default:
242911304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "nxge_tcam_cls_to_flow"
243011304SJanie.Lu@Sun.COM ": Unknown class code [0x%x]", class_code));
243111304SJanie.Lu@Sun.COM break;
243211304SJanie.Lu@Sun.COM }
243311304SJanie.Lu@Sun.COM return (0);
243411304SJanie.Lu@Sun.COM }
243511304SJanie.Lu@Sun.COM
243611304SJanie.Lu@Sun.COM void
nxge_get_tcam_entry(p_nxge_t nxgep,flow_resource_t * fs)243711304SJanie.Lu@Sun.COM nxge_get_tcam_entry(p_nxge_t nxgep, flow_resource_t *fs)
243811304SJanie.Lu@Sun.COM {
243911304SJanie.Lu@Sun.COM uint16_t index;
244011304SJanie.Lu@Sun.COM tcam_flow_spec_t *tcam_ep;
244111304SJanie.Lu@Sun.COM tcam_entry_t *tp;
244211304SJanie.Lu@Sun.COM flow_spec_t *fspec;
244311304SJanie.Lu@Sun.COM tcpip4_spec_t *fspec_key;
244411304SJanie.Lu@Sun.COM tcpip4_spec_t *fspec_mask;
244511304SJanie.Lu@Sun.COM
244611304SJanie.Lu@Sun.COM index = nxge_tcam_get_index(nxgep, (uint16_t)fs->location);
244711304SJanie.Lu@Sun.COM tcam_ep = &nxgep->classifier.tcam_entries[index];
244811304SJanie.Lu@Sun.COM if (tcam_ep->valid != 1) {
244911304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry: :"
245011304SJanie.Lu@Sun.COM "Entry [%d] invalid for index [%d]", fs->location, index));
245111304SJanie.Lu@Sun.COM return;
245211304SJanie.Lu@Sun.COM }
245311304SJanie.Lu@Sun.COM
245411304SJanie.Lu@Sun.COM /* Fill the flow spec entry */
245511304SJanie.Lu@Sun.COM tp = &tcam_ep->tce;
245611304SJanie.Lu@Sun.COM fspec = &fs->flow_spec;
245711304SJanie.Lu@Sun.COM fspec->flow_type = nxge_tcam_cls_to_flow(tp->ip4_class_key);
245811304SJanie.Lu@Sun.COM
245911304SJanie.Lu@Sun.COM /* TODO - look at proto field to differentiate between AH and ESP */
246011304SJanie.Lu@Sun.COM if (fspec->flow_type == FSPEC_AHIP4) {
246111304SJanie.Lu@Sun.COM if (tp->ip4_proto_key == IPPROTO_ESP)
246211304SJanie.Lu@Sun.COM fspec->flow_type = FSPEC_ESPIP4;
246311304SJanie.Lu@Sun.COM }
246411304SJanie.Lu@Sun.COM
246511304SJanie.Lu@Sun.COM switch (tp->ip4_class_key) {
246611304SJanie.Lu@Sun.COM case TCAM_CLASS_TCP_IPV4:
246711304SJanie.Lu@Sun.COM case TCAM_CLASS_UDP_IPV4:
246811304SJanie.Lu@Sun.COM case TCAM_CLASS_AH_ESP_IPV4:
246911304SJanie.Lu@Sun.COM case TCAM_CLASS_SCTP_IPV4:
247011304SJanie.Lu@Sun.COM fspec_key = (tcpip4_spec_t *)&fspec->uh.tcpip4spec;
247111304SJanie.Lu@Sun.COM fspec_mask = (tcpip4_spec_t *)&fspec->um.tcpip4spec;
247211304SJanie.Lu@Sun.COM FSPEC_IPV4_ADDR(fspec_key->ip4dst, tp->ip4_dest_key);
247311304SJanie.Lu@Sun.COM FSPEC_IPV4_ADDR(fspec_mask->ip4dst, tp->ip4_dest_mask);
247411304SJanie.Lu@Sun.COM FSPEC_IPV4_ADDR(fspec_key->ip4src, tp->ip4_src_key);
247511304SJanie.Lu@Sun.COM FSPEC_IPV4_ADDR(fspec_mask->ip4src, tp->ip4_src_mask);
247611304SJanie.Lu@Sun.COM fspec_key->tos = tp->ip4_tos_key;
247711304SJanie.Lu@Sun.COM fspec_mask->tos = tp->ip4_tos_mask;
247811304SJanie.Lu@Sun.COM break;
247911304SJanie.Lu@Sun.COM default:
248011304SJanie.Lu@Sun.COM break;
248111304SJanie.Lu@Sun.COM }
248211304SJanie.Lu@Sun.COM
248311304SJanie.Lu@Sun.COM switch (tp->ip4_class_key) {
248411304SJanie.Lu@Sun.COM case TCAM_CLASS_TCP_IPV4:
248511304SJanie.Lu@Sun.COM case TCAM_CLASS_UDP_IPV4:
248611304SJanie.Lu@Sun.COM case TCAM_CLASS_SCTP_IPV4:
248711304SJanie.Lu@Sun.COM FSPEC_IP_PORTS(fspec_key->pdst, fspec_key->psrc,
248811304SJanie.Lu@Sun.COM tp->ip4_port_key);
248911304SJanie.Lu@Sun.COM FSPEC_IP_PORTS(fspec_mask->pdst, fspec_mask->psrc,
249011304SJanie.Lu@Sun.COM tp->ip4_port_mask);
249111304SJanie.Lu@Sun.COM break;
249211304SJanie.Lu@Sun.COM case TCAM_CLASS_AH_ESP_IPV4:
249311304SJanie.Lu@Sun.COM fspec->uh.ahip4spec.spi = tp->ip4_port_key;
249411304SJanie.Lu@Sun.COM fspec->um.ahip4spec.spi = tp->ip4_port_mask;
249511304SJanie.Lu@Sun.COM break;
249611304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_4:
249711304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_5:
249811304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_6:
249911304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_7:
250011304SJanie.Lu@Sun.COM fspec->uh.ip_usr_spec.l4_4_bytes = tp->ip4_port_key;
250111304SJanie.Lu@Sun.COM fspec->um.ip_usr_spec.l4_4_bytes = tp->ip4_port_mask;
250211304SJanie.Lu@Sun.COM fspec->uh.ip_usr_spec.ip_ver = FSPEC_IP4;
250311304SJanie.Lu@Sun.COM fspec->uh.ip_usr_spec.proto = tp->ip4_proto_key;
250411304SJanie.Lu@Sun.COM fspec->um.ip_usr_spec.proto = tp->ip4_proto_mask;
250511304SJanie.Lu@Sun.COM break;
250611304SJanie.Lu@Sun.COM default:
250711304SJanie.Lu@Sun.COM break;
250811304SJanie.Lu@Sun.COM }
250911304SJanie.Lu@Sun.COM
251011304SJanie.Lu@Sun.COM if (tp->match_action.bits.ldw.disc == 1) {
251111304SJanie.Lu@Sun.COM fs->channel_cookie = NXGE_PKT_DISCARD;
251211304SJanie.Lu@Sun.COM } else {
251311304SJanie.Lu@Sun.COM fs->channel_cookie = tp->match_action.bits.ldw.offset;
251411304SJanie.Lu@Sun.COM }
251511304SJanie.Lu@Sun.COM }
251611304SJanie.Lu@Sun.COM
251711304SJanie.Lu@Sun.COM void
nxge_del_tcam_entry(p_nxge_t nxgep,uint32_t location)251811304SJanie.Lu@Sun.COM nxge_del_tcam_entry(p_nxge_t nxgep, uint32_t location)
251911304SJanie.Lu@Sun.COM {
252011304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS;
252111304SJanie.Lu@Sun.COM uint16_t index;
252211304SJanie.Lu@Sun.COM tcam_flow_spec_t *tcam_ep;
252311304SJanie.Lu@Sun.COM tcam_entry_t *tp;
252411304SJanie.Lu@Sun.COM tcam_class_t class;
252511304SJanie.Lu@Sun.COM
252611304SJanie.Lu@Sun.COM MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
252711304SJanie.Lu@Sun.COM index = nxge_tcam_get_index(nxgep, (uint16_t)location);
252811304SJanie.Lu@Sun.COM tcam_ep = &nxgep->classifier.tcam_entries[index];
252911304SJanie.Lu@Sun.COM if (tcam_ep->valid != 1) {
253011304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_tcam_entry: :"
253111304SJanie.Lu@Sun.COM "Entry [%d] invalid for index [%d]", location, index));
253211304SJanie.Lu@Sun.COM goto fail;
253311304SJanie.Lu@Sun.COM }
253411304SJanie.Lu@Sun.COM
253511304SJanie.Lu@Sun.COM /* Fill the flow spec entry */
253611304SJanie.Lu@Sun.COM tp = &tcam_ep->tce;
253711304SJanie.Lu@Sun.COM class = tp->ip4_class_key;
253811304SJanie.Lu@Sun.COM if (class >= TCAM_CLASS_IP_USER_4 && class <= TCAM_CLASS_IP_USER_7) {
253911304SJanie.Lu@Sun.COM int i;
254011304SJanie.Lu@Sun.COM nxge_usr_l3_cls_t *l3_ucls_p;
254111304SJanie.Lu@Sun.COM p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
254211304SJanie.Lu@Sun.COM
254311304SJanie.Lu@Sun.COM for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
254411304SJanie.Lu@Sun.COM l3_ucls_p = &hw_p->tcam_l3_prog_cls[i];
254511304SJanie.Lu@Sun.COM if (l3_ucls_p->valid) {
254611304SJanie.Lu@Sun.COM if (l3_ucls_p->cls == class &&
254711304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt) {
254811304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt--;
254911304SJanie.Lu@Sun.COM if (l3_ucls_p->tcam_ref_cnt > 0)
255011304SJanie.Lu@Sun.COM continue;
255111304SJanie.Lu@Sun.COM /* disable class */
255211304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_disable(
255311304SJanie.Lu@Sun.COM nxgep->npi_reg_handle,
255411304SJanie.Lu@Sun.COM (tcam_class_t)class);
255511304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
255611304SJanie.Lu@Sun.COM goto fail;
255711304SJanie.Lu@Sun.COM l3_ucls_p->cls = 0;
255811304SJanie.Lu@Sun.COM l3_ucls_p->pid = 0;
255911304SJanie.Lu@Sun.COM l3_ucls_p->valid = 0;
256011304SJanie.Lu@Sun.COM break;
256111304SJanie.Lu@Sun.COM }
256211304SJanie.Lu@Sun.COM }
256311304SJanie.Lu@Sun.COM }
256411304SJanie.Lu@Sun.COM if (i == NXGE_L3_PROG_CLS) {
256511304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
256611304SJanie.Lu@Sun.COM "nxge_del_tcam_entry: Usr class "
256711304SJanie.Lu@Sun.COM "0x%llx not found", (unsigned long long) class));
256811304SJanie.Lu@Sun.COM goto fail;
256911304SJanie.Lu@Sun.COM }
257011304SJanie.Lu@Sun.COM }
257111304SJanie.Lu@Sun.COM
257211304SJanie.Lu@Sun.COM rs = npi_fflp_tcam_entry_invalidate(nxgep->npi_reg_handle, index);
257311304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) {
257411304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
257511304SJanie.Lu@Sun.COM "nxge_del_tcam_entry: TCAM invalidate failed "
257611304SJanie.Lu@Sun.COM "at loc %d ", location));
257711304SJanie.Lu@Sun.COM goto fail;
257811304SJanie.Lu@Sun.COM }
257911304SJanie.Lu@Sun.COM
258011304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entries[index].valid = 0;
258111304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt--;
258211304SJanie.Lu@Sun.COM
258311304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
258411304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_del_tcam_entry"));
258511304SJanie.Lu@Sun.COM return;
258611304SJanie.Lu@Sun.COM fail:
258711304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
258811304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
258911304SJanie.Lu@Sun.COM "<== nxge_del_tcam_entry FAILED"));
259011304SJanie.Lu@Sun.COM }
259111304SJanie.Lu@Sun.COM
259211304SJanie.Lu@Sun.COM static uint8_t
nxge_iptun_pkt_type_to_pid(uint8_t pkt_type)259311304SJanie.Lu@Sun.COM nxge_iptun_pkt_type_to_pid(uint8_t pkt_type)
259411304SJanie.Lu@Sun.COM {
259511304SJanie.Lu@Sun.COM uint8_t pid = 0;
259611304SJanie.Lu@Sun.COM
259711304SJanie.Lu@Sun.COM switch (pkt_type) {
259811304SJanie.Lu@Sun.COM case IPTUN_PKT_IPV4:
259911304SJanie.Lu@Sun.COM pid = 4;
260011304SJanie.Lu@Sun.COM break;
260111304SJanie.Lu@Sun.COM case IPTUN_PKT_IPV6:
260211304SJanie.Lu@Sun.COM pid = 41;
260311304SJanie.Lu@Sun.COM break;
260411304SJanie.Lu@Sun.COM case IPTUN_PKT_GRE:
260511304SJanie.Lu@Sun.COM pid = 47;
260611304SJanie.Lu@Sun.COM break;
260711304SJanie.Lu@Sun.COM case IPTUN_PKT_GTP:
260811304SJanie.Lu@Sun.COM pid = 17;
260911304SJanie.Lu@Sun.COM break;
261011304SJanie.Lu@Sun.COM default:
261111304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
261211304SJanie.Lu@Sun.COM "nxge_iptun_pkt_type_to_pid: Unknown pkt type 0x%x",
261311304SJanie.Lu@Sun.COM pkt_type));
261411304SJanie.Lu@Sun.COM break;
261511304SJanie.Lu@Sun.COM }
261611304SJanie.Lu@Sun.COM
261711304SJanie.Lu@Sun.COM return (pid);
261811304SJanie.Lu@Sun.COM }
261911304SJanie.Lu@Sun.COM
262011304SJanie.Lu@Sun.COM static npi_status_t
nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep,uint64_t class,iptun_cfg_t * iptunp)262111304SJanie.Lu@Sun.COM nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep, uint64_t class,
262211304SJanie.Lu@Sun.COM iptun_cfg_t *iptunp)
262311304SJanie.Lu@Sun.COM {
262411304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle;
262511304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS;
262611304SJanie.Lu@Sun.COM
262711304SJanie.Lu@Sun.COM switch (iptunp->in_pkt_type) {
262811304SJanie.Lu@Sun.COM case IPTUN_PKT_IPV4:
262911304SJanie.Lu@Sun.COM case IPTUN_PKT_IPV6:
263011304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
263111304SJanie.Lu@Sun.COM (tcam_class_t)class, 0, 0, 0, 0);
263211304SJanie.Lu@Sun.COM break;
263311304SJanie.Lu@Sun.COM case IPTUN_PKT_GRE:
263411304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
263511304SJanie.Lu@Sun.COM (tcam_class_t)class, iptunp->l4b0_val,
263611304SJanie.Lu@Sun.COM iptunp->l4b0_mask, 0, 0);
263711304SJanie.Lu@Sun.COM break;
263811304SJanie.Lu@Sun.COM case IPTUN_PKT_GTP:
263911304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle,
264011304SJanie.Lu@Sun.COM (tcam_class_t)class, 0, 0, iptunp->l4b23_val,
264111304SJanie.Lu@Sun.COM (iptunp->l4b23_sel & 0x01));
264211304SJanie.Lu@Sun.COM break;
264311304SJanie.Lu@Sun.COM default:
264411304SJanie.Lu@Sun.COM rs = NPI_FFLP_TCAM_CLASS_INVALID;
264511304SJanie.Lu@Sun.COM break;
264611304SJanie.Lu@Sun.COM }
264711304SJanie.Lu@Sun.COM return (rs);
264811304SJanie.Lu@Sun.COM }
264911304SJanie.Lu@Sun.COM
265011304SJanie.Lu@Sun.COM void
nxge_add_iptun_class(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t * cls_idp)265111304SJanie.Lu@Sun.COM nxge_add_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp,
265211304SJanie.Lu@Sun.COM uint8_t *cls_idp)
265311304SJanie.Lu@Sun.COM {
265411304SJanie.Lu@Sun.COM int i, add_cls;
265511304SJanie.Lu@Sun.COM uint8_t pid;
265611304SJanie.Lu@Sun.COM uint64_t class;
265711304SJanie.Lu@Sun.COM p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
265811304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle;
265911304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS;
266011304SJanie.Lu@Sun.COM
266111304SJanie.Lu@Sun.COM pid = nxge_iptun_pkt_type_to_pid(iptunp->in_pkt_type);
266211304SJanie.Lu@Sun.COM if (pid == 0)
266311304SJanie.Lu@Sun.COM return;
266411304SJanie.Lu@Sun.COM
266511304SJanie.Lu@Sun.COM add_cls = 0;
266611304SJanie.Lu@Sun.COM MUTEX_ENTER(&hw_p->nxge_tcam_lock);
266711304SJanie.Lu@Sun.COM
266811304SJanie.Lu@Sun.COM /* Get an user programmable class ID */
266911304SJanie.Lu@Sun.COM for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
267011304SJanie.Lu@Sun.COM if (hw_p->tcam_l3_prog_cls[i].valid == 0) {
267111304SJanie.Lu@Sun.COM /* todo add new usr class reg */
267211304SJanie.Lu@Sun.COM switch (i) {
267311304SJanie.Lu@Sun.COM case 0:
267411304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_4;
267511304SJanie.Lu@Sun.COM break;
267611304SJanie.Lu@Sun.COM case 1:
267711304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_5;
267811304SJanie.Lu@Sun.COM break;
267911304SJanie.Lu@Sun.COM case 2:
268011304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_6;
268111304SJanie.Lu@Sun.COM break;
268211304SJanie.Lu@Sun.COM case 3:
268311304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_7;
268411304SJanie.Lu@Sun.COM break;
268511304SJanie.Lu@Sun.COM default:
268611304SJanie.Lu@Sun.COM break;
268711304SJanie.Lu@Sun.COM }
268811304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set(handle,
268911304SJanie.Lu@Sun.COM (tcam_class_t)class, 0, 0, pid, 0);
269011304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
269111304SJanie.Lu@Sun.COM goto fail;
269211304SJanie.Lu@Sun.COM
269311304SJanie.Lu@Sun.COM rs = nxge_set_iptun_usr_cls_reg(nxgep, class, iptunp);
269411304SJanie.Lu@Sun.COM
269511304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
269611304SJanie.Lu@Sun.COM goto fail;
269711304SJanie.Lu@Sun.COM
269811304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
269911304SJanie.Lu@Sun.COM (tcam_class_t)class);
270011304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
270111304SJanie.Lu@Sun.COM goto fail;
270211304SJanie.Lu@Sun.COM
270311304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].cls = class;
270411304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].pid = pid;
270511304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
270611304SJanie.Lu@Sun.COM iptunp->in_pkt_type;
270711304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].valid = 1;
270811304SJanie.Lu@Sun.COM *cls_idp = (uint8_t)class;
270911304SJanie.Lu@Sun.COM add_cls = 1;
271011304SJanie.Lu@Sun.COM break;
271111304SJanie.Lu@Sun.COM } else if (hw_p->tcam_l3_prog_cls[i].pid == pid) {
271211304SJanie.Lu@Sun.COM if (hw_p->tcam_l3_prog_cls[i].flow_pkt_type == 0) {
271311304SJanie.Lu@Sun.COM /* there is no flow key */
271411304SJanie.Lu@Sun.COM /* todo program the existing usr class reg */
271511304SJanie.Lu@Sun.COM
271611304SJanie.Lu@Sun.COM rs = nxge_set_iptun_usr_cls_reg(nxgep, class,
271711304SJanie.Lu@Sun.COM iptunp);
271811304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
271911304SJanie.Lu@Sun.COM goto fail;
272011304SJanie.Lu@Sun.COM
272111304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_enable(handle,
272211304SJanie.Lu@Sun.COM (tcam_class_t)class);
272311304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
272411304SJanie.Lu@Sun.COM goto fail;
272511304SJanie.Lu@Sun.COM
272611304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].flow_pkt_type =
272711304SJanie.Lu@Sun.COM iptunp->in_pkt_type;
272811304SJanie.Lu@Sun.COM *cls_idp = (uint8_t)class;
272911304SJanie.Lu@Sun.COM add_cls = 1;
273011304SJanie.Lu@Sun.COM } else {
273111304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
273211304SJanie.Lu@Sun.COM "nxge_add_iptun_class: L3 usr "
273311304SJanie.Lu@Sun.COM "programmable class with pid %d "
273411304SJanie.Lu@Sun.COM "already exists", pid));
273511304SJanie.Lu@Sun.COM }
273611304SJanie.Lu@Sun.COM break;
273711304SJanie.Lu@Sun.COM }
273811304SJanie.Lu@Sun.COM }
273911304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock);
274011304SJanie.Lu@Sun.COM
274111304SJanie.Lu@Sun.COM if (add_cls != 1) {
274211304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
274311304SJanie.Lu@Sun.COM "nxge_add_iptun_class: Could not add IP tunneling class"));
274411304SJanie.Lu@Sun.COM }
274511304SJanie.Lu@Sun.COM return;
274611304SJanie.Lu@Sun.COM fail:
274711304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock);
274811304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_iptun_class: FAILED"));
274911304SJanie.Lu@Sun.COM }
275011304SJanie.Lu@Sun.COM
275111304SJanie.Lu@Sun.COM static boolean_t
nxge_is_iptun_cls_present(p_nxge_t nxgep,uint8_t cls_id,int * idx)275211304SJanie.Lu@Sun.COM nxge_is_iptun_cls_present(p_nxge_t nxgep, uint8_t cls_id, int *idx)
275311304SJanie.Lu@Sun.COM {
275411304SJanie.Lu@Sun.COM int i;
275511304SJanie.Lu@Sun.COM p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p;
275611304SJanie.Lu@Sun.COM
275711304SJanie.Lu@Sun.COM MUTEX_ENTER(&hw_p->nxge_tcam_lock);
275811304SJanie.Lu@Sun.COM for (i = 0; i < NXGE_L3_PROG_CLS; i++) {
275911304SJanie.Lu@Sun.COM if (hw_p->tcam_l3_prog_cls[i].valid &&
276011304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].flow_pkt_type != 0) {
276111304SJanie.Lu@Sun.COM if (hw_p->tcam_l3_prog_cls[i].cls == cls_id)
276211304SJanie.Lu@Sun.COM break;
276311304SJanie.Lu@Sun.COM }
276411304SJanie.Lu@Sun.COM }
276511304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock);
276611304SJanie.Lu@Sun.COM
276711304SJanie.Lu@Sun.COM if (i == NXGE_L3_PROG_CLS) {
276811304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
276911304SJanie.Lu@Sun.COM "nxge_is_iptun_cls_present: Invalid class %d", cls_id));
277011304SJanie.Lu@Sun.COM return (B_FALSE);
277111304SJanie.Lu@Sun.COM } else {
277211304SJanie.Lu@Sun.COM *idx = i;
277311304SJanie.Lu@Sun.COM return (B_TRUE);
277411304SJanie.Lu@Sun.COM }
277511304SJanie.Lu@Sun.COM }
277611304SJanie.Lu@Sun.COM
277711304SJanie.Lu@Sun.COM void
nxge_cfg_iptun_hash(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t cls_id)277811304SJanie.Lu@Sun.COM nxge_cfg_iptun_hash(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
277911304SJanie.Lu@Sun.COM {
278011304SJanie.Lu@Sun.COM int idx;
278111304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle;
278211304SJanie.Lu@Sun.COM flow_key_cfg_t cfg;
278311304SJanie.Lu@Sun.COM
278411304SJanie.Lu@Sun.COM /* check to see that this is a valid class ID */
278511304SJanie.Lu@Sun.COM if (!nxge_is_iptun_cls_present(nxgep, cls_id, &idx)) {
278611304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
278711304SJanie.Lu@Sun.COM "nxge_cfg_iptun_hash: nxge_is_iptun_cls_present "
278811304SJanie.Lu@Sun.COM "failed for cls_id %d", cls_id));
278911304SJanie.Lu@Sun.COM return;
279011304SJanie.Lu@Sun.COM }
279111304SJanie.Lu@Sun.COM
279211304SJanie.Lu@Sun.COM bzero((void *)&cfg, sizeof (flow_key_cfg_t));
279311304SJanie.Lu@Sun.COM
279411304SJanie.Lu@Sun.COM /*
279511304SJanie.Lu@Sun.COM * This ensures that all 4 bytes of the XOR value are loaded to the
279611304SJanie.Lu@Sun.COM * hash key.
279711304SJanie.Lu@Sun.COM */
279811304SJanie.Lu@Sun.COM cfg.use_dport = cfg.use_sport = cfg.ip_opts_exist = 1;
279911304SJanie.Lu@Sun.COM
280011304SJanie.Lu@Sun.COM cfg.l4_xor_sel = (iptunp->l4xor_sel & FL_KEY_USR_L4XOR_MSK);
280111304SJanie.Lu@Sun.COM cfg.use_l4_md = 1;
280211304SJanie.Lu@Sun.COM
280311304SJanie.Lu@Sun.COM if (iptunp->hash_flags & HASH_L3PROTO)
280411304SJanie.Lu@Sun.COM cfg.use_proto = 1;
280511304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_IPDA)
280611304SJanie.Lu@Sun.COM cfg.use_daddr = 1;
280711304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_IPSA)
280811304SJanie.Lu@Sun.COM cfg.use_saddr = 1;
280911304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_VLAN)
281011304SJanie.Lu@Sun.COM cfg.use_vlan = 1;
281111304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_L2DA)
281211304SJanie.Lu@Sun.COM cfg.use_l2da = 1;
281311304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_IFPORT)
281411304SJanie.Lu@Sun.COM cfg.use_portnum = 1;
281511304SJanie.Lu@Sun.COM
281611304SJanie.Lu@Sun.COM (void) npi_fflp_cfg_ip_cls_flow_key_rfnl(handle, (tcam_class_t)cls_id,
281711304SJanie.Lu@Sun.COM &cfg);
281811304SJanie.Lu@Sun.COM }
281911304SJanie.Lu@Sun.COM
282011304SJanie.Lu@Sun.COM void
nxge_del_iptun_class(p_nxge_t nxgep,uint8_t cls_id)282111304SJanie.Lu@Sun.COM nxge_del_iptun_class(p_nxge_t nxgep, uint8_t cls_id)
282211304SJanie.Lu@Sun.COM {
282311304SJanie.Lu@Sun.COM int i;
282411304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle;
282511304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS;
282611304SJanie.Lu@Sun.COM
282711304SJanie.Lu@Sun.COM
282811304SJanie.Lu@Sun.COM /* check to see that this is a valid class ID */
282911304SJanie.Lu@Sun.COM if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) {
283011304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
283111304SJanie.Lu@Sun.COM "nxge_del_iptun_class: Invalid class ID 0x%x", cls_id));
283211304SJanie.Lu@Sun.COM return;
283311304SJanie.Lu@Sun.COM }
283411304SJanie.Lu@Sun.COM
283511304SJanie.Lu@Sun.COM MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock);
283611304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_disable(handle, (tcam_class_t)cls_id);
283711304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
283811304SJanie.Lu@Sun.COM goto fail;
283911304SJanie.Lu@Sun.COM nxgep->nxge_hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 0;
284011304SJanie.Lu@Sun.COM if (nxgep->nxge_hw_p->tcam_l3_prog_cls[i].tcam_ref_cnt == 0)
284111304SJanie.Lu@Sun.COM nxgep->nxge_hw_p->tcam_l3_prog_cls[i].valid = 0;
284211304SJanie.Lu@Sun.COM
284311304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
284411304SJanie.Lu@Sun.COM return;
284511304SJanie.Lu@Sun.COM fail:
284611304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock);
284711304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_iptun_class: FAILED"));
284811304SJanie.Lu@Sun.COM }
284911304SJanie.Lu@Sun.COM
285011304SJanie.Lu@Sun.COM void
nxge_get_iptun_class(p_nxge_t nxgep,iptun_cfg_t * iptunp,uint8_t cls_id)285111304SJanie.Lu@Sun.COM nxge_get_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id)
285211304SJanie.Lu@Sun.COM {
285311304SJanie.Lu@Sun.COM int i;
285411304SJanie.Lu@Sun.COM uint8_t pid;
285511304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle;
285611304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS;
285711304SJanie.Lu@Sun.COM flow_key_cfg_t cfg;
285811304SJanie.Lu@Sun.COM
285911304SJanie.Lu@Sun.COM
286011304SJanie.Lu@Sun.COM /* check to see that this is a valid class ID */
286111304SJanie.Lu@Sun.COM if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i))
286211304SJanie.Lu@Sun.COM return;
286311304SJanie.Lu@Sun.COM
286411304SJanie.Lu@Sun.COM bzero((void *)iptunp, sizeof (iptun_cfg_t));
286511304SJanie.Lu@Sun.COM
286611304SJanie.Lu@Sun.COM pid = nxgep->nxge_hw_p->tcam_l3_prog_cls[i].pid;
286711304SJanie.Lu@Sun.COM
286811304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_get_iptun(handle, (tcam_class_t)cls_id,
286911304SJanie.Lu@Sun.COM &iptunp->l4b0_val, &iptunp->l4b0_mask, &iptunp->l4b23_val,
287011304SJanie.Lu@Sun.COM &iptunp->l4b23_sel);
287111304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
287211304SJanie.Lu@Sun.COM goto fail;
287311304SJanie.Lu@Sun.COM
287411304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
287511304SJanie.Lu@Sun.COM (tcam_class_t)cls_id, &cfg);
287611304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
287711304SJanie.Lu@Sun.COM goto fail;
287811304SJanie.Lu@Sun.COM
287911304SJanie.Lu@Sun.COM iptunp->l4xor_sel = cfg.l4_xor_sel;
288011304SJanie.Lu@Sun.COM if (cfg.use_proto)
288111304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_L3PROTO;
288211304SJanie.Lu@Sun.COM else if (cfg.use_daddr)
288311304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_IPDA;
288411304SJanie.Lu@Sun.COM else if (cfg.use_saddr)
288511304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_IPSA;
288611304SJanie.Lu@Sun.COM else if (cfg.use_vlan)
288711304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_VLAN;
288811304SJanie.Lu@Sun.COM else if (cfg.use_l2da)
288911304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_L2DA;
289011304SJanie.Lu@Sun.COM else if (cfg.use_portnum)
289111304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_IFPORT;
289211304SJanie.Lu@Sun.COM
289311304SJanie.Lu@Sun.COM switch (pid) {
289411304SJanie.Lu@Sun.COM case 4:
289511304SJanie.Lu@Sun.COM iptunp->in_pkt_type = IPTUN_PKT_IPV4;
289611304SJanie.Lu@Sun.COM break;
289711304SJanie.Lu@Sun.COM case 41:
289811304SJanie.Lu@Sun.COM iptunp->in_pkt_type = IPTUN_PKT_IPV6;
289911304SJanie.Lu@Sun.COM break;
290011304SJanie.Lu@Sun.COM case 47:
290111304SJanie.Lu@Sun.COM iptunp->in_pkt_type = IPTUN_PKT_GRE;
290211304SJanie.Lu@Sun.COM break;
290311304SJanie.Lu@Sun.COM case 17:
290411304SJanie.Lu@Sun.COM iptunp->in_pkt_type = IPTUN_PKT_GTP;
290511304SJanie.Lu@Sun.COM break;
290611304SJanie.Lu@Sun.COM default:
290711304SJanie.Lu@Sun.COM iptunp->in_pkt_type = 0;
290811304SJanie.Lu@Sun.COM break;
290911304SJanie.Lu@Sun.COM }
291011304SJanie.Lu@Sun.COM
291111304SJanie.Lu@Sun.COM return;
291211304SJanie.Lu@Sun.COM fail:
291311304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_iptun_class: FAILED"));
291411304SJanie.Lu@Sun.COM }
291511304SJanie.Lu@Sun.COM
291611304SJanie.Lu@Sun.COM void
nxge_set_ip_cls_sym(p_nxge_t nxgep,uint8_t cls_id,uint8_t sym)291711304SJanie.Lu@Sun.COM nxge_set_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t sym)
291811304SJanie.Lu@Sun.COM {
291911304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle;
292011304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS;
292111304SJanie.Lu@Sun.COM boolean_t sym_en = (sym == 1) ? B_TRUE : B_FALSE;
292211304SJanie.Lu@Sun.COM
292311304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_sym_ip_cls_flow_key(handle, (tcam_class_t)cls_id,
292411304SJanie.Lu@Sun.COM sym_en);
292511304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
292611304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
292711304SJanie.Lu@Sun.COM "nxge_set_ip_cls_sym: FAILED"));
292811304SJanie.Lu@Sun.COM }
292911304SJanie.Lu@Sun.COM
293011304SJanie.Lu@Sun.COM void
nxge_get_ip_cls_sym(p_nxge_t nxgep,uint8_t cls_id,uint8_t * sym)293111304SJanie.Lu@Sun.COM nxge_get_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t *sym)
293211304SJanie.Lu@Sun.COM {
293311304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle;
293411304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS;
293511304SJanie.Lu@Sun.COM flow_key_cfg_t cfg;
293611304SJanie.Lu@Sun.COM
293711304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle,
293811304SJanie.Lu@Sun.COM (tcam_class_t)cls_id, &cfg);
293911304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS)
294011304SJanie.Lu@Sun.COM goto fail;
294111304SJanie.Lu@Sun.COM
294211304SJanie.Lu@Sun.COM if (cfg.use_sym)
294311304SJanie.Lu@Sun.COM *sym = 1;
294411304SJanie.Lu@Sun.COM else
294511304SJanie.Lu@Sun.COM *sym = 0;
294611304SJanie.Lu@Sun.COM return;
294711304SJanie.Lu@Sun.COM fail:
294811304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_ip_cls_sym: FAILED"));
294911304SJanie.Lu@Sun.COM }
2950