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 */ 213859Sml29623 /* 22*11304SJanie.Lu@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 233859Sml29623 * Use is subject to license terms. 243859Sml29623 */ 253859Sml29623 263859Sml29623 #include <npi_fflp.h> 273859Sml29623 #include <npi_mac.h> 283859Sml29623 #include <nxge_defs.h> 293859Sml29623 #include <nxge_flow.h> 303859Sml29623 #include <nxge_fflp.h> 313859Sml29623 #include <nxge_impl.h> 323859Sml29623 #include <nxge_fflp_hash.h> 333859Sml29623 #include <nxge_common.h> 343859Sml29623 353859Sml29623 363859Sml29623 /* 373859Sml29623 * Function prototypes 383859Sml29623 */ 393859Sml29623 static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t); 403859Sml29623 static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t); 413859Sml29623 static nxge_status_t nxge_fflp_tcam_init(p_nxge_t); 423859Sml29623 static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t); 433859Sml29623 static nxge_status_t nxge_fflp_fcram_init(p_nxge_t); 443859Sml29623 static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *); 453859Sml29623 static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 463859Sml29623 static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 473859Sml29623 static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 483859Sml29623 static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *, 493859Sml29623 tcam_entry_t *); 503859Sml29623 static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *, 513859Sml29623 tcam_entry_t *); 523859Sml29623 static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *, 533859Sml29623 tcam_entry_t *); 54*11304SJanie.Lu@Sun.COM static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t); 55*11304SJanie.Lu@Sun.COM static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t); 56*11304SJanie.Lu@Sun.COM static uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t); 57*11304SJanie.Lu@Sun.COM static uint32_t nxge_tcam_cls_to_flow(uint32_t); 58*11304SJanie.Lu@Sun.COM static uint8_t nxge_iptun_pkt_type_to_pid(uint8_t); 59*11304SJanie.Lu@Sun.COM static npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t, 60*11304SJanie.Lu@Sun.COM iptun_cfg_t *); 61*11304SJanie.Lu@Sun.COM static boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *); 623859Sml29623 633859Sml29623 /* 643859Sml29623 * functions used outside this file 653859Sml29623 */ 663859Sml29623 nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t); 673859Sml29623 nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t); 683859Sml29623 nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *); 693859Sml29623 static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t); 703859Sml29623 nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *); 713859Sml29623 nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *); 723859Sml29623 nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *, 733859Sml29623 uint32_t *, uint16_t *); 74*11304SJanie.Lu@Sun.COM int nxge_get_valid_tcam_cnt(p_nxge_t); 75*11304SJanie.Lu@Sun.COM void nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *); 76*11304SJanie.Lu@Sun.COM void nxge_get_tcam_entry(p_nxge_t, flow_resource_t *); 77*11304SJanie.Lu@Sun.COM void nxge_del_tcam_entry(p_nxge_t, uint32_t); 78*11304SJanie.Lu@Sun.COM void nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *); 79*11304SJanie.Lu@Sun.COM void nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t); 80*11304SJanie.Lu@Sun.COM void nxge_del_iptun_class(p_nxge_t, uint8_t); 81*11304SJanie.Lu@Sun.COM void nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t); 82*11304SJanie.Lu@Sun.COM void nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t); 83*11304SJanie.Lu@Sun.COM void nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *); 84*11304SJanie.Lu@Sun.COM 853859Sml29623 863859Sml29623 nxge_status_t 873859Sml29623 nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location) 883859Sml29623 { 893859Sml29623 tcam_entry_t tcam_rdptr; 903859Sml29623 uint64_t asc_ram = 0; 913859Sml29623 npi_handle_t handle; 923859Sml29623 npi_status_t status; 933859Sml29623 943859Sml29623 handle = nxgep->npi_reg_handle; 953859Sml29623 963859Sml29623 bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry)); 973859Sml29623 status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location, 986929Smisaki (struct tcam_entry *)&tcam_rdptr); 993859Sml29623 if (status & NPI_FAILURE) { 1003859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1016929Smisaki " nxge_tcam_dump_entry:" 1026929Smisaki " tcam read failed at location %d ", location)); 1033859Sml29623 return (NXGE_ERROR); 1043859Sml29623 } 1053859Sml29623 status = npi_fflp_tcam_asc_ram_entry_read(handle, 1066929Smisaki (tcam_location_t)location, &asc_ram); 1073859Sml29623 1083859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n" 1096929Smisaki " key: %llx %llx %llx %llx \n" 1106929Smisaki " mask: %llx %llx %llx %llx \n" 1116929Smisaki " ASC RAM %llx \n", location, 1126929Smisaki tcam_rdptr.key0, tcam_rdptr.key1, 1136929Smisaki tcam_rdptr.key2, tcam_rdptr.key3, 1146929Smisaki tcam_rdptr.mask0, tcam_rdptr.mask1, 1156929Smisaki tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram)); 1163859Sml29623 return (NXGE_OK); 1173859Sml29623 } 1183859Sml29623 1193859Sml29623 void 1203859Sml29623 nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp) 1213859Sml29623 { 1223859Sml29623 uint32_t tcam_loc; 1233859Sml29623 int *lptr; 1243859Sml29623 int location; 1253859Sml29623 1263859Sml29623 uint32_t start_location = 0; 1273859Sml29623 uint32_t stop_location = nxgep->classifier.tcam_size; 1283859Sml29623 lptr = (int *)mp->b_rptr; 1293859Sml29623 location = *lptr; 1303859Sml29623 1313859Sml29623 if ((location >= nxgep->classifier.tcam_size) || (location < -1)) { 1323859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1336929Smisaki "nxge_tcam_dump: Invalid location %d \n", location)); 1343859Sml29623 return; 1353859Sml29623 } 1363859Sml29623 if (location == -1) { 1373859Sml29623 start_location = 0; 1383859Sml29623 stop_location = nxgep->classifier.tcam_size; 1393859Sml29623 } else { 1403859Sml29623 start_location = location; 1413859Sml29623 stop_location = location + 1; 1423859Sml29623 } 1433859Sml29623 for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++) 1443859Sml29623 (void) nxge_tcam_dump_entry(nxgep, tcam_loc); 1453859Sml29623 } 1463859Sml29623 1473859Sml29623 /* 1483859Sml29623 * nxge_fflp_vlan_table_invalidate_all 1493859Sml29623 * invalidates the vlan RDC table entries. 1503859Sml29623 * INPUT 1513859Sml29623 * nxge soft state data structure 1523859Sml29623 * Return 1533859Sml29623 * NXGE_OK 1543859Sml29623 * NXGE_ERROR 1553859Sml29623 * 1563859Sml29623 */ 1573859Sml29623 1583859Sml29623 static nxge_status_t 1593859Sml29623 nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep) 1603859Sml29623 { 1613859Sml29623 vlan_id_t vlan_id; 1623859Sml29623 npi_handle_t handle; 1633859Sml29623 npi_status_t rs = NPI_SUCCESS; 1643859Sml29623 vlan_id_t start = 0, stop = NXGE_MAX_VLANS; 1653859Sml29623 1663859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all ")); 1673859Sml29623 handle = nxgep->npi_reg_handle; 1683859Sml29623 for (vlan_id = start; vlan_id < stop; vlan_id++) { 1693859Sml29623 rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id); 1703859Sml29623 if (rs != NPI_SUCCESS) { 1713859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1726929Smisaki "VLAN Table invalidate failed for vlan id %d ", 1736929Smisaki vlan_id)); 1743859Sml29623 return (NXGE_ERROR | rs); 1753859Sml29623 } 1763859Sml29623 } 1773859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all ")); 1783859Sml29623 return (NXGE_OK); 1793859Sml29623 } 1803859Sml29623 1813859Sml29623 /* 1823859Sml29623 * The following functions are used by other modules to init 1833859Sml29623 * the fflp module. 1843859Sml29623 * these functions are the basic API used to init 1853859Sml29623 * the fflp modules (tcam, fcram etc ......) 1863859Sml29623 * 1873859Sml29623 * The TCAM search future would be disabled by default. 1883859Sml29623 */ 1893859Sml29623 1903859Sml29623 static nxge_status_t 1913859Sml29623 nxge_fflp_tcam_init(p_nxge_t nxgep) 1923859Sml29623 { 1933859Sml29623 uint8_t access_ratio; 1943859Sml29623 tcam_class_t class; 1953859Sml29623 npi_status_t rs = NPI_SUCCESS; 1963859Sml29623 npi_handle_t handle; 1973859Sml29623 1983859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init")); 1993859Sml29623 handle = nxgep->npi_reg_handle; 2003859Sml29623 2013859Sml29623 rs = npi_fflp_cfg_tcam_disable(handle); 2023859Sml29623 if (rs != NPI_SUCCESS) { 2033859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n")); 2043859Sml29623 return (NXGE_ERROR | rs); 2053859Sml29623 } 2063859Sml29623 2073859Sml29623 access_ratio = nxgep->param_arr[param_tcam_access_ratio].value; 2083859Sml29623 rs = npi_fflp_cfg_tcam_access(handle, access_ratio); 2093859Sml29623 if (rs != NPI_SUCCESS) { 2103859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2116929Smisaki "failed TCAM Access cfg\n")); 2123859Sml29623 return (NXGE_ERROR | rs); 2133859Sml29623 } 2143859Sml29623 2153859Sml29623 /* disable configurable classes */ 2163859Sml29623 /* disable the configurable ethernet classes; */ 2173859Sml29623 for (class = TCAM_CLASS_ETYPE_1; 2186929Smisaki class <= TCAM_CLASS_ETYPE_2; class++) { 2193859Sml29623 rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class); 2203859Sml29623 if (rs != NPI_SUCCESS) { 2213859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2226929Smisaki "TCAM USR Ether Class config failed.")); 2233859Sml29623 return (NXGE_ERROR | rs); 2243859Sml29623 } 2253859Sml29623 } 2263859Sml29623 2273859Sml29623 /* disable the configurable ip classes; */ 2283859Sml29623 for (class = TCAM_CLASS_IP_USER_4; 2296929Smisaki class <= TCAM_CLASS_IP_USER_7; class++) { 2303859Sml29623 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 2313859Sml29623 if (rs != NPI_SUCCESS) { 2323859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2336929Smisaki "TCAM USR IP Class cnfg failed.")); 2343859Sml29623 return (NXGE_ERROR | rs); 2353859Sml29623 } 2363859Sml29623 } 2373859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init")); 2383859Sml29623 return (NXGE_OK); 2393859Sml29623 } 2403859Sml29623 2413859Sml29623 /* 2423859Sml29623 * nxge_fflp_tcam_invalidate_all 2433859Sml29623 * invalidates all the tcam entries. 2443859Sml29623 * INPUT 2453859Sml29623 * nxge soft state data structure 2463859Sml29623 * Return 2473859Sml29623 * NXGE_OK 2483859Sml29623 * NXGE_ERROR 2493859Sml29623 * 2503859Sml29623 */ 2513859Sml29623 2523859Sml29623 2533859Sml29623 static nxge_status_t 2543859Sml29623 nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep) 2553859Sml29623 { 2563859Sml29623 uint16_t location; 2573859Sml29623 npi_status_t rs = NPI_SUCCESS; 2583859Sml29623 npi_handle_t handle; 2593859Sml29623 uint16_t start = 0, stop = nxgep->classifier.tcam_size; 2603859Sml29623 p_nxge_hw_list_t hw_p; 2613859Sml29623 2623859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2636929Smisaki "==> nxge_fflp_tcam_invalidate_all")); 2643859Sml29623 handle = nxgep->npi_reg_handle; 2653859Sml29623 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 2663859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2676929Smisaki " nxge_fflp_tcam_invalidate_all:" 2686929Smisaki " common hardware not set", nxgep->niu_type)); 2693859Sml29623 return (NXGE_ERROR); 2703859Sml29623 } 2713859Sml29623 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 2723859Sml29623 for (location = start; location < stop; location++) { 2733859Sml29623 rs = npi_fflp_tcam_entry_invalidate(handle, location); 2743859Sml29623 if (rs != NPI_SUCCESS) { 2753859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2763859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2776929Smisaki "TCAM invalidate failed at loc %d ", location)); 2783859Sml29623 return (NXGE_ERROR | rs); 2793859Sml29623 } 2803859Sml29623 } 2813859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2823859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2836929Smisaki "<== nxge_fflp_tcam_invalidate_all")); 2843859Sml29623 return (NXGE_OK); 2853859Sml29623 } 2863859Sml29623 2873859Sml29623 /* 2883859Sml29623 * nxge_fflp_fcram_entry_invalidate_all 2893859Sml29623 * invalidates all the FCRAM entries. 2903859Sml29623 * INPUT 2913859Sml29623 * nxge soft state data structure 2923859Sml29623 * Return 2933859Sml29623 * NXGE_OK 2943859Sml29623 * NXGE_ERROR 2953859Sml29623 * 2963859Sml29623 */ 2973859Sml29623 2983859Sml29623 static nxge_status_t 2993859Sml29623 nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep) 3003859Sml29623 { 3013859Sml29623 npi_handle_t handle; 3023859Sml29623 npi_status_t rs = NPI_SUCCESS; 3033859Sml29623 part_id_t pid = 0; 3043859Sml29623 uint8_t base_mask, base_reloc; 3053859Sml29623 fcram_entry_t fc; 3063859Sml29623 uint32_t location; 3073859Sml29623 uint32_t increment, last_location; 3083859Sml29623 3093859Sml29623 /* 3103859Sml29623 * (1) configure and enable partition 0 with no relocation 3113859Sml29623 * (2) Assume the FCRAM is used as IPv4 exact match entry cells 3123859Sml29623 * (3) Invalidate these cells by clearing the valid bit in 3133859Sml29623 * the subareas 0 and 4 3143859Sml29623 * (4) disable the partition 3153859Sml29623 * 3163859Sml29623 */ 3173859Sml29623 3183859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all")); 3193859Sml29623 3203859Sml29623 base_mask = base_reloc = 0x0; 3213859Sml29623 handle = nxgep->npi_reg_handle; 3223859Sml29623 rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc); 3233859Sml29623 3243859Sml29623 if (rs != NPI_SUCCESS) { 3253859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n")); 3263859Sml29623 return (NXGE_ERROR | rs); 3273859Sml29623 } 3283859Sml29623 rs = npi_fflp_cfg_fcram_partition_disable(handle, pid); 3293859Sml29623 3303859Sml29623 if (rs != NPI_SUCCESS) { 3313859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3326929Smisaki "failed partition enable\n")); 3333859Sml29623 return (NXGE_ERROR | rs); 3343859Sml29623 } 3353859Sml29623 fc.dreg[0].value = 0; 3363859Sml29623 fc.hash_hdr_valid = 0; 3373859Sml29623 fc.hash_hdr_ext = 1; /* specify as IPV4 exact match entry */ 3383859Sml29623 increment = sizeof (hash_ipv4_t); 3393859Sml29623 last_location = FCRAM_SIZE * 0x40; 3403859Sml29623 3413859Sml29623 for (location = 0; location < last_location; location += increment) { 3423859Sml29623 rs = npi_fflp_fcram_subarea_write(handle, pid, 3436929Smisaki location, fc.value[0]); 3443859Sml29623 if (rs != NPI_SUCCESS) { 3453859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3466929Smisaki "failed write at location %x ", location)); 3473859Sml29623 return (NXGE_ERROR | rs); 3483859Sml29623 } 3493859Sml29623 } 3503859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all")); 3513859Sml29623 return (NXGE_OK); 3523859Sml29623 } 3533859Sml29623 3543859Sml29623 static nxge_status_t 3553859Sml29623 nxge_fflp_fcram_init(p_nxge_t nxgep) 3563859Sml29623 { 3573859Sml29623 fflp_fcram_output_drive_t strength; 3583859Sml29623 fflp_fcram_qs_t qs; 3593859Sml29623 npi_status_t rs = NPI_SUCCESS; 3603859Sml29623 uint8_t access_ratio; 3613859Sml29623 int partition; 3623859Sml29623 npi_handle_t handle; 3633859Sml29623 uint32_t min_time, max_time, sys_time; 3643859Sml29623 3653859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init")); 3663859Sml29623 3673859Sml29623 /* 3683859Sml29623 * Recommended values are needed. 3693859Sml29623 */ 3703859Sml29623 min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME; 3713859Sml29623 max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME; 3723859Sml29623 sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME; 3733859Sml29623 3743859Sml29623 handle = nxgep->npi_reg_handle; 3753859Sml29623 strength = FCRAM_OUTDR_NORMAL; 3763859Sml29623 qs = FCRAM_QS_MODE_QS; 3773859Sml29623 rs = npi_fflp_cfg_fcram_reset(handle, strength, qs); 3783859Sml29623 if (rs != NPI_SUCCESS) { 3793859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. ")); 3803859Sml29623 return (NXGE_ERROR | rs); 3813859Sml29623 } 3823859Sml29623 3833859Sml29623 access_ratio = nxgep->param_arr[param_fcram_access_ratio].value; 3843859Sml29623 rs = npi_fflp_cfg_fcram_access(handle, access_ratio); 3853859Sml29623 if (rs != NPI_SUCCESS) { 3863859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio" 3876929Smisaki "configuration \n")); 3883859Sml29623 return (NXGE_ERROR | rs); 3893859Sml29623 } 3903859Sml29623 rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time, 3916929Smisaki max_time, sys_time); 3923859Sml29623 if (rs != NPI_SUCCESS) { 3933859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3946929Smisaki "failed FCRAM refresh cfg")); 3953859Sml29623 return (NXGE_ERROR); 3963859Sml29623 } 3973859Sml29623 3983859Sml29623 /* disable all the partitions until explicitly enabled */ 3993859Sml29623 for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) { 4003859Sml29623 rs = npi_fflp_cfg_fcram_partition_disable(handle, partition); 4013859Sml29623 if (rs != NPI_SUCCESS) { 4023859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4036929Smisaki "failed FCRAM partition" 4046929Smisaki " enable for partition %d ", partition)); 4053859Sml29623 return (NXGE_ERROR | rs); 4063859Sml29623 } 4073859Sml29623 } 4083859Sml29623 4093859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init")); 4103859Sml29623 return (NXGE_OK); 4113859Sml29623 } 4123859Sml29623 4133859Sml29623 nxge_status_t 4143859Sml29623 nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac) 4153859Sml29623 { 4163859Sml29623 npi_status_t rs = NPI_SUCCESS; 4173859Sml29623 hostinfo_t mac_rdc; 4183859Sml29623 npi_handle_t handle; 4193859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 4203859Sml29623 4213859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 4223859Sml29623 if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) { 4233859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4246929Smisaki " nxge_logical_mac_assign_rdc_table" 4256929Smisaki " unconfigured alt MAC addr %d ", alt_mac)); 4263859Sml29623 return (NXGE_ERROR); 4273859Sml29623 } 4283859Sml29623 handle = nxgep->npi_reg_handle; 4293859Sml29623 mac_rdc.value = 0; 4303859Sml29623 mac_rdc.bits.w0.rdc_tbl_num = 4316929Smisaki p_class_cfgp->mac_host_info[alt_mac].rdctbl; 4323859Sml29623 mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr; 4333859Sml29623 4343859Sml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET, 4356929Smisaki nxgep->function_num, alt_mac, &mac_rdc); 4363859Sml29623 4373859Sml29623 if (rs != NPI_SUCCESS) { 4383859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4396929Smisaki "failed Assign RDC table")); 4403859Sml29623 return (NXGE_ERROR | rs); 4413859Sml29623 } 4423859Sml29623 return (NXGE_OK); 4433859Sml29623 } 4443859Sml29623 4453859Sml29623 nxge_status_t 4463859Sml29623 nxge_main_mac_assign_rdc_table(p_nxge_t nxgep) 4473859Sml29623 { 4483859Sml29623 npi_status_t rs = NPI_SUCCESS; 4493859Sml29623 hostinfo_t mac_rdc; 4503859Sml29623 npi_handle_t handle; 4513859Sml29623 4523859Sml29623 handle = nxgep->npi_reg_handle; 4533859Sml29623 mac_rdc.value = 0; 4543859Sml29623 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp; 4553859Sml29623 mac_rdc.bits.w0.mac_pref = 1; 4563859Sml29623 switch (nxgep->function_num) { 4573859Sml29623 case 0: 4583859Sml29623 case 1: 4593859Sml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET, 4606929Smisaki nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 4613859Sml29623 break; 4623859Sml29623 case 2: 4633859Sml29623 case 3: 4643859Sml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET, 4656929Smisaki nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 4663859Sml29623 break; 4673859Sml29623 default: 4683859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4696929Smisaki "failed Assign RDC table (invalid function #)")); 4703859Sml29623 return (NXGE_ERROR); 4713859Sml29623 } 4723859Sml29623 4733859Sml29623 if (rs != NPI_SUCCESS) { 4743859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4756929Smisaki "failed Assign RDC table")); 4763859Sml29623 return (NXGE_ERROR | rs); 4773859Sml29623 } 4783859Sml29623 return (NXGE_OK); 4793859Sml29623 } 4803859Sml29623 4813859Sml29623 /* 4823859Sml29623 * Initialize hostinfo registers for alternate MAC addresses and 4833859Sml29623 * multicast MAC address. 4843859Sml29623 */ 4853859Sml29623 nxge_status_t 4863859Sml29623 nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep) 4873859Sml29623 { 4883859Sml29623 npi_status_t rs = NPI_SUCCESS; 4893859Sml29623 hostinfo_t mac_rdc; 4903859Sml29623 npi_handle_t handle; 4913859Sml29623 int i; 4923859Sml29623 4933859Sml29623 handle = nxgep->npi_reg_handle; 4943859Sml29623 mac_rdc.value = 0; 4953859Sml29623 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp; 4963859Sml29623 mac_rdc.bits.w0.mac_pref = 1; 4973859Sml29623 switch (nxgep->function_num) { 4983859Sml29623 case 0: 4993859Sml29623 case 1: 5003859Sml29623 /* 5013859Sml29623 * Tests indicate that it is OK not to re-initialize the 5023859Sml29623 * hostinfo registers for the XMAC's alternate MAC 5033859Sml29623 * addresses. But that is necessary for BMAC (case 2 5043859Sml29623 * and case 3 below) 5053859Sml29623 */ 5063859Sml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET, 5076929Smisaki nxgep->function_num, 5086929Smisaki XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 5093859Sml29623 break; 5103859Sml29623 case 2: 5113859Sml29623 case 3: 5123859Sml29623 for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++) 5133859Sml29623 rs |= npi_mac_hostinfo_entry(handle, OP_SET, 5146929Smisaki nxgep->function_num, i, &mac_rdc); 5153859Sml29623 5163859Sml29623 rs |= npi_mac_hostinfo_entry(handle, OP_SET, 5176929Smisaki nxgep->function_num, 5186929Smisaki BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 5193859Sml29623 break; 5203859Sml29623 default: 5213859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5226929Smisaki "failed Assign RDC table (invalid function #)")); 5233859Sml29623 return (NXGE_ERROR); 5243859Sml29623 } 5253859Sml29623 5263859Sml29623 if (rs != NPI_SUCCESS) { 5273859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5286929Smisaki "failed Assign RDC table")); 5293859Sml29623 return (NXGE_ERROR | rs); 5303859Sml29623 } 5313859Sml29623 return (NXGE_OK); 5323859Sml29623 } 5333859Sml29623 5343859Sml29623 nxge_status_t 5353859Sml29623 nxge_fflp_init_hostinfo(p_nxge_t nxgep) 5363859Sml29623 { 5373859Sml29623 nxge_status_t status = NXGE_OK; 5383859Sml29623 5393859Sml29623 status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 5403859Sml29623 status |= nxge_main_mac_assign_rdc_table(nxgep); 5413859Sml29623 return (status); 5423859Sml29623 } 5433859Sml29623 5443859Sml29623 nxge_status_t 5453859Sml29623 nxge_fflp_hw_reset(p_nxge_t nxgep) 5463859Sml29623 { 5473859Sml29623 npi_handle_t handle; 5483859Sml29623 npi_status_t rs = NPI_SUCCESS; 5493859Sml29623 nxge_status_t status = NXGE_OK; 5503859Sml29623 5513859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset")); 5523859Sml29623 5534977Sraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 5543859Sml29623 status = nxge_fflp_fcram_init(nxgep); 5553859Sml29623 if (status != NXGE_OK) { 5563859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5576929Smisaki " failed FCRAM init. ")); 5583859Sml29623 return (status); 5593859Sml29623 } 5603859Sml29623 } 5613859Sml29623 5623859Sml29623 status = nxge_fflp_tcam_init(nxgep); 5633859Sml29623 if (status != NXGE_OK) { 5643859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5656929Smisaki "failed TCAM init.")); 5663859Sml29623 return (status); 5673859Sml29623 } 5683859Sml29623 5693859Sml29623 handle = nxgep->npi_reg_handle; 5703859Sml29623 rs = npi_fflp_cfg_llcsnap_enable(handle); 5713859Sml29623 if (rs != NPI_SUCCESS) { 5723859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5736929Smisaki "failed LLCSNAP enable. ")); 5743859Sml29623 return (NXGE_ERROR | rs); 5753859Sml29623 } 5763859Sml29623 5773859Sml29623 rs = npi_fflp_cfg_cam_errorcheck_disable(handle); 5783859Sml29623 if (rs != NPI_SUCCESS) { 5793859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5806929Smisaki "failed CAM Error Check enable. ")); 5813859Sml29623 return (NXGE_ERROR | rs); 5823859Sml29623 } 5833859Sml29623 5843859Sml29623 /* init the hash generators */ 5853859Sml29623 rs = npi_fflp_cfg_hash_h1poly(handle, 0); 5863859Sml29623 if (rs != NPI_SUCCESS) { 5873859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5886929Smisaki "failed H1 Poly Init. ")); 5893859Sml29623 return (NXGE_ERROR | rs); 5903859Sml29623 } 5913859Sml29623 5923859Sml29623 rs = npi_fflp_cfg_hash_h2poly(handle, 0); 5933859Sml29623 if (rs != NPI_SUCCESS) { 5943859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5956929Smisaki "failed H2 Poly Init. ")); 5963859Sml29623 return (NXGE_ERROR | rs); 5973859Sml29623 } 5983859Sml29623 5993859Sml29623 /* invalidate TCAM entries */ 6003859Sml29623 status = nxge_fflp_tcam_invalidate_all(nxgep); 6013859Sml29623 if (status != NXGE_OK) { 6023859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6036929Smisaki "failed TCAM Entry Invalidate. ")); 6043859Sml29623 return (status); 6053859Sml29623 } 6063859Sml29623 6073859Sml29623 /* invalidate FCRAM entries */ 6084977Sraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 6093859Sml29623 status = nxge_fflp_fcram_invalidate_all(nxgep); 6103859Sml29623 if (status != NXGE_OK) { 6113859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6126929Smisaki "failed FCRAM Entry Invalidate.")); 6133859Sml29623 return (status); 6143859Sml29623 } 6153859Sml29623 } 6163859Sml29623 6173859Sml29623 /* invalidate VLAN RDC tables */ 6183859Sml29623 status = nxge_fflp_vlan_tbl_clear_all(nxgep); 6193859Sml29623 if (status != NXGE_OK) { 6203859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6216929Smisaki "failed VLAN Table Invalidate. ")); 6223859Sml29623 return (status); 6233859Sml29623 } 6243859Sml29623 nxgep->classifier.state |= NXGE_FFLP_HW_RESET; 6253859Sml29623 6263859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset")); 6273859Sml29623 return (NXGE_OK); 6283859Sml29623 } 6293859Sml29623 6303859Sml29623 nxge_status_t 6313859Sml29623 nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class, 6323859Sml29623 uint32_t class_config) 6333859Sml29623 { 6343859Sml29623 flow_key_cfg_t fcfg; 6353859Sml29623 npi_handle_t handle; 6363859Sml29623 npi_status_t rs = NPI_SUCCESS; 6373859Sml29623 6383859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key")); 6393859Sml29623 handle = nxgep->npi_reg_handle; 6403859Sml29623 bzero(&fcfg, sizeof (flow_key_cfg_t)); 6413859Sml29623 6423859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_PROTO) 6433859Sml29623 fcfg.use_proto = 1; 6443859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT) 6453859Sml29623 fcfg.use_dport = 1; 6463859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT) 6473859Sml29623 fcfg.use_sport = 1; 6483859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_IPDST) 6493859Sml29623 fcfg.use_daddr = 1; 6503859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_IPSRC) 6513859Sml29623 fcfg.use_saddr = 1; 6523859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_VLAN) 6533859Sml29623 fcfg.use_vlan = 1; 6543859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_L2DA) 6553859Sml29623 fcfg.use_l2da = 1; 6563859Sml29623 if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM) 6573859Sml29623 fcfg.use_portnum = 1; 6583859Sml29623 fcfg.ip_opts_exist = 0; 6593859Sml29623 6603859Sml29623 rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg); 6613859Sml29623 if (rs & NPI_FFLP_ERROR) { 6623859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 6636929Smisaki " opt %x for class %d failed ", class_config, l3_class)); 6643859Sml29623 return (NXGE_ERROR | rs); 6653859Sml29623 } 6663859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key")); 6673859Sml29623 return (NXGE_OK); 6683859Sml29623 } 6693859Sml29623 6703859Sml29623 nxge_status_t 6713859Sml29623 nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class, 6723859Sml29623 uint32_t *class_config) 6733859Sml29623 { 6743859Sml29623 flow_key_cfg_t fcfg; 6753859Sml29623 npi_handle_t handle; 6763859Sml29623 npi_status_t rs = NPI_SUCCESS; 6773859Sml29623 uint32_t ccfg = 0; 6783859Sml29623 6793859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get")); 6803859Sml29623 handle = nxgep->npi_reg_handle; 6813859Sml29623 bzero(&fcfg, sizeof (flow_key_cfg_t)); 6823859Sml29623 6833859Sml29623 rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg); 6843859Sml29623 if (rs & NPI_FFLP_ERROR) { 6853859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 6866929Smisaki " opt %x for class %d failed ", class_config, l3_class)); 6873859Sml29623 return (NXGE_ERROR | rs); 6883859Sml29623 } 6893859Sml29623 6903859Sml29623 if (fcfg.use_proto) 6913859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_PROTO; 6923859Sml29623 if (fcfg.use_dport) 6933859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT; 6943859Sml29623 if (fcfg.use_sport) 6953859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT; 6963859Sml29623 if (fcfg.use_daddr) 6973859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_IPDST; 6983859Sml29623 if (fcfg.use_saddr) 6993859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_IPSRC; 7003859Sml29623 if (fcfg.use_vlan) 7013859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_VLAN; 7023859Sml29623 if (fcfg.use_l2da) 7033859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_L2DA; 7043859Sml29623 if (fcfg.use_portnum) 7053859Sml29623 ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM; 7063859Sml29623 7073859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 7086929Smisaki " nxge_cfg_ip_cls_flow_key_get %x", ccfg)); 7093859Sml29623 *class_config = ccfg; 7103859Sml29623 7113859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 7126929Smisaki " <== nxge_cfg_ip_cls_flow_key_get")); 7133859Sml29623 return (NXGE_OK); 7143859Sml29623 } 7153859Sml29623 7163859Sml29623 static nxge_status_t 7173859Sml29623 nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class, 7183859Sml29623 uint32_t *class_config) 7193859Sml29623 { 7203859Sml29623 npi_status_t rs = NPI_SUCCESS; 7213859Sml29623 tcam_key_cfg_t cfg; 7223859Sml29623 npi_handle_t handle; 7233859Sml29623 uint32_t ccfg = 0; 7243859Sml29623 7253859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 7263859Sml29623 7273859Sml29623 bzero(&cfg, sizeof (tcam_key_cfg_t)); 7283859Sml29623 handle = nxgep->npi_reg_handle; 7293859Sml29623 7303859Sml29623 rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg); 7313859Sml29623 if (rs & NPI_FFLP_ERROR) { 7323859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 7336929Smisaki " opt %x for class %d failed ", class_config, class)); 7343859Sml29623 return (NXGE_ERROR | rs); 7353859Sml29623 } 7363859Sml29623 if (cfg.discard) 7373859Sml29623 ccfg |= NXGE_CLASS_DISCARD; 7383859Sml29623 if (cfg.lookup_enable) 7393859Sml29623 ccfg |= NXGE_CLASS_TCAM_LOOKUP; 7403859Sml29623 if (cfg.use_ip_daddr) 7413859Sml29623 ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR; 7423859Sml29623 *class_config = ccfg; 7433859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 7446929Smisaki " ==> nxge_cfg_tcam_ip_class %x", ccfg)); 7453859Sml29623 return (NXGE_OK); 7463859Sml29623 } 7473859Sml29623 7483859Sml29623 static nxge_status_t 7493859Sml29623 nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class, 7503859Sml29623 uint32_t class_config) 7513859Sml29623 { 7523859Sml29623 npi_status_t rs = NPI_SUCCESS; 7533859Sml29623 tcam_key_cfg_t cfg; 7543859Sml29623 npi_handle_t handle; 7553859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 7563859Sml29623 7573859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 7583859Sml29623 7593859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 7603859Sml29623 p_class_cfgp->class_cfg[class] = class_config; 7613859Sml29623 7623859Sml29623 bzero(&cfg, sizeof (tcam_key_cfg_t)); 7633859Sml29623 handle = nxgep->npi_reg_handle; 7643859Sml29623 cfg.discard = 0; 7653859Sml29623 cfg.lookup_enable = 0; 7663859Sml29623 cfg.use_ip_daddr = 0; 7673859Sml29623 if (class_config & NXGE_CLASS_DISCARD) 7683859Sml29623 cfg.discard = 1; 7693859Sml29623 if (class_config & NXGE_CLASS_TCAM_LOOKUP) 7703859Sml29623 cfg.lookup_enable = 1; 7713859Sml29623 if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR) 7723859Sml29623 cfg.use_ip_daddr = 1; 7733859Sml29623 7743859Sml29623 rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg); 7753859Sml29623 if (rs & NPI_FFLP_ERROR) { 7763859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 7776929Smisaki " opt %x for class %d failed ", class_config, class)); 7783859Sml29623 return (NXGE_ERROR | rs); 7793859Sml29623 } 7803859Sml29623 return (NXGE_OK); 7813859Sml29623 } 7823859Sml29623 7833859Sml29623 nxge_status_t 7843859Sml29623 nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1) 7853859Sml29623 { 7863859Sml29623 npi_status_t rs = NPI_SUCCESS; 7873859Sml29623 npi_handle_t handle; 7883859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 7893859Sml29623 7903859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1")); 7913859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 7923859Sml29623 p_class_cfgp->init_h1 = h1; 7933859Sml29623 handle = nxgep->npi_reg_handle; 7943859Sml29623 rs = npi_fflp_cfg_hash_h1poly(handle, h1); 7953859Sml29623 if (rs & NPI_FFLP_ERROR) { 7963859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 7976929Smisaki " nxge_fflp_init_h1 %x failed ", h1)); 7983859Sml29623 return (NXGE_ERROR | rs); 7993859Sml29623 } 8003859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1")); 8013859Sml29623 return (NXGE_OK); 8023859Sml29623 } 8033859Sml29623 8043859Sml29623 nxge_status_t 8053859Sml29623 nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2) 8063859Sml29623 { 8073859Sml29623 npi_status_t rs = NPI_SUCCESS; 8083859Sml29623 npi_handle_t handle; 8093859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 8103859Sml29623 8113859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2")); 8123859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 8133859Sml29623 p_class_cfgp->init_h2 = h2; 8143859Sml29623 8153859Sml29623 handle = nxgep->npi_reg_handle; 8163859Sml29623 rs = npi_fflp_cfg_hash_h2poly(handle, h2); 8173859Sml29623 if (rs & NPI_FFLP_ERROR) { 8183859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8196929Smisaki " nxge_fflp_init_h2 %x failed ", h2)); 8203859Sml29623 return (NXGE_ERROR | rs); 8213859Sml29623 } 8223859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2")); 8233859Sml29623 return (NXGE_OK); 8243859Sml29623 } 8253859Sml29623 8263859Sml29623 nxge_status_t 8273859Sml29623 nxge_classify_init_sw(p_nxge_t nxgep) 8283859Sml29623 { 8293859Sml29623 nxge_classify_t *classify_ptr; 8303859Sml29623 8313859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw")); 8323859Sml29623 classify_ptr = &nxgep->classifier; 8333859Sml29623 8343859Sml29623 if (classify_ptr->state & NXGE_FFLP_SW_INIT) { 8353859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 8366929Smisaki "nxge_classify_init_sw already init")); 8373859Sml29623 return (NXGE_OK); 8383859Sml29623 } 839*11304SJanie.Lu@Sun.COM 840*11304SJanie.Lu@Sun.COM classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports; 841*11304SJanie.Lu@Sun.COM classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam; 842*11304SJanie.Lu@Sun.COM classify_ptr->tcam_top = nxgep->function_num; 8433859Sml29623 8443859Sml29623 /* Init defaults */ 8453859Sml29623 /* 8463859Sml29623 * add hacks required for HW shortcomings for example, code to handle 8473859Sml29623 * fragmented packets 8483859Sml29623 */ 8493859Sml29623 nxge_init_h1_table(); 8503859Sml29623 nxge_crc_ccitt_init(); 8513859Sml29623 nxgep->classifier.tcam_location = nxgep->function_num; 8523859Sml29623 nxgep->classifier.fragment_bug = 1; 8533859Sml29623 classify_ptr->state |= NXGE_FFLP_SW_INIT; 8543859Sml29623 8553859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw")); 8563859Sml29623 return (NXGE_OK); 8573859Sml29623 } 8583859Sml29623 8593859Sml29623 nxge_status_t 8603859Sml29623 nxge_classify_exit_sw(p_nxge_t nxgep) 8613859Sml29623 { 8623859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw")); 8633859Sml29623 nxgep->classifier.state = NULL; 8643859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw")); 8653859Sml29623 return (NXGE_OK); 8663859Sml29623 } 8673859Sml29623 8683859Sml29623 /* 8693859Sml29623 * Figures out the RDC Group for the entry 8703859Sml29623 * 8713859Sml29623 * The current implementation is just a place holder and it 8723859Sml29623 * returns 0. 8733859Sml29623 * The real location determining algorithm would consider 8743859Sml29623 * the partition etc ... before deciding w 8753859Sml29623 * 8763859Sml29623 */ 8773859Sml29623 8783859Sml29623 /* ARGSUSED */ 8793859Sml29623 static uint8_t 880*11304SJanie.Lu@Sun.COM nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie) 8813859Sml29623 { 8823859Sml29623 int use_port_rdc_grp = 0; 8833859Sml29623 uint8_t rdc_grp = 0; 8843859Sml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp; 8853859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp; 8863859Sml29623 p_nxge_rdc_grp_t rdc_grp_p; 8873859Sml29623 8883859Sml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 8893859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 8903859Sml29623 rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp]; 8916495Sspeer rdc_grp = p_cfgp->def_mac_rxdma_grpid; 8923859Sml29623 8933859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8946929Smisaki "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n", 8956929Smisaki cookie, rdc_grp, rdc_grp_p)); 8963859Sml29623 return (rdc_grp); 8973859Sml29623 } 8983859Sml29623 8993859Sml29623 /* ARGSUSED */ 9003859Sml29623 static uint8_t 901*11304SJanie.Lu@Sun.COM nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie) 9023859Sml29623 { 9033859Sml29623 return ((uint8_t)cookie); 9043859Sml29623 } 9053859Sml29623 9063859Sml29623 /* ARGSUSED */ 9073859Sml29623 static void 9083859Sml29623 nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec, 9093859Sml29623 tcam_entry_t *tcam_ptr) 9103859Sml29623 { 9113859Sml29623 udpip4_spec_t *fspec_key; 9123859Sml29623 udpip4_spec_t *fspec_mask; 9133859Sml29623 9143859Sml29623 fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec; 9153859Sml29623 fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec; 9163859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 9173859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 9183859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 9193859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 9203859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 9216929Smisaki fspec_key->pdst, fspec_key->psrc); 9223859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 9236929Smisaki fspec_mask->pdst, fspec_mask->psrc); 9243859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 9256929Smisaki tcam_ptr->ip4_class_mask, 9266929Smisaki TCAM_CLASS_UDP_IPV4); 9273859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 9286929Smisaki tcam_ptr->ip4_proto_mask, 9296929Smisaki IPPROTO_UDP); 930*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos; 931*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos; 9323859Sml29623 } 9333859Sml29623 9343859Sml29623 static void 9353859Sml29623 nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 9363859Sml29623 tcam_entry_t *tcam_ptr) 9373859Sml29623 { 9383859Sml29623 udpip6_spec_t *fspec_key; 9393859Sml29623 udpip6_spec_t *fspec_mask; 9403859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 9413859Sml29623 9423859Sml29623 fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec; 9433859Sml29623 fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec; 9443859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 9453859Sml29623 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 9466929Smisaki NXGE_CLASS_TCAM_USE_SRC_ADDR) { 9473859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 9483859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 9493859Sml29623 } else { 9503859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 9513859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 9523859Sml29623 } 9533859Sml29623 9543859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 9556929Smisaki tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6); 9563859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 9576929Smisaki tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP); 9583859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 9596929Smisaki fspec_key->pdst, fspec_key->psrc); 9603859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 9616929Smisaki fspec_mask->pdst, fspec_mask->psrc); 962*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_key = fspec_key->tos; 963*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_mask = fspec_mask->tos; 9643859Sml29623 } 9653859Sml29623 9663859Sml29623 /* ARGSUSED */ 9673859Sml29623 static void 9683859Sml29623 nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec, 9693859Sml29623 tcam_entry_t *tcam_ptr) 9703859Sml29623 { 9713859Sml29623 tcpip4_spec_t *fspec_key; 9723859Sml29623 tcpip4_spec_t *fspec_mask; 9733859Sml29623 9743859Sml29623 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 9753859Sml29623 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 9763859Sml29623 9773859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 9783859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 9793859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 9803859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 9813859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 9826929Smisaki fspec_key->pdst, fspec_key->psrc); 9833859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 9846929Smisaki fspec_mask->pdst, fspec_mask->psrc); 9853859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 9866929Smisaki tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4); 9873859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 9886929Smisaki tcam_ptr->ip4_proto_mask, IPPROTO_TCP); 989*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos; 990*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos; 9913859Sml29623 } 9923859Sml29623 9933859Sml29623 /* ARGSUSED */ 9943859Sml29623 static void 9953859Sml29623 nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec, 9963859Sml29623 tcam_entry_t *tcam_ptr) 9973859Sml29623 { 9983859Sml29623 tcpip4_spec_t *fspec_key; 9993859Sml29623 tcpip4_spec_t *fspec_mask; 10003859Sml29623 10013859Sml29623 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 10023859Sml29623 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 10033859Sml29623 10043859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 10053859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 10063859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 10073859Sml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 10083859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 10096929Smisaki tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4); 10103859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 10116929Smisaki tcam_ptr->ip4_proto_mask, IPPROTO_SCTP); 10123859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 10136929Smisaki fspec_key->pdst, fspec_key->psrc); 10143859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 10156929Smisaki fspec_mask->pdst, fspec_mask->psrc); 1016*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos; 1017*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos; 10183859Sml29623 } 10193859Sml29623 10203859Sml29623 static void 10213859Sml29623 nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 10223859Sml29623 tcam_entry_t *tcam_ptr) 10233859Sml29623 { 10243859Sml29623 tcpip6_spec_t *fspec_key; 10253859Sml29623 tcpip6_spec_t *fspec_mask; 10263859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 10273859Sml29623 10283859Sml29623 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 10293859Sml29623 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 10303859Sml29623 10313859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 10323859Sml29623 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 10336929Smisaki NXGE_CLASS_TCAM_USE_SRC_ADDR) { 10343859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 10353859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 10363859Sml29623 } else { 10373859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 10383859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 10393859Sml29623 } 10403859Sml29623 10413859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 10426929Smisaki tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6); 10433859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 10446929Smisaki tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP); 10453859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 10466929Smisaki fspec_key->pdst, fspec_key->psrc); 10473859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 10486929Smisaki fspec_mask->pdst, fspec_mask->psrc); 1049*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_key = fspec_key->tos; 1050*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_mask = fspec_mask->tos; 10513859Sml29623 } 10523859Sml29623 10533859Sml29623 static void 10543859Sml29623 nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 10553859Sml29623 tcam_entry_t *tcam_ptr) 10563859Sml29623 { 10573859Sml29623 tcpip6_spec_t *fspec_key; 10583859Sml29623 tcpip6_spec_t *fspec_mask; 10593859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 10603859Sml29623 10613859Sml29623 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 10623859Sml29623 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 10633859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 10643859Sml29623 10653859Sml29623 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 10666929Smisaki NXGE_CLASS_TCAM_USE_SRC_ADDR) { 10673859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 10683859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 10693859Sml29623 } else { 10703859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 10713859Sml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 10723859Sml29623 } 10733859Sml29623 10743859Sml29623 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 10756929Smisaki tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6); 10763859Sml29623 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 10776929Smisaki tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP); 10783859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 10796929Smisaki fspec_key->pdst, fspec_key->psrc); 10803859Sml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 10816929Smisaki fspec_mask->pdst, fspec_mask->psrc); 1082*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_key = fspec_key->tos; 1083*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_mask = fspec_mask->tos; 10843859Sml29623 } 10853859Sml29623 1086*11304SJanie.Lu@Sun.COM /* ARGSUSED */ 1087*11304SJanie.Lu@Sun.COM static void 1088*11304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec, 1089*11304SJanie.Lu@Sun.COM tcam_entry_t *tcam_ptr) 1090*11304SJanie.Lu@Sun.COM { 1091*11304SJanie.Lu@Sun.COM ahip4_spec_t *fspec_key; 1092*11304SJanie.Lu@Sun.COM ahip4_spec_t *fspec_mask; 1093*11304SJanie.Lu@Sun.COM 1094*11304SJanie.Lu@Sun.COM fspec_key = (ahip4_spec_t *)&flow_spec->uh.ahip4spec; 1095*11304SJanie.Lu@Sun.COM fspec_mask = (ahip4_spec_t *)&flow_spec->um.ahip4spec; 1096*11304SJanie.Lu@Sun.COM 1097*11304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1098*11304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1099*11304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1100*11304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1101*11304SJanie.Lu@Sun.COM 1102*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_port_key = fspec_key->spi; 1103*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_port_mask = fspec_mask->spi; 1104*11304SJanie.Lu@Sun.COM 1105*11304SJanie.Lu@Sun.COM TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1106*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_class_mask, 1107*11304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV4); 1108*11304SJanie.Lu@Sun.COM 1109*11304SJanie.Lu@Sun.COM if (flow_spec->flow_type == FSPEC_AHIP4) { 1110*11304SJanie.Lu@Sun.COM TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1111*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_proto_mask, IPPROTO_AH); 1112*11304SJanie.Lu@Sun.COM } else { 1113*11304SJanie.Lu@Sun.COM TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1114*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_proto_mask, IPPROTO_ESP); 1115*11304SJanie.Lu@Sun.COM } 1116*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos; 1117*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos; 1118*11304SJanie.Lu@Sun.COM } 1119*11304SJanie.Lu@Sun.COM 1120*11304SJanie.Lu@Sun.COM static void 1121*11304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1122*11304SJanie.Lu@Sun.COM tcam_entry_t *tcam_ptr) 1123*11304SJanie.Lu@Sun.COM { 1124*11304SJanie.Lu@Sun.COM ahip6_spec_t *fspec_key; 1125*11304SJanie.Lu@Sun.COM ahip6_spec_t *fspec_mask; 1126*11304SJanie.Lu@Sun.COM p_nxge_class_pt_cfg_t p_class_cfgp; 1127*11304SJanie.Lu@Sun.COM 1128*11304SJanie.Lu@Sun.COM fspec_key = (ahip6_spec_t *)&flow_spec->uh.ahip6spec; 1129*11304SJanie.Lu@Sun.COM fspec_mask = (ahip6_spec_t *)&flow_spec->um.ahip6spec; 1130*11304SJanie.Lu@Sun.COM 1131*11304SJanie.Lu@Sun.COM p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1132*11304SJanie.Lu@Sun.COM if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] & 1133*11304SJanie.Lu@Sun.COM NXGE_CLASS_TCAM_USE_SRC_ADDR) { 1134*11304SJanie.Lu@Sun.COM TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 1135*11304SJanie.Lu@Sun.COM TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 1136*11304SJanie.Lu@Sun.COM } else { 1137*11304SJanie.Lu@Sun.COM TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 1138*11304SJanie.Lu@Sun.COM TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 1139*11304SJanie.Lu@Sun.COM } 1140*11304SJanie.Lu@Sun.COM 1141*11304SJanie.Lu@Sun.COM TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1142*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6); 1143*11304SJanie.Lu@Sun.COM 1144*11304SJanie.Lu@Sun.COM if (flow_spec->flow_type == FSPEC_AHIP6) { 1145*11304SJanie.Lu@Sun.COM TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1146*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH); 1147*11304SJanie.Lu@Sun.COM } else { 1148*11304SJanie.Lu@Sun.COM TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1149*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP); 1150*11304SJanie.Lu@Sun.COM } 1151*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_port_key = fspec_key->spi; 1152*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_port_mask = fspec_mask->spi; 1153*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_key = fspec_key->tos; 1154*11304SJanie.Lu@Sun.COM tcam_ptr->ip6_tos_mask = fspec_mask->tos; 1155*11304SJanie.Lu@Sun.COM } 1156*11304SJanie.Lu@Sun.COM 1157*11304SJanie.Lu@Sun.COM /* ARGSUSED */ 1158*11304SJanie.Lu@Sun.COM static void 1159*11304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec, 1160*11304SJanie.Lu@Sun.COM tcam_entry_t *tcam_ptr, tcam_class_t class) 1161*11304SJanie.Lu@Sun.COM { 1162*11304SJanie.Lu@Sun.COM ip_user_spec_t *fspec_key; 1163*11304SJanie.Lu@Sun.COM ip_user_spec_t *fspec_mask; 1164*11304SJanie.Lu@Sun.COM 1165*11304SJanie.Lu@Sun.COM fspec_key = (ip_user_spec_t *)&flow_spec->uh.ip_usr_spec; 1166*11304SJanie.Lu@Sun.COM fspec_mask = (ip_user_spec_t *)&flow_spec->um.ip_usr_spec; 1167*11304SJanie.Lu@Sun.COM 1168*11304SJanie.Lu@Sun.COM if (fspec_key->ip_ver == FSPEC_IP4) { 1169*11304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1170*11304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1171*11304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1172*11304SJanie.Lu@Sun.COM TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1173*11304SJanie.Lu@Sun.COM 1174*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_port_key = fspec_key->l4_4_bytes; 1175*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_port_mask = fspec_mask->l4_4_bytes; 1176*11304SJanie.Lu@Sun.COM 1177*11304SJanie.Lu@Sun.COM TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1178*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_class_mask, class); 1179*11304SJanie.Lu@Sun.COM 1180*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_proto_key = fspec_key->proto; 1181*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_proto_mask = fspec_mask->proto; 1182*11304SJanie.Lu@Sun.COM 1183*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_key = fspec_key->tos; 1184*11304SJanie.Lu@Sun.COM tcam_ptr->ip4_tos_mask = fspec_mask->tos; 1185*11304SJanie.Lu@Sun.COM } 1186*11304SJanie.Lu@Sun.COM } 1187*11304SJanie.Lu@Sun.COM 1188*11304SJanie.Lu@Sun.COM 11893859Sml29623 nxge_status_t 11903859Sml29623 nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res, 11913859Sml29623 uint32_t *H1, uint16_t *H2) 11923859Sml29623 { 11933859Sml29623 flow_spec_t *flow_spec; 11943859Sml29623 uint32_t class_cfg; 11953859Sml29623 flow_template_t ft; 11963859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 11973859Sml29623 11983859Sml29623 int ft_size = sizeof (flow_template_t); 11993859Sml29623 12003859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash")); 12013859Sml29623 12023859Sml29623 flow_spec = (flow_spec_t *)&flow_res->flow_spec; 12033859Sml29623 bzero((char *)&ft, ft_size); 12043859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 12053859Sml29623 12063859Sml29623 switch (flow_spec->flow_type) { 12073859Sml29623 case FSPEC_TCPIP4: 12083859Sml29623 class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4]; 12093859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 12103859Sml29623 ft.ip_proto = IPPROTO_TCP; 12113859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 12123859Sml29623 ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src; 12133859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 12143859Sml29623 ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst; 12153859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 12163859Sml29623 ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc; 12173859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 12183859Sml29623 ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst; 12193859Sml29623 break; 12203859Sml29623 12213859Sml29623 case FSPEC_UDPIP4: 12223859Sml29623 class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4]; 12233859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 12243859Sml29623 ft.ip_proto = IPPROTO_UDP; 12253859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 12263859Sml29623 ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src; 12273859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 12283859Sml29623 ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst; 12293859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 12303859Sml29623 ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc; 12313859Sml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 12323859Sml29623 ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst; 12333859Sml29623 break; 12343859Sml29623 12353859Sml29623 default: 12363859Sml29623 return (NXGE_ERROR); 12373859Sml29623 } 12383859Sml29623 12393859Sml29623 *H1 = nxge_compute_h1(p_class_cfgp->init_h1, 12406929Smisaki (uint32_t *)&ft, ft_size) & 0xfffff; 12413859Sml29623 *H2 = nxge_compute_h2(p_class_cfgp->init_h2, 12426929Smisaki (uint8_t *)&ft, ft_size); 12433859Sml29623 12443859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash")); 12453859Sml29623 return (NXGE_OK); 12463859Sml29623 } 12473859Sml29623 12483859Sml29623 nxge_status_t 12493859Sml29623 nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 12503859Sml29623 { 12513859Sml29623 uint32_t H1; 12523859Sml29623 uint16_t H2; 12533859Sml29623 nxge_status_t status = NXGE_OK; 12543859Sml29623 12553859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry")); 12563859Sml29623 status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2); 12573859Sml29623 if (status != NXGE_OK) { 12583859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 12596929Smisaki " nxge_add_fcram_entry failed ")); 12603859Sml29623 return (status); 12613859Sml29623 } 12623859Sml29623 12633859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry")); 12643859Sml29623 return (NXGE_OK); 12653859Sml29623 } 12663859Sml29623 12673859Sml29623 /* 12683859Sml29623 * Already decided this flow goes into the tcam 12693859Sml29623 */ 12703859Sml29623 12713859Sml29623 nxge_status_t 12723859Sml29623 nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 12733859Sml29623 { 12743859Sml29623 npi_handle_t handle; 1275*11304SJanie.Lu@Sun.COM uint64_t channel_cookie; 1276*11304SJanie.Lu@Sun.COM uint64_t flow_cookie; 12773859Sml29623 flow_spec_t *flow_spec; 12783859Sml29623 npi_status_t rs = NPI_SUCCESS; 12793859Sml29623 tcam_entry_t tcam_ptr; 1280*11304SJanie.Lu@Sun.COM tcam_location_t location; 12813859Sml29623 uint8_t offset, rdc_grp; 12823859Sml29623 p_nxge_hw_list_t hw_p; 1283*11304SJanie.Lu@Sun.COM uint64_t class; 12843859Sml29623 12853859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry")); 12863859Sml29623 handle = nxgep->npi_reg_handle; 12873859Sml29623 12883859Sml29623 bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 12893859Sml29623 flow_spec = (flow_spec_t *)&flow_res->flow_spec; 12903859Sml29623 flow_cookie = flow_res->flow_cookie; 12913859Sml29623 channel_cookie = flow_res->channel_cookie; 1292*11304SJanie.Lu@Sun.COM location = (tcam_location_t)nxge_tcam_get_index(nxgep, 1293*11304SJanie.Lu@Sun.COM (uint16_t)flow_res->location); 1294*11304SJanie.Lu@Sun.COM 1295*11304SJanie.Lu@Sun.COM if ((hw_p = nxgep->nxge_hw_p) == NULL) { 1296*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1297*11304SJanie.Lu@Sun.COM " nxge_add_tcam_entry: common hardware not set", 1298*11304SJanie.Lu@Sun.COM nxgep->niu_type)); 1299*11304SJanie.Lu@Sun.COM return (NXGE_ERROR); 1300*11304SJanie.Lu@Sun.COM } 1301*11304SJanie.Lu@Sun.COM 1302*11304SJanie.Lu@Sun.COM if (flow_spec->flow_type == FSPEC_IP_USR) { 1303*11304SJanie.Lu@Sun.COM int i; 1304*11304SJanie.Lu@Sun.COM int add_usr_cls = 0; 1305*11304SJanie.Lu@Sun.COM int ipv6 = 0; 1306*11304SJanie.Lu@Sun.COM ip_user_spec_t *uspec = &flow_spec->uh.ip_usr_spec; 1307*11304SJanie.Lu@Sun.COM ip_user_spec_t *umask = &flow_spec->um.ip_usr_spec; 1308*11304SJanie.Lu@Sun.COM nxge_usr_l3_cls_t *l3_ucls_p; 1309*11304SJanie.Lu@Sun.COM 1310*11304SJanie.Lu@Sun.COM MUTEX_ENTER(&hw_p->nxge_tcam_lock); 1311*11304SJanie.Lu@Sun.COM 1312*11304SJanie.Lu@Sun.COM for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 1313*11304SJanie.Lu@Sun.COM l3_ucls_p = &hw_p->tcam_l3_prog_cls[i]; 1314*11304SJanie.Lu@Sun.COM if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) { 1315*11304SJanie.Lu@Sun.COM if (uspec->proto == l3_ucls_p->pid) { 1316*11304SJanie.Lu@Sun.COM class = l3_ucls_p->cls; 1317*11304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt++; 1318*11304SJanie.Lu@Sun.COM add_usr_cls = 1; 1319*11304SJanie.Lu@Sun.COM break; 1320*11304SJanie.Lu@Sun.COM } 1321*11304SJanie.Lu@Sun.COM } else if (l3_ucls_p->valid == 0) { 1322*11304SJanie.Lu@Sun.COM /* Program new user IP class */ 1323*11304SJanie.Lu@Sun.COM switch (i) { 1324*11304SJanie.Lu@Sun.COM case 0: 1325*11304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_4; 1326*11304SJanie.Lu@Sun.COM break; 1327*11304SJanie.Lu@Sun.COM case 1: 1328*11304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_5; 1329*11304SJanie.Lu@Sun.COM break; 1330*11304SJanie.Lu@Sun.COM case 2: 1331*11304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_6; 1332*11304SJanie.Lu@Sun.COM break; 1333*11304SJanie.Lu@Sun.COM case 3: 1334*11304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_7; 1335*11304SJanie.Lu@Sun.COM break; 1336*11304SJanie.Lu@Sun.COM default: 1337*11304SJanie.Lu@Sun.COM break; 1338*11304SJanie.Lu@Sun.COM } 1339*11304SJanie.Lu@Sun.COM if (uspec->ip_ver == FSPEC_IP6) 1340*11304SJanie.Lu@Sun.COM ipv6 = 1; 1341*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set(handle, 1342*11304SJanie.Lu@Sun.COM (tcam_class_t)class, uspec->tos, 1343*11304SJanie.Lu@Sun.COM umask->tos, uspec->proto, ipv6); 1344*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 1345*11304SJanie.Lu@Sun.COM goto fail; 1346*11304SJanie.Lu@Sun.COM 1347*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 1348*11304SJanie.Lu@Sun.COM (tcam_class_t)class); 1349*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 1350*11304SJanie.Lu@Sun.COM goto fail; 1351*11304SJanie.Lu@Sun.COM 1352*11304SJanie.Lu@Sun.COM l3_ucls_p->cls = class; 1353*11304SJanie.Lu@Sun.COM l3_ucls_p->pid = uspec->proto; 1354*11304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt++; 1355*11304SJanie.Lu@Sun.COM l3_ucls_p->valid = 1; 1356*11304SJanie.Lu@Sun.COM add_usr_cls = 1; 1357*11304SJanie.Lu@Sun.COM break; 1358*11304SJanie.Lu@Sun.COM } else if (l3_ucls_p->tcam_ref_cnt == 0 && 1359*11304SJanie.Lu@Sun.COM uspec->proto == l3_ucls_p->pid) { 1360*11304SJanie.Lu@Sun.COM /* 1361*11304SJanie.Lu@Sun.COM * The class has already been programmed, 1362*11304SJanie.Lu@Sun.COM * probably for flow hash 1363*11304SJanie.Lu@Sun.COM */ 1364*11304SJanie.Lu@Sun.COM class = l3_ucls_p->cls; 1365*11304SJanie.Lu@Sun.COM if (uspec->ip_ver == FSPEC_IP6) 1366*11304SJanie.Lu@Sun.COM ipv6 = 1; 1367*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set(handle, 1368*11304SJanie.Lu@Sun.COM (tcam_class_t)class, uspec->tos, 1369*11304SJanie.Lu@Sun.COM umask->tos, uspec->proto, ipv6); 1370*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 1371*11304SJanie.Lu@Sun.COM goto fail; 1372*11304SJanie.Lu@Sun.COM 1373*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 1374*11304SJanie.Lu@Sun.COM (tcam_class_t)class); 1375*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 1376*11304SJanie.Lu@Sun.COM goto fail; 1377*11304SJanie.Lu@Sun.COM 1378*11304SJanie.Lu@Sun.COM l3_ucls_p->pid = uspec->proto; 1379*11304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt++; 1380*11304SJanie.Lu@Sun.COM add_usr_cls = 1; 1381*11304SJanie.Lu@Sun.COM break; 1382*11304SJanie.Lu@Sun.COM } 1383*11304SJanie.Lu@Sun.COM } 1384*11304SJanie.Lu@Sun.COM if (!add_usr_cls) { 1385*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1386*11304SJanie.Lu@Sun.COM "nxge_add_tcam_entry: Could not find/insert class" 1387*11304SJanie.Lu@Sun.COM "for pid %d", uspec->proto)); 1388*11304SJanie.Lu@Sun.COM goto fail; 1389*11304SJanie.Lu@Sun.COM } 1390*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1391*11304SJanie.Lu@Sun.COM } 13923859Sml29623 13933859Sml29623 switch (flow_spec->flow_type) { 13943859Sml29623 case FSPEC_TCPIP4: 13953859Sml29623 nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr); 13963859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4, 13976929Smisaki flow_cookie); 13983859Sml29623 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4, 13996929Smisaki channel_cookie); 14003859Sml29623 break; 14013859Sml29623 14023859Sml29623 case FSPEC_UDPIP4: 14033859Sml29623 nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr); 14043859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep, 14056929Smisaki TCAM_CLASS_UDP_IPV4, 14066929Smisaki flow_cookie); 14073859Sml29623 offset = nxge_get_rdc_offset(nxgep, 14086929Smisaki TCAM_CLASS_UDP_IPV4, 14096929Smisaki channel_cookie); 14103859Sml29623 break; 14113859Sml29623 14123859Sml29623 case FSPEC_TCPIP6: 14133859Sml29623 nxge_fill_tcam_entry_tcp_ipv6(nxgep, 14146929Smisaki flow_spec, &tcam_ptr); 14153859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6, 14166929Smisaki flow_cookie); 14173859Sml29623 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6, 14186929Smisaki channel_cookie); 14193859Sml29623 break; 14203859Sml29623 14213859Sml29623 case FSPEC_UDPIP6: 14223859Sml29623 nxge_fill_tcam_entry_udp_ipv6(nxgep, 14236929Smisaki flow_spec, &tcam_ptr); 14243859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep, 14256929Smisaki TCAM_CLASS_UDP_IPV6, 1426*11304SJanie.Lu@Sun.COM flow_cookie); 14273859Sml29623 offset = nxge_get_rdc_offset(nxgep, 14286929Smisaki TCAM_CLASS_UDP_IPV6, 1429*11304SJanie.Lu@Sun.COM channel_cookie); 14303859Sml29623 break; 14313859Sml29623 14323859Sml29623 case FSPEC_SCTPIP4: 14333859Sml29623 nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr); 14343859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep, 14356929Smisaki TCAM_CLASS_SCTP_IPV4, 1436*11304SJanie.Lu@Sun.COM flow_cookie); 14373859Sml29623 offset = nxge_get_rdc_offset(nxgep, 14386929Smisaki TCAM_CLASS_SCTP_IPV4, 1439*11304SJanie.Lu@Sun.COM channel_cookie); 14403859Sml29623 break; 14413859Sml29623 14423859Sml29623 case FSPEC_SCTPIP6: 14433859Sml29623 nxge_fill_tcam_entry_sctp_ipv6(nxgep, 14446929Smisaki flow_spec, &tcam_ptr); 14453859Sml29623 rdc_grp = nxge_get_rdc_group(nxgep, 14466929Smisaki TCAM_CLASS_SCTP_IPV6, 1447*11304SJanie.Lu@Sun.COM flow_cookie); 1448*11304SJanie.Lu@Sun.COM offset = nxge_get_rdc_offset(nxgep, 1449*11304SJanie.Lu@Sun.COM TCAM_CLASS_SCTP_IPV6, 14506929Smisaki channel_cookie); 1451*11304SJanie.Lu@Sun.COM break; 1452*11304SJanie.Lu@Sun.COM 1453*11304SJanie.Lu@Sun.COM case FSPEC_AHIP4: 1454*11304SJanie.Lu@Sun.COM case FSPEC_ESPIP4: 1455*11304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp(nxgep, flow_spec, &tcam_ptr); 1456*11304SJanie.Lu@Sun.COM rdc_grp = nxge_get_rdc_group(nxgep, 1457*11304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV4, 1458*11304SJanie.Lu@Sun.COM flow_cookie); 14593859Sml29623 offset = nxge_get_rdc_offset(nxgep, 1460*11304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV4, 1461*11304SJanie.Lu@Sun.COM channel_cookie); 14623859Sml29623 break; 14633859Sml29623 1464*11304SJanie.Lu@Sun.COM case FSPEC_AHIP6: 1465*11304SJanie.Lu@Sun.COM case FSPEC_ESPIP6: 1466*11304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ah_esp_ipv6(nxgep, 1467*11304SJanie.Lu@Sun.COM flow_spec, &tcam_ptr); 1468*11304SJanie.Lu@Sun.COM rdc_grp = nxge_get_rdc_group(nxgep, 1469*11304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV6, 1470*11304SJanie.Lu@Sun.COM flow_cookie); 1471*11304SJanie.Lu@Sun.COM offset = nxge_get_rdc_offset(nxgep, 1472*11304SJanie.Lu@Sun.COM TCAM_CLASS_AH_ESP_IPV6, 1473*11304SJanie.Lu@Sun.COM channel_cookie); 1474*11304SJanie.Lu@Sun.COM break; 1475*11304SJanie.Lu@Sun.COM 1476*11304SJanie.Lu@Sun.COM case FSPEC_IP_USR: 1477*11304SJanie.Lu@Sun.COM nxge_fill_tcam_entry_ip_usr(nxgep, flow_spec, &tcam_ptr, 1478*11304SJanie.Lu@Sun.COM (tcam_class_t)class); 1479*11304SJanie.Lu@Sun.COM rdc_grp = nxge_get_rdc_group(nxgep, 1480*11304SJanie.Lu@Sun.COM (tcam_class_t)class, flow_cookie); 1481*11304SJanie.Lu@Sun.COM offset = nxge_get_rdc_offset(nxgep, 1482*11304SJanie.Lu@Sun.COM (tcam_class_t)class, channel_cookie); 1483*11304SJanie.Lu@Sun.COM break; 14843859Sml29623 default: 1485*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1486*11304SJanie.Lu@Sun.COM "nxge_add_tcam_entry: Unknown flow spec 0x%x", 1487*11304SJanie.Lu@Sun.COM flow_spec->flow_type)); 1488*11304SJanie.Lu@Sun.COM return (NXGE_ERROR); 14893859Sml29623 } 14903859Sml29623 14913859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 14926929Smisaki " nxge_add_tcam_entry write" 14936929Smisaki " for location %d offset %d", location, offset)); 14943859Sml29623 14953859Sml29623 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 14963859Sml29623 rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr); 14973859Sml29623 14983859Sml29623 if (rs & NPI_FFLP_ERROR) { 14993859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 15006929Smisaki " nxge_add_tcam_entry write" 15016929Smisaki " failed for location %d", location)); 1502*11304SJanie.Lu@Sun.COM goto fail; 15033859Sml29623 } 15043859Sml29623 15053859Sml29623 tcam_ptr.match_action.value = 0; 15063859Sml29623 tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp; 15073859Sml29623 tcam_ptr.match_action.bits.ldw.offset = offset; 15083859Sml29623 tcam_ptr.match_action.bits.ldw.tres = 15096929Smisaki TRES_TERM_OVRD_L2RDC; 1510*11304SJanie.Lu@Sun.COM if (channel_cookie == NXGE_PKT_DISCARD) 15113859Sml29623 tcam_ptr.match_action.bits.ldw.disc = 1; 15123859Sml29623 rs = npi_fflp_tcam_asc_ram_entry_write(handle, 15136929Smisaki location, tcam_ptr.match_action.value); 15143859Sml29623 if (rs & NPI_FFLP_ERROR) { 15153859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 15166929Smisaki " nxge_add_tcam_entry write" 15176929Smisaki " failed for ASC RAM location %d", location)); 1518*11304SJanie.Lu@Sun.COM goto fail; 15193859Sml29623 } 15203859Sml29623 bcopy((void *) &tcam_ptr, 15216929Smisaki (void *) &nxgep->classifier.tcam_entries[location].tce, 15226929Smisaki sizeof (tcam_entry_t)); 1523*11304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt++; 1524*11304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entries[location].valid = 1; 15253859Sml29623 15263859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 15273859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry")); 15283859Sml29623 return (NXGE_OK); 1529*11304SJanie.Lu@Sun.COM fail: 1530*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1531*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_tcam_entry FAILED")); 1532*11304SJanie.Lu@Sun.COM return (NXGE_ERROR); 15333859Sml29623 } 15343859Sml29623 15353859Sml29623 static nxge_status_t 15363859Sml29623 nxge_tcam_handle_ip_fragment(p_nxge_t nxgep) 15373859Sml29623 { 15383859Sml29623 tcam_entry_t tcam_ptr; 15393859Sml29623 tcam_location_t location; 15403859Sml29623 uint8_t class; 15413859Sml29623 uint32_t class_config; 15423859Sml29623 npi_handle_t handle; 15433859Sml29623 npi_status_t rs = NPI_SUCCESS; 15443859Sml29623 p_nxge_hw_list_t hw_p; 15453859Sml29623 nxge_status_t status = NXGE_OK; 15463859Sml29623 15473859Sml29623 handle = nxgep->npi_reg_handle; 15483859Sml29623 class = 0; 15493859Sml29623 bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 15503859Sml29623 tcam_ptr.ip4_noport_key = 1; 15513859Sml29623 tcam_ptr.ip4_noport_mask = 1; 15523859Sml29623 location = nxgep->function_num; 15533859Sml29623 nxgep->classifier.fragment_bug_location = location; 15543859Sml29623 15553859Sml29623 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 15563859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 15576929Smisaki " nxge_tcam_handle_ip_fragment: common hardware not set", 15586929Smisaki nxgep->niu_type)); 15593859Sml29623 return (NXGE_ERROR); 15603859Sml29623 } 15613859Sml29623 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 15623859Sml29623 rs = npi_fflp_tcam_entry_write(handle, 15636929Smisaki location, &tcam_ptr); 15643859Sml29623 15653859Sml29623 if (rs & NPI_FFLP_ERROR) { 15663859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 15673859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 15686929Smisaki " nxge_tcam_handle_ip_fragment " 15696929Smisaki " tcam_entry write" 15706929Smisaki " failed for location %d", location)); 15713859Sml29623 return (NXGE_ERROR); 15723859Sml29623 } 15733859Sml29623 tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp; 15743859Sml29623 tcam_ptr.match_action.bits.ldw.offset = 0; /* use the default */ 15753859Sml29623 tcam_ptr.match_action.bits.ldw.tres = 15766929Smisaki TRES_TERM_USE_OFFSET; 15773859Sml29623 rs = npi_fflp_tcam_asc_ram_entry_write(handle, 15786929Smisaki location, tcam_ptr.match_action.value); 15793859Sml29623 15803859Sml29623 if (rs & NPI_FFLP_ERROR) { 15813859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 15823859Sml29623 NXGE_DEBUG_MSG((nxgep, 15836929Smisaki FFLP_CTL, 15846929Smisaki " nxge_tcam_handle_ip_fragment " 15856929Smisaki " tcam_entry write" 15866929Smisaki " failed for ASC RAM location %d", location)); 15873859Sml29623 return (NXGE_ERROR); 15883859Sml29623 } 15893859Sml29623 bcopy((void *) &tcam_ptr, 15906929Smisaki (void *) &nxgep->classifier.tcam_entries[location].tce, 15916929Smisaki sizeof (tcam_entry_t)); 1592*11304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt++; 1593*11304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entries[location].valid = 1; 15943859Sml29623 for (class = TCAM_CLASS_TCP_IPV4; 15956929Smisaki class <= TCAM_CLASS_SCTP_IPV6; class++) { 15963859Sml29623 class_config = nxgep->class_config.class_cfg[class]; 15973859Sml29623 class_config |= NXGE_CLASS_TCAM_LOOKUP; 15983859Sml29623 status = nxge_fflp_ip_class_config(nxgep, class, class_config); 15993859Sml29623 16003859Sml29623 if (status & NPI_FFLP_ERROR) { 16013859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 16023859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16036929Smisaki "nxge_tcam_handle_ip_fragment " 16046929Smisaki "nxge_fflp_ip_class_config failed " 16056929Smisaki " class %d config %x ", class, class_config)); 16063859Sml29623 return (NXGE_ERROR); 16073859Sml29623 } 16083859Sml29623 } 16093859Sml29623 16103859Sml29623 rs = npi_fflp_cfg_tcam_enable(handle); 16113859Sml29623 if (rs & NPI_FFLP_ERROR) { 16123859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 16133859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16146929Smisaki "nxge_tcam_handle_ip_fragment " 16156929Smisaki " nxge_fflp_config_tcam_enable failed")); 16163859Sml29623 return (NXGE_ERROR); 16173859Sml29623 } 16183859Sml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 16193859Sml29623 return (NXGE_OK); 16203859Sml29623 } 16213859Sml29623 16223859Sml29623 /* ARGSUSED */ 16233859Sml29623 static int 16243859Sml29623 nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res) 16253859Sml29623 { 16263859Sml29623 return (0); 16273859Sml29623 } 16283859Sml29623 16293859Sml29623 nxge_status_t 16303859Sml29623 nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res) 16313859Sml29623 { 16323859Sml29623 16333859Sml29623 int insert_hash = 0; 16343859Sml29623 nxge_status_t status = NXGE_OK; 16353859Sml29623 16364977Sraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 16373859Sml29623 /* determine whether to do TCAM or Hash flow */ 16383859Sml29623 insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res); 16393859Sml29623 } 16403859Sml29623 if (insert_hash) { 16413859Sml29623 status = nxge_add_fcram_entry(nxgep, flow_res); 16423859Sml29623 } else { 16433859Sml29623 status = nxge_add_tcam_entry(nxgep, flow_res); 16443859Sml29623 } 16453859Sml29623 return (status); 16463859Sml29623 } 16473859Sml29623 16483859Sml29623 void 16493859Sml29623 nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp) 16503859Sml29623 { 16513859Sml29623 flow_resource_t *fs; 16523859Sml29623 16533859Sml29623 fs = (flow_resource_t *)mp->b_rptr; 16543859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16556929Smisaki "nxge_put_tcam addr fs $%p type %x offset %x", 16566929Smisaki fs, fs->flow_spec.flow_type, fs->channel_cookie)); 16573859Sml29623 (void) nxge_add_tcam_entry(nxgep, fs); 16583859Sml29623 } 16593859Sml29623 16603859Sml29623 nxge_status_t 16613859Sml29623 nxge_fflp_config_tcam_enable(p_nxge_t nxgep) 16623859Sml29623 { 16633859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle; 16643859Sml29623 npi_status_t rs = NPI_SUCCESS; 16653859Sml29623 16663859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable")); 16673859Sml29623 rs = npi_fflp_cfg_tcam_enable(handle); 16683859Sml29623 if (rs & NPI_FFLP_ERROR) { 16693859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16706929Smisaki " nxge_fflp_config_tcam_enable failed")); 16713859Sml29623 return (NXGE_ERROR | rs); 16723859Sml29623 } 16733859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable")); 16743859Sml29623 return (NXGE_OK); 16753859Sml29623 } 16763859Sml29623 16773859Sml29623 nxge_status_t 16783859Sml29623 nxge_fflp_config_tcam_disable(p_nxge_t nxgep) 16793859Sml29623 { 16803859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle; 16813859Sml29623 npi_status_t rs = NPI_SUCCESS; 16823859Sml29623 16833859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 16846929Smisaki " ==> nxge_fflp_config_tcam_disable")); 16853859Sml29623 rs = npi_fflp_cfg_tcam_disable(handle); 16863859Sml29623 if (rs & NPI_FFLP_ERROR) { 16873859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16886929Smisaki " nxge_fflp_config_tcam_disable failed")); 16893859Sml29623 return (NXGE_ERROR | rs); 16903859Sml29623 } 16913859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 16926929Smisaki " <== nxge_fflp_config_tcam_disable")); 16933859Sml29623 return (NXGE_OK); 16943859Sml29623 } 16953859Sml29623 16963859Sml29623 nxge_status_t 16973859Sml29623 nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep) 16983859Sml29623 { 16993859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle; 17003859Sml29623 npi_status_t rs = NPI_SUCCESS; 17013859Sml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp; 17023859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp; 17033859Sml29623 uint8_t partition; 17043859Sml29623 17053859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17066929Smisaki " ==> nxge_fflp_config_hash_lookup_enable")); 17073859Sml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 17083859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 17093859Sml29623 17106495Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 17116495Sspeer if (p_cfgp->grpids[partition]) { 17126495Sspeer rs = npi_fflp_cfg_fcram_partition_enable( 17136929Smisaki handle, partition); 17146495Sspeer if (rs != NPI_SUCCESS) { 17156495Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17166495Sspeer " nxge_fflp_config_hash_lookup_enable" 17176495Sspeer "failed FCRAM partition" 17186495Sspeer " enable for partition %d ", partition)); 17196495Sspeer return (NXGE_ERROR | rs); 17206495Sspeer } 17213859Sml29623 } 17223859Sml29623 } 17233859Sml29623 17243859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17256929Smisaki " <== nxge_fflp_config_hash_lookup_enable")); 17263859Sml29623 return (NXGE_OK); 17273859Sml29623 } 17283859Sml29623 17293859Sml29623 nxge_status_t 17303859Sml29623 nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep) 17313859Sml29623 { 17323859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle; 17333859Sml29623 npi_status_t rs = NPI_SUCCESS; 17343859Sml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp; 17353859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp; 17363859Sml29623 uint8_t partition; 17373859Sml29623 17383859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17396929Smisaki " ==> nxge_fflp_config_hash_lookup_disable")); 17403859Sml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 17413859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 17423859Sml29623 17436495Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 17446495Sspeer if (p_cfgp->grpids[partition]) { 17456495Sspeer rs = npi_fflp_cfg_fcram_partition_disable(handle, 17466495Sspeer partition); 17476495Sspeer if (rs != NPI_SUCCESS) { 17486495Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17496495Sspeer " nxge_fflp_config_hash_lookup_disable" 17506495Sspeer " failed FCRAM partition" 17516495Sspeer " disable for partition %d ", partition)); 17526495Sspeer return (NXGE_ERROR | rs); 17536495Sspeer } 17543859Sml29623 } 17553859Sml29623 } 17563859Sml29623 17573859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17586929Smisaki " <== nxge_fflp_config_hash_lookup_disable")); 17593859Sml29623 return (NXGE_OK); 17603859Sml29623 } 17613859Sml29623 17623859Sml29623 nxge_status_t 17633859Sml29623 nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep) 17643859Sml29623 { 17653859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle; 17663859Sml29623 npi_status_t rs = NPI_SUCCESS; 17673859Sml29623 17683859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17696929Smisaki " ==> nxge_fflp_config_llc_snap_enable")); 17703859Sml29623 rs = npi_fflp_cfg_llcsnap_enable(handle); 17713859Sml29623 if (rs & NPI_FFLP_ERROR) { 17723859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17736929Smisaki " nxge_fflp_config_llc_snap_enable failed")); 17743859Sml29623 return (NXGE_ERROR | rs); 17753859Sml29623 } 17763859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17776929Smisaki " <== nxge_fflp_config_llc_snap_enable")); 17783859Sml29623 return (NXGE_OK); 17793859Sml29623 } 17803859Sml29623 17813859Sml29623 nxge_status_t 17823859Sml29623 nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep) 17833859Sml29623 { 17843859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle; 17853859Sml29623 npi_status_t rs = NPI_SUCCESS; 17863859Sml29623 17873859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17886929Smisaki " ==> nxge_fflp_config_llc_snap_disable")); 17893859Sml29623 rs = npi_fflp_cfg_llcsnap_disable(handle); 17903859Sml29623 if (rs & NPI_FFLP_ERROR) { 17913859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17926929Smisaki " nxge_fflp_config_llc_snap_disable failed")); 17933859Sml29623 return (NXGE_ERROR | rs); 17943859Sml29623 } 17953859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17966929Smisaki " <== nxge_fflp_config_llc_snap_disable")); 17973859Sml29623 return (NXGE_OK); 17983859Sml29623 } 17993859Sml29623 18003859Sml29623 nxge_status_t 18013859Sml29623 nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class, 18023859Sml29623 uint32_t config) 18033859Sml29623 { 18043859Sml29623 npi_status_t rs = NPI_SUCCESS; 18053859Sml29623 npi_handle_t handle = nxgep->npi_reg_handle; 18063859Sml29623 uint8_t tos, tos_mask, proto, ver = 0; 18073859Sml29623 uint8_t class_enable = 0; 18083859Sml29623 18093859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config")); 18103859Sml29623 18113859Sml29623 tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >> 18126929Smisaki NXGE_CLASS_CFG_IP_TOS_SHIFT; 18133859Sml29623 tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >> 18146929Smisaki NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT; 18153859Sml29623 proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >> 18166929Smisaki NXGE_CLASS_CFG_IP_PROTO_SHIFT; 18173859Sml29623 if (config & NXGE_CLASS_CFG_IP_IPV6_MASK) 18183859Sml29623 ver = 1; 18193859Sml29623 if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK) 18203859Sml29623 class_enable = 1; 18213859Sml29623 rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask, 18226929Smisaki proto, ver); 18233859Sml29623 if (rs & NPI_FFLP_ERROR) { 18243859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18256929Smisaki " nxge_fflp_ip_usr_class_config" 18266929Smisaki " for class %d failed ", class)); 18273859Sml29623 return (NXGE_ERROR | rs); 18283859Sml29623 } 18293859Sml29623 if (class_enable) 18303859Sml29623 rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class); 18313859Sml29623 else 18323859Sml29623 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 18333859Sml29623 18343859Sml29623 if (rs & NPI_FFLP_ERROR) { 18353859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18366929Smisaki " nxge_fflp_ip_usr_class_config" 18376929Smisaki " TCAM enable/disable for class %d failed ", class)); 18383859Sml29623 return (NXGE_ERROR | rs); 18393859Sml29623 } 18403859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config")); 18413859Sml29623 return (NXGE_OK); 18423859Sml29623 } 18433859Sml29623 18443859Sml29623 nxge_status_t 18453859Sml29623 nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config) 18463859Sml29623 { 18473859Sml29623 uint32_t class_config; 18483859Sml29623 nxge_status_t t_status = NXGE_OK; 18493859Sml29623 nxge_status_t f_status = NXGE_OK; 18503859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 18513859Sml29623 18523859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 18533859Sml29623 18543859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 18553859Sml29623 class_config = p_class_cfgp->class_cfg[class]; 18563859Sml29623 18573859Sml29623 if (class_config != config) { 18583859Sml29623 p_class_cfgp->class_cfg[class] = config; 18593859Sml29623 class_config = config; 18603859Sml29623 } 18613859Sml29623 18623859Sml29623 t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config); 18633859Sml29623 f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config); 18643859Sml29623 18653859Sml29623 if (t_status & NPI_FFLP_ERROR) { 18663859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 18676929Smisaki " nxge_fflp_ip_class_config %x" 18686929Smisaki " for class %d tcam failed", config, class)); 18693859Sml29623 return (t_status); 18703859Sml29623 } 18713859Sml29623 if (f_status & NPI_FFLP_ERROR) { 18723859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18736929Smisaki " nxge_fflp_ip_class_config %x" 18746929Smisaki " for class %d flow key failed", config, class)); 18753859Sml29623 return (f_status); 18763859Sml29623 } 18773859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 18783859Sml29623 return (NXGE_OK); 18793859Sml29623 } 18803859Sml29623 18813859Sml29623 nxge_status_t 18823859Sml29623 nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class, 18833859Sml29623 uint32_t *config) 18843859Sml29623 { 18853859Sml29623 uint32_t t_class_config, f_class_config; 18863859Sml29623 int t_status = NXGE_OK; 18873859Sml29623 int f_status = NXGE_OK; 18883859Sml29623 18893859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 18903859Sml29623 18913859Sml29623 t_class_config = f_class_config = 0; 18923859Sml29623 t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config); 18933859Sml29623 f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config); 18943859Sml29623 18953859Sml29623 if (t_status & NPI_FFLP_ERROR) { 18963859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18976929Smisaki " nxge_fflp_ip_class_config_get " 18986929Smisaki " for class %d tcam failed", class)); 18993859Sml29623 return (t_status); 19003859Sml29623 } 19013859Sml29623 19023859Sml29623 if (f_status & NPI_FFLP_ERROR) { 19033859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 19046929Smisaki " nxge_fflp_ip_class_config_get " 19056929Smisaki " for class %d flow key failed", class)); 19063859Sml29623 return (f_status); 19073859Sml29623 } 19083859Sml29623 19093859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 19106929Smisaki " nxge_fflp_ip_class_config tcam %x flow %x", 19116929Smisaki t_class_config, f_class_config)); 19123859Sml29623 19133859Sml29623 *config = t_class_config | f_class_config; 19143859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get")); 19153859Sml29623 return (NXGE_OK); 19163859Sml29623 } 19173859Sml29623 19183859Sml29623 nxge_status_t 19193859Sml29623 nxge_fflp_ip_class_config_all(p_nxge_t nxgep) 19203859Sml29623 { 19213859Sml29623 uint32_t class_config; 19223859Sml29623 tcam_class_t class; 19233859Sml29623 19243859Sml29623 #ifdef NXGE_DEBUG 19253859Sml29623 int status = NXGE_OK; 19263859Sml29623 #endif 19273859Sml29623 19283859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config")); 19293859Sml29623 for (class = TCAM_CLASS_TCP_IPV4; 19306929Smisaki class <= TCAM_CLASS_SCTP_IPV6; class++) { 19313859Sml29623 class_config = nxgep->class_config.class_cfg[class]; 19323859Sml29623 #ifndef NXGE_DEBUG 19333859Sml29623 (void) nxge_fflp_ip_class_config(nxgep, class, class_config); 19343859Sml29623 #else 19353859Sml29623 status = nxge_fflp_ip_class_config(nxgep, class, class_config); 19363859Sml29623 if (status & NPI_FFLP_ERROR) { 19373859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19386929Smisaki "nxge_fflp_ip_class_config failed " 19396929Smisaki " class %d config %x ", 19406929Smisaki class, class_config)); 19413859Sml29623 } 19423859Sml29623 #endif 19433859Sml29623 } 19443859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 19453859Sml29623 return (NXGE_OK); 19463859Sml29623 } 19473859Sml29623 19483859Sml29623 nxge_status_t 19493859Sml29623 nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id) 19503859Sml29623 { 19513859Sml29623 uint8_t port, rdc_grp; 19523859Sml29623 npi_handle_t handle; 19533859Sml29623 npi_status_t rs = NPI_SUCCESS; 19543859Sml29623 uint8_t priority = 1; 19553859Sml29623 p_nxge_mv_cfg_t vlan_table; 19563859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 19573859Sml29623 p_nxge_hw_list_t hw_p; 19583859Sml29623 19593859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table")); 19603859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 19613859Sml29623 handle = nxgep->npi_reg_handle; 19623859Sml29623 vlan_table = p_class_cfgp->vlan_tbl; 19633859Sml29623 port = nxgep->function_num; 19643859Sml29623 19653859Sml29623 if (vlan_table[vlan_id].flag == 0) { 19663859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19676929Smisaki " nxge_fflp_config_vlan_table" 19686929Smisaki " vlan id is not configured %d", vlan_id)); 19693859Sml29623 return (NXGE_ERROR); 19703859Sml29623 } 19713859Sml29623 19723859Sml29623 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 19733859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19746929Smisaki " nxge_fflp_config_vlan_table:" 19756929Smisaki " common hardware not set", nxgep->niu_type)); 19763859Sml29623 return (NXGE_ERROR); 19773859Sml29623 } 19783859Sml29623 MUTEX_ENTER(&hw_p->nxge_vlan_lock); 19793859Sml29623 rdc_grp = vlan_table[vlan_id].rdctbl; 19803859Sml29623 rs = npi_fflp_cfg_enet_vlan_table_assoc(handle, 19816929Smisaki port, vlan_id, 19826929Smisaki rdc_grp, priority); 19833859Sml29623 19843859Sml29623 MUTEX_EXIT(&hw_p->nxge_vlan_lock); 19853859Sml29623 if (rs & NPI_FFLP_ERROR) { 19863859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19876929Smisaki "nxge_fflp_config_vlan_table failed " 19886929Smisaki " Port %d vlan_id %d rdc_grp %d", 19896929Smisaki port, vlan_id, rdc_grp)); 19903859Sml29623 return (NXGE_ERROR | rs); 19913859Sml29623 } 19923859Sml29623 19933859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table")); 19943859Sml29623 return (NXGE_OK); 19953859Sml29623 } 19963859Sml29623 19973859Sml29623 nxge_status_t 19983859Sml29623 nxge_fflp_update_hw(p_nxge_t nxgep) 19993859Sml29623 { 20003859Sml29623 nxge_status_t status = NXGE_OK; 20013859Sml29623 p_nxge_param_t pa; 20023859Sml29623 uint64_t cfgd_vlans; 20033859Sml29623 uint64_t *val_ptr; 20043859Sml29623 int i; 20053859Sml29623 int num_macs; 20063859Sml29623 uint8_t alt_mac; 20073859Sml29623 nxge_param_map_t *p_map; 20083859Sml29623 p_nxge_mv_cfg_t vlan_table; 20093859Sml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 20103859Sml29623 p_nxge_dma_pt_cfg_t p_all_cfgp; 20113859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp; 20123859Sml29623 20133859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw")); 20143859Sml29623 20153859Sml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 20163859Sml29623 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 20173859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 20183859Sml29623 20193859Sml29623 status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1); 20203859Sml29623 if (status != NXGE_OK) { 20213859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20226929Smisaki "nxge_fflp_set_hash1 Failed")); 20233859Sml29623 return (NXGE_ERROR); 20243859Sml29623 } 20253859Sml29623 20263859Sml29623 status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2); 20273859Sml29623 if (status != NXGE_OK) { 20283859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20296929Smisaki "nxge_fflp_set_hash2 Failed")); 20303859Sml29623 return (NXGE_ERROR); 20313859Sml29623 } 20323859Sml29623 vlan_table = p_class_cfgp->vlan_tbl; 20333859Sml29623 20343859Sml29623 /* configure vlan tables */ 20353859Sml29623 pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp]; 20365125Sjoycey #if defined(__i386) 20375125Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value; 20385125Sjoycey #else 20393859Sml29623 val_ptr = (uint64_t *)pa->value; 20405125Sjoycey #endif 20413859Sml29623 cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >> 20426929Smisaki NXGE_PARAM_ARRAY_CNT_SHIFT); 20433859Sml29623 20443859Sml29623 for (i = 0; i < cfgd_vlans; i++) { 20453859Sml29623 p_map = (nxge_param_map_t *)&val_ptr[i]; 20463859Sml29623 if (vlan_table[p_map->param_id].flag) { 20473859Sml29623 status = nxge_fflp_config_vlan_table(nxgep, 20486929Smisaki p_map->param_id); 20493859Sml29623 if (status != NXGE_OK) { 20503859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20516929Smisaki "nxge_fflp_config_vlan_table Failed")); 20523859Sml29623 return (NXGE_ERROR); 20533859Sml29623 } 20543859Sml29623 } 20553859Sml29623 } 20563859Sml29623 20573859Sml29623 /* config MAC addresses */ 20583859Sml29623 num_macs = p_cfgp->max_macs; 20593859Sml29623 pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp]; 20605125Sjoycey #if defined(__i386) 20615125Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value; 20625125Sjoycey #else 20633859Sml29623 val_ptr = (uint64_t *)pa->value; 20645125Sjoycey #endif 20653859Sml29623 20663859Sml29623 for (alt_mac = 0; alt_mac < num_macs; alt_mac++) { 20673859Sml29623 if (p_class_cfgp->mac_host_info[alt_mac].flag) { 20683859Sml29623 status = nxge_logical_mac_assign_rdc_table(nxgep, 20696929Smisaki alt_mac); 20703859Sml29623 if (status != NXGE_OK) { 20713859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20726929Smisaki "nxge_logical_mac_assign_rdc_table" 20736929Smisaki " Failed")); 20743859Sml29623 return (NXGE_ERROR); 20753859Sml29623 } 20763859Sml29623 } 20773859Sml29623 } 20783859Sml29623 20793859Sml29623 /* Config Hash values */ 20805523Syc148097 /* config classes */ 20813859Sml29623 status = nxge_fflp_ip_class_config_all(nxgep); 20823859Sml29623 if (status != NXGE_OK) { 20833859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 20846929Smisaki "nxge_fflp_ip_class_config_all Failed")); 20853859Sml29623 return (NXGE_ERROR); 20863859Sml29623 } 20873859Sml29623 return (NXGE_OK); 20883859Sml29623 } 20893859Sml29623 20903859Sml29623 nxge_status_t 20913859Sml29623 nxge_classify_init_hw(p_nxge_t nxgep) 20923859Sml29623 { 20933859Sml29623 nxge_status_t status = NXGE_OK; 20943859Sml29623 20953859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw")); 20963859Sml29623 20973859Sml29623 if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) { 20983859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20996929Smisaki "nxge_classify_init_hw already init")); 21003859Sml29623 return (NXGE_OK); 21013859Sml29623 } 21023859Sml29623 21033859Sml29623 /* Now do a real configuration */ 21043859Sml29623 status = nxge_fflp_update_hw(nxgep); 21053859Sml29623 if (status != NXGE_OK) { 21063859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21076929Smisaki "nxge_fflp_update_hw failed")); 21083859Sml29623 return (NXGE_ERROR); 21093859Sml29623 } 21103859Sml29623 21113859Sml29623 /* Init RDC tables? ? who should do that? rxdma or fflp ? */ 21123859Sml29623 /* attach rdc table to the MAC port. */ 21133859Sml29623 status = nxge_main_mac_assign_rdc_table(nxgep); 21143859Sml29623 if (status != NXGE_OK) { 21153859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21166929Smisaki "nxge_main_mac_assign_rdc_table failed")); 21173859Sml29623 return (NXGE_ERROR); 21183859Sml29623 } 21193859Sml29623 21203859Sml29623 status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 21213859Sml29623 if (status != NXGE_OK) { 21223859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21236929Smisaki "nxge_multicast_mac_assign_rdc_table failed")); 21243859Sml29623 return (NXGE_ERROR); 21253859Sml29623 } 21263859Sml29623 2127*11304SJanie.Lu@Sun.COM if (nxgep->classifier.fragment_bug == 1) { 2128*11304SJanie.Lu@Sun.COM status = nxge_tcam_handle_ip_fragment(nxgep); 2129*11304SJanie.Lu@Sun.COM if (status != NXGE_OK) { 2130*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2131*11304SJanie.Lu@Sun.COM "nxge_tcam_handle_ip_fragment failed")); 2132*11304SJanie.Lu@Sun.COM return (NXGE_ERROR); 2133*11304SJanie.Lu@Sun.COM } 21343859Sml29623 } 21353859Sml29623 21363859Sml29623 nxgep->classifier.state |= NXGE_FFLP_HW_INIT; 21373859Sml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw")); 21383859Sml29623 return (NXGE_OK); 21393859Sml29623 } 21403859Sml29623 21413859Sml29623 nxge_status_t 21423859Sml29623 nxge_fflp_handle_sys_errors(p_nxge_t nxgep) 21433859Sml29623 { 21443859Sml29623 npi_handle_t handle; 21453859Sml29623 p_nxge_fflp_stats_t statsp; 21463859Sml29623 uint8_t portn, rdc_grp; 21473859Sml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp; 21483859Sml29623 p_nxge_hw_pt_cfg_t p_cfgp; 21493859Sml29623 vlan_par_err_t vlan_err; 21503859Sml29623 tcam_err_t tcam_err; 21513859Sml29623 hash_lookup_err_log1_t fcram1_err; 21523859Sml29623 hash_lookup_err_log2_t fcram2_err; 21533859Sml29623 hash_tbl_data_log_t fcram_err; 21543859Sml29623 21553859Sml29623 handle = nxgep->npi_handle; 21563859Sml29623 statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats; 21573859Sml29623 portn = nxgep->mac.portnum; 21583859Sml29623 21593859Sml29623 /* 21603859Sml29623 * need to read the fflp error registers to figure out what the error 21613859Sml29623 * is 21623859Sml29623 */ 21633859Sml29623 npi_fflp_vlan_error_get(handle, &vlan_err); 21643859Sml29623 npi_fflp_tcam_error_get(handle, &tcam_err); 21653859Sml29623 21663859Sml29623 if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) { 21673859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 21686929Smisaki " vlan table parity error on port %d" 21696929Smisaki " addr: 0x%x data: 0x%x", 21706929Smisaki portn, vlan_err.bits.ldw.addr, 21716929Smisaki vlan_err.bits.ldw.data)); 21723859Sml29623 statsp->vlan_parity_err++; 21733859Sml29623 21743859Sml29623 if (vlan_err.bits.ldw.m_err) { 21753859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 21766929Smisaki " vlan table multiple errors on port %d", 21776929Smisaki portn)); 21783859Sml29623 } 21793859Sml29623 statsp->errlog.vlan = (uint32_t)vlan_err.value; 21803859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 21816929Smisaki NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR); 21823859Sml29623 npi_fflp_vlan_error_clear(handle); 21833859Sml29623 } 21843859Sml29623 21853859Sml29623 if (tcam_err.bits.ldw.err) { 21863859Sml29623 if (tcam_err.bits.ldw.p_ecc != 0) { 21873859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 21886929Smisaki " TCAM ECC error on port %d" 21896929Smisaki " TCAM entry: 0x%x syndrome: 0x%x", 21906929Smisaki portn, tcam_err.bits.ldw.addr, 21916929Smisaki tcam_err.bits.ldw.syndrome)); 21923859Sml29623 statsp->tcam_ecc_err++; 21933859Sml29623 } else { 21943859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 21956929Smisaki " TCAM Parity error on port %d" 21966929Smisaki " addr: 0x%x parity value: 0x%x", 21976929Smisaki portn, tcam_err.bits.ldw.addr, 21986929Smisaki tcam_err.bits.ldw.syndrome)); 21993859Sml29623 statsp->tcam_parity_err++; 22003859Sml29623 } 22013859Sml29623 22023859Sml29623 if (tcam_err.bits.ldw.mult) { 22033859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 22046929Smisaki " TCAM Multiple errors on port %d", portn)); 22053859Sml29623 } else { 22063859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 22076929Smisaki " TCAM PIO error on port %d", portn)); 22083859Sml29623 } 22093859Sml29623 22103859Sml29623 statsp->errlog.tcam = (uint32_t)tcam_err.value; 22113859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 22126929Smisaki NXGE_FM_EREPORT_FFLP_TCAM_ERR); 22133859Sml29623 npi_fflp_tcam_error_clear(handle); 22143859Sml29623 } 22153859Sml29623 22163859Sml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 22173859Sml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 22183859Sml29623 22196495Sspeer for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) { 22206495Sspeer if (p_cfgp->grpids[rdc_grp]) { 22216495Sspeer npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp); 22226495Sspeer if (fcram_err.bits.ldw.pio_err) { 22236495Sspeer NXGE_ERROR_MSG((nxgep, FFLP_CTL, 22246929Smisaki " FCRAM PIO ECC error on port %d" 22256929Smisaki " rdc group: %d Hash Table addr: 0x%x" 22266929Smisaki " syndrome: 0x%x", 22276929Smisaki portn, rdc_grp, 22286929Smisaki fcram_err.bits.ldw.fcram_addr, 22296929Smisaki fcram_err.bits.ldw.syndrome)); 22306495Sspeer statsp->hash_pio_err[rdc_grp]++; 22316495Sspeer statsp->errlog.hash_pio[rdc_grp] = 22326495Sspeer (uint32_t)fcram_err.value; 22336495Sspeer NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 22346495Sspeer NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR); 22356495Sspeer npi_fflp_fcram_error_clear(handle, rdc_grp); 22366495Sspeer } 22373859Sml29623 } 22383859Sml29623 } 22393859Sml29623 22403859Sml29623 npi_fflp_fcram_error_log1_get(handle, &fcram1_err); 22413859Sml29623 if (fcram1_err.bits.ldw.ecc_err) { 22423859Sml29623 char *multi_str = ""; 22433859Sml29623 char *multi_bit_str = ""; 22443859Sml29623 22453859Sml29623 npi_fflp_fcram_error_log2_get(handle, &fcram2_err); 22463859Sml29623 if (fcram1_err.bits.ldw.mult_lk) { 22473859Sml29623 multi_str = "multiple"; 22483859Sml29623 } 22493859Sml29623 if (fcram1_err.bits.ldw.mult_bit) { 22503859Sml29623 multi_bit_str = "multiple bits"; 22513859Sml29623 } 22525523Syc148097 statsp->hash_lookup_err++; 22533859Sml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 22546929Smisaki " FCRAM %s lookup %s ECC error on port %d" 22556929Smisaki " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x", 22566929Smisaki multi_str, multi_bit_str, portn, 22576929Smisaki fcram2_err.bits.ldw.h1, 22586929Smisaki fcram2_err.bits.ldw.subarea, 22596929Smisaki fcram2_err.bits.ldw.syndrome)); 22603859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 22616929Smisaki NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR); 22623859Sml29623 } 22633859Sml29623 statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value; 22643859Sml29623 statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value; 22653859Sml29623 return (NXGE_OK); 22663859Sml29623 } 2267*11304SJanie.Lu@Sun.COM 2268*11304SJanie.Lu@Sun.COM int 2269*11304SJanie.Lu@Sun.COM nxge_get_valid_tcam_cnt(p_nxge_t nxgep) { 2270*11304SJanie.Lu@Sun.COM return ((nxgep->classifier.fragment_bug == 1) ? 2271*11304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt - 1 : 2272*11304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt); 2273*11304SJanie.Lu@Sun.COM } 2274*11304SJanie.Lu@Sun.COM 2275*11304SJanie.Lu@Sun.COM int 2276*11304SJanie.Lu@Sun.COM nxge_rxdma_channel_cnt(p_nxge_t nxgep) 2277*11304SJanie.Lu@Sun.COM { 2278*11304SJanie.Lu@Sun.COM p_nxge_dma_pt_cfg_t p_dma_cfgp; 2279*11304SJanie.Lu@Sun.COM p_nxge_hw_pt_cfg_t p_cfgp; 2280*11304SJanie.Lu@Sun.COM 2281*11304SJanie.Lu@Sun.COM p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2282*11304SJanie.Lu@Sun.COM p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2283*11304SJanie.Lu@Sun.COM return (p_cfgp->max_rdcs); 2284*11304SJanie.Lu@Sun.COM } 2285*11304SJanie.Lu@Sun.COM 2286*11304SJanie.Lu@Sun.COM /* ARGSUSED */ 2287*11304SJanie.Lu@Sun.COM int 2288*11304SJanie.Lu@Sun.COM nxge_rxclass_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 2289*11304SJanie.Lu@Sun.COM { 2290*11304SJanie.Lu@Sun.COM uint32_t cmd; 2291*11304SJanie.Lu@Sun.COM rx_class_cfg_t *cfg_info = (rx_class_cfg_t *)mp->b_rptr; 2292*11304SJanie.Lu@Sun.COM 2293*11304SJanie.Lu@Sun.COM if (nxgep == NULL) { 2294*11304SJanie.Lu@Sun.COM return (-1); 2295*11304SJanie.Lu@Sun.COM } 2296*11304SJanie.Lu@Sun.COM cmd = cfg_info->cmd; 2297*11304SJanie.Lu@Sun.COM switch (cmd) { 2298*11304SJanie.Lu@Sun.COM default: 2299*11304SJanie.Lu@Sun.COM return (-1); 2300*11304SJanie.Lu@Sun.COM 2301*11304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_GCHAN: 2302*11304SJanie.Lu@Sun.COM cfg_info->data = nxge_rxdma_channel_cnt(nxgep); 2303*11304SJanie.Lu@Sun.COM break; 2304*11304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_GRULE_CNT: 2305*11304SJanie.Lu@Sun.COM MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2306*11304SJanie.Lu@Sun.COM cfg_info->rule_cnt = nxge_get_valid_tcam_cnt(nxgep); 2307*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2308*11304SJanie.Lu@Sun.COM break; 2309*11304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_GRULE: 2310*11304SJanie.Lu@Sun.COM nxge_get_tcam_entry(nxgep, &cfg_info->fs); 2311*11304SJanie.Lu@Sun.COM break; 2312*11304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_GRULE_ALL: 2313*11304SJanie.Lu@Sun.COM nxge_get_tcam_entry_all(nxgep, cfg_info); 2314*11304SJanie.Lu@Sun.COM break; 2315*11304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_RULE_DEL: 2316*11304SJanie.Lu@Sun.COM nxge_del_tcam_entry(nxgep, cfg_info->fs.location); 2317*11304SJanie.Lu@Sun.COM break; 2318*11304SJanie.Lu@Sun.COM case NXGE_RX_CLASS_RULE_INS: 2319*11304SJanie.Lu@Sun.COM (void) nxge_add_tcam_entry(nxgep, &cfg_info->fs); 2320*11304SJanie.Lu@Sun.COM break; 2321*11304SJanie.Lu@Sun.COM } 2322*11304SJanie.Lu@Sun.COM return (0); 2323*11304SJanie.Lu@Sun.COM } 2324*11304SJanie.Lu@Sun.COM /* ARGSUSED */ 2325*11304SJanie.Lu@Sun.COM int 2326*11304SJanie.Lu@Sun.COM nxge_rxhash_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 2327*11304SJanie.Lu@Sun.COM { 2328*11304SJanie.Lu@Sun.COM uint32_t cmd; 2329*11304SJanie.Lu@Sun.COM cfg_cmd_t *cfg_info = (cfg_cmd_t *)mp->b_rptr; 2330*11304SJanie.Lu@Sun.COM 2331*11304SJanie.Lu@Sun.COM if (nxgep == NULL) { 2332*11304SJanie.Lu@Sun.COM return (-1); 2333*11304SJanie.Lu@Sun.COM } 2334*11304SJanie.Lu@Sun.COM cmd = cfg_info->cmd; 2335*11304SJanie.Lu@Sun.COM 2336*11304SJanie.Lu@Sun.COM switch (cmd) { 2337*11304SJanie.Lu@Sun.COM default: 2338*11304SJanie.Lu@Sun.COM return (-1); 2339*11304SJanie.Lu@Sun.COM case NXGE_IPTUN_CFG_ADD_CLS: 2340*11304SJanie.Lu@Sun.COM nxge_add_iptun_class(nxgep, &cfg_info->iptun_cfg, 2341*11304SJanie.Lu@Sun.COM &cfg_info->class_id); 2342*11304SJanie.Lu@Sun.COM break; 2343*11304SJanie.Lu@Sun.COM case NXGE_IPTUN_CFG_SET_HASH: 2344*11304SJanie.Lu@Sun.COM nxge_cfg_iptun_hash(nxgep, &cfg_info->iptun_cfg, 2345*11304SJanie.Lu@Sun.COM cfg_info->class_id); 2346*11304SJanie.Lu@Sun.COM break; 2347*11304SJanie.Lu@Sun.COM case NXGE_IPTUN_CFG_DEL_CLS: 2348*11304SJanie.Lu@Sun.COM nxge_del_iptun_class(nxgep, cfg_info->class_id); 2349*11304SJanie.Lu@Sun.COM break; 2350*11304SJanie.Lu@Sun.COM case NXGE_IPTUN_CFG_GET_CLS: 2351*11304SJanie.Lu@Sun.COM nxge_get_iptun_class(nxgep, &cfg_info->iptun_cfg, 2352*11304SJanie.Lu@Sun.COM cfg_info->class_id); 2353*11304SJanie.Lu@Sun.COM break; 2354*11304SJanie.Lu@Sun.COM case NXGE_CLS_CFG_SET_SYM: 2355*11304SJanie.Lu@Sun.COM nxge_set_ip_cls_sym(nxgep, cfg_info->class_id, cfg_info->sym); 2356*11304SJanie.Lu@Sun.COM break; 2357*11304SJanie.Lu@Sun.COM case NXGE_CLS_CFG_GET_SYM: 2358*11304SJanie.Lu@Sun.COM nxge_get_ip_cls_sym(nxgep, cfg_info->class_id, &cfg_info->sym); 2359*11304SJanie.Lu@Sun.COM break; 2360*11304SJanie.Lu@Sun.COM } 2361*11304SJanie.Lu@Sun.COM return (0); 2362*11304SJanie.Lu@Sun.COM } 2363*11304SJanie.Lu@Sun.COM 2364*11304SJanie.Lu@Sun.COM void 2365*11304SJanie.Lu@Sun.COM nxge_get_tcam_entry_all(p_nxge_t nxgep, rx_class_cfg_t *cfgp) 2366*11304SJanie.Lu@Sun.COM { 2367*11304SJanie.Lu@Sun.COM nxge_classify_t *clasp = &nxgep->classifier; 2368*11304SJanie.Lu@Sun.COM uint16_t n_entries; 2369*11304SJanie.Lu@Sun.COM int i, j, k; 2370*11304SJanie.Lu@Sun.COM tcam_flow_spec_t *tcam_entryp; 2371*11304SJanie.Lu@Sun.COM 2372*11304SJanie.Lu@Sun.COM cfgp->data = clasp->tcam_size; 2373*11304SJanie.Lu@Sun.COM MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2374*11304SJanie.Lu@Sun.COM n_entries = cfgp->rule_cnt; 2375*11304SJanie.Lu@Sun.COM 2376*11304SJanie.Lu@Sun.COM for (i = 0, j = 0; j < cfgp->data; j++) { 2377*11304SJanie.Lu@Sun.COM k = nxge_tcam_get_index(nxgep, j); 2378*11304SJanie.Lu@Sun.COM tcam_entryp = &clasp->tcam_entries[k]; 2379*11304SJanie.Lu@Sun.COM if (tcam_entryp->valid != 1) 2380*11304SJanie.Lu@Sun.COM continue; 2381*11304SJanie.Lu@Sun.COM cfgp->rule_locs[i] = j; 2382*11304SJanie.Lu@Sun.COM i++; 2383*11304SJanie.Lu@Sun.COM }; 2384*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2385*11304SJanie.Lu@Sun.COM 2386*11304SJanie.Lu@Sun.COM if (n_entries != i) { 2387*11304SJanie.Lu@Sun.COM /* print warning, this should not happen */ 2388*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry_all" 2389*11304SJanie.Lu@Sun.COM "n_entries[%d] != i[%d]!!!", n_entries, i)); 2390*11304SJanie.Lu@Sun.COM } 2391*11304SJanie.Lu@Sun.COM } 2392*11304SJanie.Lu@Sun.COM 2393*11304SJanie.Lu@Sun.COM 2394*11304SJanie.Lu@Sun.COM /* Entries for the ports are interleaved in the TCAM */ 2395*11304SJanie.Lu@Sun.COM static uint16_t 2396*11304SJanie.Lu@Sun.COM nxge_tcam_get_index(p_nxge_t nxgep, uint16_t index) 2397*11304SJanie.Lu@Sun.COM { 2398*11304SJanie.Lu@Sun.COM /* One entry reserved for IP fragment rule */ 2399*11304SJanie.Lu@Sun.COM if (index >= (nxgep->classifier.tcam_size - 1)) 2400*11304SJanie.Lu@Sun.COM index = 0; 2401*11304SJanie.Lu@Sun.COM if (nxgep->classifier.fragment_bug == 1) 2402*11304SJanie.Lu@Sun.COM index++; 2403*11304SJanie.Lu@Sun.COM return (nxgep->classifier.tcam_top + (index * nxgep->nports)); 2404*11304SJanie.Lu@Sun.COM } 2405*11304SJanie.Lu@Sun.COM 2406*11304SJanie.Lu@Sun.COM static uint32_t 2407*11304SJanie.Lu@Sun.COM nxge_tcam_cls_to_flow(uint32_t class_code) { 2408*11304SJanie.Lu@Sun.COM switch (class_code) { 2409*11304SJanie.Lu@Sun.COM case TCAM_CLASS_TCP_IPV4: 2410*11304SJanie.Lu@Sun.COM return (FSPEC_TCPIP4); 2411*11304SJanie.Lu@Sun.COM case TCAM_CLASS_UDP_IPV4: 2412*11304SJanie.Lu@Sun.COM return (FSPEC_UDPIP4); 2413*11304SJanie.Lu@Sun.COM case TCAM_CLASS_AH_ESP_IPV4: 2414*11304SJanie.Lu@Sun.COM return (FSPEC_AHIP4); 2415*11304SJanie.Lu@Sun.COM case TCAM_CLASS_SCTP_IPV4: 2416*11304SJanie.Lu@Sun.COM return (FSPEC_SCTPIP4); 2417*11304SJanie.Lu@Sun.COM case TCAM_CLASS_TCP_IPV6: 2418*11304SJanie.Lu@Sun.COM return (FSPEC_TCPIP6); 2419*11304SJanie.Lu@Sun.COM case TCAM_CLASS_UDP_IPV6: 2420*11304SJanie.Lu@Sun.COM return (FSPEC_UDPIP6); 2421*11304SJanie.Lu@Sun.COM case TCAM_CLASS_AH_ESP_IPV6: 2422*11304SJanie.Lu@Sun.COM return (FSPEC_AHIP6); 2423*11304SJanie.Lu@Sun.COM case TCAM_CLASS_SCTP_IPV6: 2424*11304SJanie.Lu@Sun.COM return (FSPEC_SCTPIP6); 2425*11304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_4: 2426*11304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_5: 2427*11304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_6: 2428*11304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_7: 2429*11304SJanie.Lu@Sun.COM return (FSPEC_IP_USR); 2430*11304SJanie.Lu@Sun.COM default: 2431*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "nxge_tcam_cls_to_flow" 2432*11304SJanie.Lu@Sun.COM ": Unknown class code [0x%x]", class_code)); 2433*11304SJanie.Lu@Sun.COM break; 2434*11304SJanie.Lu@Sun.COM } 2435*11304SJanie.Lu@Sun.COM return (0); 2436*11304SJanie.Lu@Sun.COM } 2437*11304SJanie.Lu@Sun.COM 2438*11304SJanie.Lu@Sun.COM void 2439*11304SJanie.Lu@Sun.COM nxge_get_tcam_entry(p_nxge_t nxgep, flow_resource_t *fs) 2440*11304SJanie.Lu@Sun.COM { 2441*11304SJanie.Lu@Sun.COM uint16_t index; 2442*11304SJanie.Lu@Sun.COM tcam_flow_spec_t *tcam_ep; 2443*11304SJanie.Lu@Sun.COM tcam_entry_t *tp; 2444*11304SJanie.Lu@Sun.COM flow_spec_t *fspec; 2445*11304SJanie.Lu@Sun.COM tcpip4_spec_t *fspec_key; 2446*11304SJanie.Lu@Sun.COM tcpip4_spec_t *fspec_mask; 2447*11304SJanie.Lu@Sun.COM 2448*11304SJanie.Lu@Sun.COM index = nxge_tcam_get_index(nxgep, (uint16_t)fs->location); 2449*11304SJanie.Lu@Sun.COM tcam_ep = &nxgep->classifier.tcam_entries[index]; 2450*11304SJanie.Lu@Sun.COM if (tcam_ep->valid != 1) { 2451*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry: :" 2452*11304SJanie.Lu@Sun.COM "Entry [%d] invalid for index [%d]", fs->location, index)); 2453*11304SJanie.Lu@Sun.COM return; 2454*11304SJanie.Lu@Sun.COM } 2455*11304SJanie.Lu@Sun.COM 2456*11304SJanie.Lu@Sun.COM /* Fill the flow spec entry */ 2457*11304SJanie.Lu@Sun.COM tp = &tcam_ep->tce; 2458*11304SJanie.Lu@Sun.COM fspec = &fs->flow_spec; 2459*11304SJanie.Lu@Sun.COM fspec->flow_type = nxge_tcam_cls_to_flow(tp->ip4_class_key); 2460*11304SJanie.Lu@Sun.COM 2461*11304SJanie.Lu@Sun.COM /* TODO - look at proto field to differentiate between AH and ESP */ 2462*11304SJanie.Lu@Sun.COM if (fspec->flow_type == FSPEC_AHIP4) { 2463*11304SJanie.Lu@Sun.COM if (tp->ip4_proto_key == IPPROTO_ESP) 2464*11304SJanie.Lu@Sun.COM fspec->flow_type = FSPEC_ESPIP4; 2465*11304SJanie.Lu@Sun.COM } 2466*11304SJanie.Lu@Sun.COM 2467*11304SJanie.Lu@Sun.COM switch (tp->ip4_class_key) { 2468*11304SJanie.Lu@Sun.COM case TCAM_CLASS_TCP_IPV4: 2469*11304SJanie.Lu@Sun.COM case TCAM_CLASS_UDP_IPV4: 2470*11304SJanie.Lu@Sun.COM case TCAM_CLASS_AH_ESP_IPV4: 2471*11304SJanie.Lu@Sun.COM case TCAM_CLASS_SCTP_IPV4: 2472*11304SJanie.Lu@Sun.COM fspec_key = (tcpip4_spec_t *)&fspec->uh.tcpip4spec; 2473*11304SJanie.Lu@Sun.COM fspec_mask = (tcpip4_spec_t *)&fspec->um.tcpip4spec; 2474*11304SJanie.Lu@Sun.COM FSPEC_IPV4_ADDR(fspec_key->ip4dst, tp->ip4_dest_key); 2475*11304SJanie.Lu@Sun.COM FSPEC_IPV4_ADDR(fspec_mask->ip4dst, tp->ip4_dest_mask); 2476*11304SJanie.Lu@Sun.COM FSPEC_IPV4_ADDR(fspec_key->ip4src, tp->ip4_src_key); 2477*11304SJanie.Lu@Sun.COM FSPEC_IPV4_ADDR(fspec_mask->ip4src, tp->ip4_src_mask); 2478*11304SJanie.Lu@Sun.COM fspec_key->tos = tp->ip4_tos_key; 2479*11304SJanie.Lu@Sun.COM fspec_mask->tos = tp->ip4_tos_mask; 2480*11304SJanie.Lu@Sun.COM break; 2481*11304SJanie.Lu@Sun.COM default: 2482*11304SJanie.Lu@Sun.COM break; 2483*11304SJanie.Lu@Sun.COM } 2484*11304SJanie.Lu@Sun.COM 2485*11304SJanie.Lu@Sun.COM switch (tp->ip4_class_key) { 2486*11304SJanie.Lu@Sun.COM case TCAM_CLASS_TCP_IPV4: 2487*11304SJanie.Lu@Sun.COM case TCAM_CLASS_UDP_IPV4: 2488*11304SJanie.Lu@Sun.COM case TCAM_CLASS_SCTP_IPV4: 2489*11304SJanie.Lu@Sun.COM FSPEC_IP_PORTS(fspec_key->pdst, fspec_key->psrc, 2490*11304SJanie.Lu@Sun.COM tp->ip4_port_key); 2491*11304SJanie.Lu@Sun.COM FSPEC_IP_PORTS(fspec_mask->pdst, fspec_mask->psrc, 2492*11304SJanie.Lu@Sun.COM tp->ip4_port_mask); 2493*11304SJanie.Lu@Sun.COM break; 2494*11304SJanie.Lu@Sun.COM case TCAM_CLASS_AH_ESP_IPV4: 2495*11304SJanie.Lu@Sun.COM fspec->uh.ahip4spec.spi = tp->ip4_port_key; 2496*11304SJanie.Lu@Sun.COM fspec->um.ahip4spec.spi = tp->ip4_port_mask; 2497*11304SJanie.Lu@Sun.COM break; 2498*11304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_4: 2499*11304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_5: 2500*11304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_6: 2501*11304SJanie.Lu@Sun.COM case TCAM_CLASS_IP_USER_7: 2502*11304SJanie.Lu@Sun.COM fspec->uh.ip_usr_spec.l4_4_bytes = tp->ip4_port_key; 2503*11304SJanie.Lu@Sun.COM fspec->um.ip_usr_spec.l4_4_bytes = tp->ip4_port_mask; 2504*11304SJanie.Lu@Sun.COM fspec->uh.ip_usr_spec.ip_ver = FSPEC_IP4; 2505*11304SJanie.Lu@Sun.COM fspec->uh.ip_usr_spec.proto = tp->ip4_proto_key; 2506*11304SJanie.Lu@Sun.COM fspec->um.ip_usr_spec.proto = tp->ip4_proto_mask; 2507*11304SJanie.Lu@Sun.COM break; 2508*11304SJanie.Lu@Sun.COM default: 2509*11304SJanie.Lu@Sun.COM break; 2510*11304SJanie.Lu@Sun.COM } 2511*11304SJanie.Lu@Sun.COM 2512*11304SJanie.Lu@Sun.COM if (tp->match_action.bits.ldw.disc == 1) { 2513*11304SJanie.Lu@Sun.COM fs->channel_cookie = NXGE_PKT_DISCARD; 2514*11304SJanie.Lu@Sun.COM } else { 2515*11304SJanie.Lu@Sun.COM fs->channel_cookie = tp->match_action.bits.ldw.offset; 2516*11304SJanie.Lu@Sun.COM } 2517*11304SJanie.Lu@Sun.COM } 2518*11304SJanie.Lu@Sun.COM 2519*11304SJanie.Lu@Sun.COM void 2520*11304SJanie.Lu@Sun.COM nxge_del_tcam_entry(p_nxge_t nxgep, uint32_t location) 2521*11304SJanie.Lu@Sun.COM { 2522*11304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS; 2523*11304SJanie.Lu@Sun.COM uint16_t index; 2524*11304SJanie.Lu@Sun.COM tcam_flow_spec_t *tcam_ep; 2525*11304SJanie.Lu@Sun.COM tcam_entry_t *tp; 2526*11304SJanie.Lu@Sun.COM tcam_class_t class; 2527*11304SJanie.Lu@Sun.COM 2528*11304SJanie.Lu@Sun.COM MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2529*11304SJanie.Lu@Sun.COM index = nxge_tcam_get_index(nxgep, (uint16_t)location); 2530*11304SJanie.Lu@Sun.COM tcam_ep = &nxgep->classifier.tcam_entries[index]; 2531*11304SJanie.Lu@Sun.COM if (tcam_ep->valid != 1) { 2532*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_tcam_entry: :" 2533*11304SJanie.Lu@Sun.COM "Entry [%d] invalid for index [%d]", location, index)); 2534*11304SJanie.Lu@Sun.COM goto fail; 2535*11304SJanie.Lu@Sun.COM } 2536*11304SJanie.Lu@Sun.COM 2537*11304SJanie.Lu@Sun.COM /* Fill the flow spec entry */ 2538*11304SJanie.Lu@Sun.COM tp = &tcam_ep->tce; 2539*11304SJanie.Lu@Sun.COM class = tp->ip4_class_key; 2540*11304SJanie.Lu@Sun.COM if (class >= TCAM_CLASS_IP_USER_4 && class <= TCAM_CLASS_IP_USER_7) { 2541*11304SJanie.Lu@Sun.COM int i; 2542*11304SJanie.Lu@Sun.COM nxge_usr_l3_cls_t *l3_ucls_p; 2543*11304SJanie.Lu@Sun.COM p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 2544*11304SJanie.Lu@Sun.COM 2545*11304SJanie.Lu@Sun.COM for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 2546*11304SJanie.Lu@Sun.COM l3_ucls_p = &hw_p->tcam_l3_prog_cls[i]; 2547*11304SJanie.Lu@Sun.COM if (l3_ucls_p->valid) { 2548*11304SJanie.Lu@Sun.COM if (l3_ucls_p->cls == class && 2549*11304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt) { 2550*11304SJanie.Lu@Sun.COM l3_ucls_p->tcam_ref_cnt--; 2551*11304SJanie.Lu@Sun.COM if (l3_ucls_p->tcam_ref_cnt > 0) 2552*11304SJanie.Lu@Sun.COM continue; 2553*11304SJanie.Lu@Sun.COM /* disable class */ 2554*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_disable( 2555*11304SJanie.Lu@Sun.COM nxgep->npi_reg_handle, 2556*11304SJanie.Lu@Sun.COM (tcam_class_t)class); 2557*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2558*11304SJanie.Lu@Sun.COM goto fail; 2559*11304SJanie.Lu@Sun.COM l3_ucls_p->cls = 0; 2560*11304SJanie.Lu@Sun.COM l3_ucls_p->pid = 0; 2561*11304SJanie.Lu@Sun.COM l3_ucls_p->valid = 0; 2562*11304SJanie.Lu@Sun.COM break; 2563*11304SJanie.Lu@Sun.COM } 2564*11304SJanie.Lu@Sun.COM } 2565*11304SJanie.Lu@Sun.COM } 2566*11304SJanie.Lu@Sun.COM if (i == NXGE_L3_PROG_CLS) { 2567*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2568*11304SJanie.Lu@Sun.COM "nxge_del_tcam_entry: Usr class " 2569*11304SJanie.Lu@Sun.COM "0x%llx not found", (unsigned long long) class)); 2570*11304SJanie.Lu@Sun.COM goto fail; 2571*11304SJanie.Lu@Sun.COM } 2572*11304SJanie.Lu@Sun.COM } 2573*11304SJanie.Lu@Sun.COM 2574*11304SJanie.Lu@Sun.COM rs = npi_fflp_tcam_entry_invalidate(nxgep->npi_reg_handle, index); 2575*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) { 2576*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2577*11304SJanie.Lu@Sun.COM "nxge_del_tcam_entry: TCAM invalidate failed " 2578*11304SJanie.Lu@Sun.COM "at loc %d ", location)); 2579*11304SJanie.Lu@Sun.COM goto fail; 2580*11304SJanie.Lu@Sun.COM } 2581*11304SJanie.Lu@Sun.COM 2582*11304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entries[index].valid = 0; 2583*11304SJanie.Lu@Sun.COM nxgep->classifier.tcam_entry_cnt--; 2584*11304SJanie.Lu@Sun.COM 2585*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2586*11304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_del_tcam_entry")); 2587*11304SJanie.Lu@Sun.COM return; 2588*11304SJanie.Lu@Sun.COM fail: 2589*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2590*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2591*11304SJanie.Lu@Sun.COM "<== nxge_del_tcam_entry FAILED")); 2592*11304SJanie.Lu@Sun.COM } 2593*11304SJanie.Lu@Sun.COM 2594*11304SJanie.Lu@Sun.COM static uint8_t 2595*11304SJanie.Lu@Sun.COM nxge_iptun_pkt_type_to_pid(uint8_t pkt_type) 2596*11304SJanie.Lu@Sun.COM { 2597*11304SJanie.Lu@Sun.COM uint8_t pid = 0; 2598*11304SJanie.Lu@Sun.COM 2599*11304SJanie.Lu@Sun.COM switch (pkt_type) { 2600*11304SJanie.Lu@Sun.COM case IPTUN_PKT_IPV4: 2601*11304SJanie.Lu@Sun.COM pid = 4; 2602*11304SJanie.Lu@Sun.COM break; 2603*11304SJanie.Lu@Sun.COM case IPTUN_PKT_IPV6: 2604*11304SJanie.Lu@Sun.COM pid = 41; 2605*11304SJanie.Lu@Sun.COM break; 2606*11304SJanie.Lu@Sun.COM case IPTUN_PKT_GRE: 2607*11304SJanie.Lu@Sun.COM pid = 47; 2608*11304SJanie.Lu@Sun.COM break; 2609*11304SJanie.Lu@Sun.COM case IPTUN_PKT_GTP: 2610*11304SJanie.Lu@Sun.COM pid = 17; 2611*11304SJanie.Lu@Sun.COM break; 2612*11304SJanie.Lu@Sun.COM default: 2613*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 2614*11304SJanie.Lu@Sun.COM "nxge_iptun_pkt_type_to_pid: Unknown pkt type 0x%x", 2615*11304SJanie.Lu@Sun.COM pkt_type)); 2616*11304SJanie.Lu@Sun.COM break; 2617*11304SJanie.Lu@Sun.COM } 2618*11304SJanie.Lu@Sun.COM 2619*11304SJanie.Lu@Sun.COM return (pid); 2620*11304SJanie.Lu@Sun.COM } 2621*11304SJanie.Lu@Sun.COM 2622*11304SJanie.Lu@Sun.COM static npi_status_t 2623*11304SJanie.Lu@Sun.COM nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep, uint64_t class, 2624*11304SJanie.Lu@Sun.COM iptun_cfg_t *iptunp) 2625*11304SJanie.Lu@Sun.COM { 2626*11304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle; 2627*11304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS; 2628*11304SJanie.Lu@Sun.COM 2629*11304SJanie.Lu@Sun.COM switch (iptunp->in_pkt_type) { 2630*11304SJanie.Lu@Sun.COM case IPTUN_PKT_IPV4: 2631*11304SJanie.Lu@Sun.COM case IPTUN_PKT_IPV6: 2632*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 2633*11304SJanie.Lu@Sun.COM (tcam_class_t)class, 0, 0, 0, 0); 2634*11304SJanie.Lu@Sun.COM break; 2635*11304SJanie.Lu@Sun.COM case IPTUN_PKT_GRE: 2636*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 2637*11304SJanie.Lu@Sun.COM (tcam_class_t)class, iptunp->l4b0_val, 2638*11304SJanie.Lu@Sun.COM iptunp->l4b0_mask, 0, 0); 2639*11304SJanie.Lu@Sun.COM break; 2640*11304SJanie.Lu@Sun.COM case IPTUN_PKT_GTP: 2641*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 2642*11304SJanie.Lu@Sun.COM (tcam_class_t)class, 0, 0, iptunp->l4b23_val, 2643*11304SJanie.Lu@Sun.COM (iptunp->l4b23_sel & 0x01)); 2644*11304SJanie.Lu@Sun.COM break; 2645*11304SJanie.Lu@Sun.COM default: 2646*11304SJanie.Lu@Sun.COM rs = NPI_FFLP_TCAM_CLASS_INVALID; 2647*11304SJanie.Lu@Sun.COM break; 2648*11304SJanie.Lu@Sun.COM } 2649*11304SJanie.Lu@Sun.COM return (rs); 2650*11304SJanie.Lu@Sun.COM } 2651*11304SJanie.Lu@Sun.COM 2652*11304SJanie.Lu@Sun.COM void 2653*11304SJanie.Lu@Sun.COM nxge_add_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, 2654*11304SJanie.Lu@Sun.COM uint8_t *cls_idp) 2655*11304SJanie.Lu@Sun.COM { 2656*11304SJanie.Lu@Sun.COM int i, add_cls; 2657*11304SJanie.Lu@Sun.COM uint8_t pid; 2658*11304SJanie.Lu@Sun.COM uint64_t class; 2659*11304SJanie.Lu@Sun.COM p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 2660*11304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle; 2661*11304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS; 2662*11304SJanie.Lu@Sun.COM 2663*11304SJanie.Lu@Sun.COM pid = nxge_iptun_pkt_type_to_pid(iptunp->in_pkt_type); 2664*11304SJanie.Lu@Sun.COM if (pid == 0) 2665*11304SJanie.Lu@Sun.COM return; 2666*11304SJanie.Lu@Sun.COM 2667*11304SJanie.Lu@Sun.COM add_cls = 0; 2668*11304SJanie.Lu@Sun.COM MUTEX_ENTER(&hw_p->nxge_tcam_lock); 2669*11304SJanie.Lu@Sun.COM 2670*11304SJanie.Lu@Sun.COM /* Get an user programmable class ID */ 2671*11304SJanie.Lu@Sun.COM for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 2672*11304SJanie.Lu@Sun.COM if (hw_p->tcam_l3_prog_cls[i].valid == 0) { 2673*11304SJanie.Lu@Sun.COM /* todo add new usr class reg */ 2674*11304SJanie.Lu@Sun.COM switch (i) { 2675*11304SJanie.Lu@Sun.COM case 0: 2676*11304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_4; 2677*11304SJanie.Lu@Sun.COM break; 2678*11304SJanie.Lu@Sun.COM case 1: 2679*11304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_5; 2680*11304SJanie.Lu@Sun.COM break; 2681*11304SJanie.Lu@Sun.COM case 2: 2682*11304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_6; 2683*11304SJanie.Lu@Sun.COM break; 2684*11304SJanie.Lu@Sun.COM case 3: 2685*11304SJanie.Lu@Sun.COM class = TCAM_CLASS_IP_USER_7; 2686*11304SJanie.Lu@Sun.COM break; 2687*11304SJanie.Lu@Sun.COM default: 2688*11304SJanie.Lu@Sun.COM break; 2689*11304SJanie.Lu@Sun.COM } 2690*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_set(handle, 2691*11304SJanie.Lu@Sun.COM (tcam_class_t)class, 0, 0, pid, 0); 2692*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2693*11304SJanie.Lu@Sun.COM goto fail; 2694*11304SJanie.Lu@Sun.COM 2695*11304SJanie.Lu@Sun.COM rs = nxge_set_iptun_usr_cls_reg(nxgep, class, iptunp); 2696*11304SJanie.Lu@Sun.COM 2697*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2698*11304SJanie.Lu@Sun.COM goto fail; 2699*11304SJanie.Lu@Sun.COM 2700*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 2701*11304SJanie.Lu@Sun.COM (tcam_class_t)class); 2702*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2703*11304SJanie.Lu@Sun.COM goto fail; 2704*11304SJanie.Lu@Sun.COM 2705*11304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].cls = class; 2706*11304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].pid = pid; 2707*11304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 2708*11304SJanie.Lu@Sun.COM iptunp->in_pkt_type; 2709*11304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].valid = 1; 2710*11304SJanie.Lu@Sun.COM *cls_idp = (uint8_t)class; 2711*11304SJanie.Lu@Sun.COM add_cls = 1; 2712*11304SJanie.Lu@Sun.COM break; 2713*11304SJanie.Lu@Sun.COM } else if (hw_p->tcam_l3_prog_cls[i].pid == pid) { 2714*11304SJanie.Lu@Sun.COM if (hw_p->tcam_l3_prog_cls[i].flow_pkt_type == 0) { 2715*11304SJanie.Lu@Sun.COM /* there is no flow key */ 2716*11304SJanie.Lu@Sun.COM /* todo program the existing usr class reg */ 2717*11304SJanie.Lu@Sun.COM 2718*11304SJanie.Lu@Sun.COM rs = nxge_set_iptun_usr_cls_reg(nxgep, class, 2719*11304SJanie.Lu@Sun.COM iptunp); 2720*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2721*11304SJanie.Lu@Sun.COM goto fail; 2722*11304SJanie.Lu@Sun.COM 2723*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 2724*11304SJanie.Lu@Sun.COM (tcam_class_t)class); 2725*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2726*11304SJanie.Lu@Sun.COM goto fail; 2727*11304SJanie.Lu@Sun.COM 2728*11304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 2729*11304SJanie.Lu@Sun.COM iptunp->in_pkt_type; 2730*11304SJanie.Lu@Sun.COM *cls_idp = (uint8_t)class; 2731*11304SJanie.Lu@Sun.COM add_cls = 1; 2732*11304SJanie.Lu@Sun.COM } else { 2733*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2734*11304SJanie.Lu@Sun.COM "nxge_add_iptun_class: L3 usr " 2735*11304SJanie.Lu@Sun.COM "programmable class with pid %d " 2736*11304SJanie.Lu@Sun.COM "already exists", pid)); 2737*11304SJanie.Lu@Sun.COM } 2738*11304SJanie.Lu@Sun.COM break; 2739*11304SJanie.Lu@Sun.COM } 2740*11304SJanie.Lu@Sun.COM } 2741*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2742*11304SJanie.Lu@Sun.COM 2743*11304SJanie.Lu@Sun.COM if (add_cls != 1) { 2744*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2745*11304SJanie.Lu@Sun.COM "nxge_add_iptun_class: Could not add IP tunneling class")); 2746*11304SJanie.Lu@Sun.COM } 2747*11304SJanie.Lu@Sun.COM return; 2748*11304SJanie.Lu@Sun.COM fail: 2749*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2750*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_iptun_class: FAILED")); 2751*11304SJanie.Lu@Sun.COM } 2752*11304SJanie.Lu@Sun.COM 2753*11304SJanie.Lu@Sun.COM static boolean_t 2754*11304SJanie.Lu@Sun.COM nxge_is_iptun_cls_present(p_nxge_t nxgep, uint8_t cls_id, int *idx) 2755*11304SJanie.Lu@Sun.COM { 2756*11304SJanie.Lu@Sun.COM int i; 2757*11304SJanie.Lu@Sun.COM p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 2758*11304SJanie.Lu@Sun.COM 2759*11304SJanie.Lu@Sun.COM MUTEX_ENTER(&hw_p->nxge_tcam_lock); 2760*11304SJanie.Lu@Sun.COM for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 2761*11304SJanie.Lu@Sun.COM if (hw_p->tcam_l3_prog_cls[i].valid && 2762*11304SJanie.Lu@Sun.COM hw_p->tcam_l3_prog_cls[i].flow_pkt_type != 0) { 2763*11304SJanie.Lu@Sun.COM if (hw_p->tcam_l3_prog_cls[i].cls == cls_id) 2764*11304SJanie.Lu@Sun.COM break; 2765*11304SJanie.Lu@Sun.COM } 2766*11304SJanie.Lu@Sun.COM } 2767*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2768*11304SJanie.Lu@Sun.COM 2769*11304SJanie.Lu@Sun.COM if (i == NXGE_L3_PROG_CLS) { 2770*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2771*11304SJanie.Lu@Sun.COM "nxge_is_iptun_cls_present: Invalid class %d", cls_id)); 2772*11304SJanie.Lu@Sun.COM return (B_FALSE); 2773*11304SJanie.Lu@Sun.COM } else { 2774*11304SJanie.Lu@Sun.COM *idx = i; 2775*11304SJanie.Lu@Sun.COM return (B_TRUE); 2776*11304SJanie.Lu@Sun.COM } 2777*11304SJanie.Lu@Sun.COM } 2778*11304SJanie.Lu@Sun.COM 2779*11304SJanie.Lu@Sun.COM void 2780*11304SJanie.Lu@Sun.COM nxge_cfg_iptun_hash(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id) 2781*11304SJanie.Lu@Sun.COM { 2782*11304SJanie.Lu@Sun.COM int idx; 2783*11304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle; 2784*11304SJanie.Lu@Sun.COM flow_key_cfg_t cfg; 2785*11304SJanie.Lu@Sun.COM 2786*11304SJanie.Lu@Sun.COM /* check to see that this is a valid class ID */ 2787*11304SJanie.Lu@Sun.COM if (!nxge_is_iptun_cls_present(nxgep, cls_id, &idx)) { 2788*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2789*11304SJanie.Lu@Sun.COM "nxge_cfg_iptun_hash: nxge_is_iptun_cls_present " 2790*11304SJanie.Lu@Sun.COM "failed for cls_id %d", cls_id)); 2791*11304SJanie.Lu@Sun.COM return; 2792*11304SJanie.Lu@Sun.COM } 2793*11304SJanie.Lu@Sun.COM 2794*11304SJanie.Lu@Sun.COM bzero((void *)&cfg, sizeof (flow_key_cfg_t)); 2795*11304SJanie.Lu@Sun.COM 2796*11304SJanie.Lu@Sun.COM /* 2797*11304SJanie.Lu@Sun.COM * This ensures that all 4 bytes of the XOR value are loaded to the 2798*11304SJanie.Lu@Sun.COM * hash key. 2799*11304SJanie.Lu@Sun.COM */ 2800*11304SJanie.Lu@Sun.COM cfg.use_dport = cfg.use_sport = cfg.ip_opts_exist = 1; 2801*11304SJanie.Lu@Sun.COM 2802*11304SJanie.Lu@Sun.COM cfg.l4_xor_sel = (iptunp->l4xor_sel & FL_KEY_USR_L4XOR_MSK); 2803*11304SJanie.Lu@Sun.COM cfg.use_l4_md = 1; 2804*11304SJanie.Lu@Sun.COM 2805*11304SJanie.Lu@Sun.COM if (iptunp->hash_flags & HASH_L3PROTO) 2806*11304SJanie.Lu@Sun.COM cfg.use_proto = 1; 2807*11304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_IPDA) 2808*11304SJanie.Lu@Sun.COM cfg.use_daddr = 1; 2809*11304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_IPSA) 2810*11304SJanie.Lu@Sun.COM cfg.use_saddr = 1; 2811*11304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_VLAN) 2812*11304SJanie.Lu@Sun.COM cfg.use_vlan = 1; 2813*11304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_L2DA) 2814*11304SJanie.Lu@Sun.COM cfg.use_l2da = 1; 2815*11304SJanie.Lu@Sun.COM else if (iptunp->hash_flags & HASH_IFPORT) 2816*11304SJanie.Lu@Sun.COM cfg.use_portnum = 1; 2817*11304SJanie.Lu@Sun.COM 2818*11304SJanie.Lu@Sun.COM (void) npi_fflp_cfg_ip_cls_flow_key_rfnl(handle, (tcam_class_t)cls_id, 2819*11304SJanie.Lu@Sun.COM &cfg); 2820*11304SJanie.Lu@Sun.COM } 2821*11304SJanie.Lu@Sun.COM 2822*11304SJanie.Lu@Sun.COM void 2823*11304SJanie.Lu@Sun.COM nxge_del_iptun_class(p_nxge_t nxgep, uint8_t cls_id) 2824*11304SJanie.Lu@Sun.COM { 2825*11304SJanie.Lu@Sun.COM int i; 2826*11304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle; 2827*11304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS; 2828*11304SJanie.Lu@Sun.COM 2829*11304SJanie.Lu@Sun.COM 2830*11304SJanie.Lu@Sun.COM /* check to see that this is a valid class ID */ 2831*11304SJanie.Lu@Sun.COM if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) { 2832*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2833*11304SJanie.Lu@Sun.COM "nxge_del_iptun_class: Invalid class ID 0x%x", cls_id)); 2834*11304SJanie.Lu@Sun.COM return; 2835*11304SJanie.Lu@Sun.COM } 2836*11304SJanie.Lu@Sun.COM 2837*11304SJanie.Lu@Sun.COM MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2838*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_disable(handle, (tcam_class_t)cls_id); 2839*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2840*11304SJanie.Lu@Sun.COM goto fail; 2841*11304SJanie.Lu@Sun.COM nxgep->nxge_hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 0; 2842*11304SJanie.Lu@Sun.COM if (nxgep->nxge_hw_p->tcam_l3_prog_cls[i].tcam_ref_cnt == 0) 2843*11304SJanie.Lu@Sun.COM nxgep->nxge_hw_p->tcam_l3_prog_cls[i].valid = 0; 2844*11304SJanie.Lu@Sun.COM 2845*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2846*11304SJanie.Lu@Sun.COM return; 2847*11304SJanie.Lu@Sun.COM fail: 2848*11304SJanie.Lu@Sun.COM MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2849*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_iptun_class: FAILED")); 2850*11304SJanie.Lu@Sun.COM } 2851*11304SJanie.Lu@Sun.COM 2852*11304SJanie.Lu@Sun.COM void 2853*11304SJanie.Lu@Sun.COM nxge_get_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id) 2854*11304SJanie.Lu@Sun.COM { 2855*11304SJanie.Lu@Sun.COM int i; 2856*11304SJanie.Lu@Sun.COM uint8_t pid; 2857*11304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle; 2858*11304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS; 2859*11304SJanie.Lu@Sun.COM flow_key_cfg_t cfg; 2860*11304SJanie.Lu@Sun.COM 2861*11304SJanie.Lu@Sun.COM 2862*11304SJanie.Lu@Sun.COM /* check to see that this is a valid class ID */ 2863*11304SJanie.Lu@Sun.COM if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) 2864*11304SJanie.Lu@Sun.COM return; 2865*11304SJanie.Lu@Sun.COM 2866*11304SJanie.Lu@Sun.COM bzero((void *)iptunp, sizeof (iptun_cfg_t)); 2867*11304SJanie.Lu@Sun.COM 2868*11304SJanie.Lu@Sun.COM pid = nxgep->nxge_hw_p->tcam_l3_prog_cls[i].pid; 2869*11304SJanie.Lu@Sun.COM 2870*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_usr_cls_get_iptun(handle, (tcam_class_t)cls_id, 2871*11304SJanie.Lu@Sun.COM &iptunp->l4b0_val, &iptunp->l4b0_mask, &iptunp->l4b23_val, 2872*11304SJanie.Lu@Sun.COM &iptunp->l4b23_sel); 2873*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2874*11304SJanie.Lu@Sun.COM goto fail; 2875*11304SJanie.Lu@Sun.COM 2876*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle, 2877*11304SJanie.Lu@Sun.COM (tcam_class_t)cls_id, &cfg); 2878*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2879*11304SJanie.Lu@Sun.COM goto fail; 2880*11304SJanie.Lu@Sun.COM 2881*11304SJanie.Lu@Sun.COM iptunp->l4xor_sel = cfg.l4_xor_sel; 2882*11304SJanie.Lu@Sun.COM if (cfg.use_proto) 2883*11304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_L3PROTO; 2884*11304SJanie.Lu@Sun.COM else if (cfg.use_daddr) 2885*11304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_IPDA; 2886*11304SJanie.Lu@Sun.COM else if (cfg.use_saddr) 2887*11304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_IPSA; 2888*11304SJanie.Lu@Sun.COM else if (cfg.use_vlan) 2889*11304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_VLAN; 2890*11304SJanie.Lu@Sun.COM else if (cfg.use_l2da) 2891*11304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_L2DA; 2892*11304SJanie.Lu@Sun.COM else if (cfg.use_portnum) 2893*11304SJanie.Lu@Sun.COM iptunp->hash_flags |= HASH_IFPORT; 2894*11304SJanie.Lu@Sun.COM 2895*11304SJanie.Lu@Sun.COM switch (pid) { 2896*11304SJanie.Lu@Sun.COM case 4: 2897*11304SJanie.Lu@Sun.COM iptunp->in_pkt_type = IPTUN_PKT_IPV4; 2898*11304SJanie.Lu@Sun.COM break; 2899*11304SJanie.Lu@Sun.COM case 41: 2900*11304SJanie.Lu@Sun.COM iptunp->in_pkt_type = IPTUN_PKT_IPV6; 2901*11304SJanie.Lu@Sun.COM break; 2902*11304SJanie.Lu@Sun.COM case 47: 2903*11304SJanie.Lu@Sun.COM iptunp->in_pkt_type = IPTUN_PKT_GRE; 2904*11304SJanie.Lu@Sun.COM break; 2905*11304SJanie.Lu@Sun.COM case 17: 2906*11304SJanie.Lu@Sun.COM iptunp->in_pkt_type = IPTUN_PKT_GTP; 2907*11304SJanie.Lu@Sun.COM break; 2908*11304SJanie.Lu@Sun.COM default: 2909*11304SJanie.Lu@Sun.COM iptunp->in_pkt_type = 0; 2910*11304SJanie.Lu@Sun.COM break; 2911*11304SJanie.Lu@Sun.COM } 2912*11304SJanie.Lu@Sun.COM 2913*11304SJanie.Lu@Sun.COM return; 2914*11304SJanie.Lu@Sun.COM fail: 2915*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_iptun_class: FAILED")); 2916*11304SJanie.Lu@Sun.COM } 2917*11304SJanie.Lu@Sun.COM 2918*11304SJanie.Lu@Sun.COM void 2919*11304SJanie.Lu@Sun.COM nxge_set_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t sym) 2920*11304SJanie.Lu@Sun.COM { 2921*11304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle; 2922*11304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS; 2923*11304SJanie.Lu@Sun.COM boolean_t sym_en = (sym == 1) ? B_TRUE : B_FALSE; 2924*11304SJanie.Lu@Sun.COM 2925*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_sym_ip_cls_flow_key(handle, (tcam_class_t)cls_id, 2926*11304SJanie.Lu@Sun.COM sym_en); 2927*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2928*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2929*11304SJanie.Lu@Sun.COM "nxge_set_ip_cls_sym: FAILED")); 2930*11304SJanie.Lu@Sun.COM } 2931*11304SJanie.Lu@Sun.COM 2932*11304SJanie.Lu@Sun.COM void 2933*11304SJanie.Lu@Sun.COM nxge_get_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t *sym) 2934*11304SJanie.Lu@Sun.COM { 2935*11304SJanie.Lu@Sun.COM npi_handle_t handle = nxgep->npi_reg_handle; 2936*11304SJanie.Lu@Sun.COM npi_status_t rs = NPI_SUCCESS; 2937*11304SJanie.Lu@Sun.COM flow_key_cfg_t cfg; 2938*11304SJanie.Lu@Sun.COM 2939*11304SJanie.Lu@Sun.COM rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle, 2940*11304SJanie.Lu@Sun.COM (tcam_class_t)cls_id, &cfg); 2941*11304SJanie.Lu@Sun.COM if (rs != NPI_SUCCESS) 2942*11304SJanie.Lu@Sun.COM goto fail; 2943*11304SJanie.Lu@Sun.COM 2944*11304SJanie.Lu@Sun.COM if (cfg.use_sym) 2945*11304SJanie.Lu@Sun.COM *sym = 1; 2946*11304SJanie.Lu@Sun.COM else 2947*11304SJanie.Lu@Sun.COM *sym = 0; 2948*11304SJanie.Lu@Sun.COM return; 2949*11304SJanie.Lu@Sun.COM fail: 2950*11304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_ip_cls_sym: FAILED")); 2951*11304SJanie.Lu@Sun.COM } 2952