16f45ec7bSml29623 /* 26f45ec7bSml29623 * CDDL HEADER START 36f45ec7bSml29623 * 46f45ec7bSml29623 * The contents of this file are subject to the terms of the 56f45ec7bSml29623 * Common Development and Distribution License (the "License"). 66f45ec7bSml29623 * You may not use this file except in compliance with the License. 76f45ec7bSml29623 * 86f45ec7bSml29623 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96f45ec7bSml29623 * or http://www.opensolaris.org/os/licensing. 106f45ec7bSml29623 * See the License for the specific language governing permissions 116f45ec7bSml29623 * and limitations under the License. 126f45ec7bSml29623 * 136f45ec7bSml29623 * When distributing Covered Code, include this CDDL HEADER in each 146f45ec7bSml29623 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156f45ec7bSml29623 * If applicable, add the following below this CDDL HEADER, with the 166f45ec7bSml29623 * fields enclosed by brackets "[]" replaced with your own identifying 176f45ec7bSml29623 * information: Portions Copyright [yyyy] [name of copyright owner] 186f45ec7bSml29623 * 196f45ec7bSml29623 * CDDL HEADER END 206f45ec7bSml29623 */ 21*0dc2366fSVenugopal Iyer 226f45ec7bSml29623 /* 23*0dc2366fSVenugopal Iyer * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 246f45ec7bSml29623 * Use is subject to license terms. 256f45ec7bSml29623 */ 266f45ec7bSml29623 276f45ec7bSml29623 #include <npi_fflp.h> 286f45ec7bSml29623 #include <npi_mac.h> 296f45ec7bSml29623 #include <nxge_defs.h> 306f45ec7bSml29623 #include <nxge_flow.h> 316f45ec7bSml29623 #include <nxge_fflp.h> 326f45ec7bSml29623 #include <nxge_impl.h> 336f45ec7bSml29623 #include <nxge_fflp_hash.h> 346f45ec7bSml29623 #include <nxge_common.h> 356f45ec7bSml29623 366f45ec7bSml29623 376f45ec7bSml29623 /* 386f45ec7bSml29623 * Function prototypes 396f45ec7bSml29623 */ 406f45ec7bSml29623 static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t); 416f45ec7bSml29623 static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t); 426f45ec7bSml29623 static nxge_status_t nxge_fflp_tcam_init(p_nxge_t); 436f45ec7bSml29623 static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t); 446f45ec7bSml29623 static nxge_status_t nxge_fflp_fcram_init(p_nxge_t); 456f45ec7bSml29623 static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *); 466f45ec7bSml29623 static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 476f45ec7bSml29623 static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 486f45ec7bSml29623 static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 496f45ec7bSml29623 static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *, 506f45ec7bSml29623 tcam_entry_t *); 516f45ec7bSml29623 static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *, 526f45ec7bSml29623 tcam_entry_t *); 536f45ec7bSml29623 static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *, 546f45ec7bSml29623 tcam_entry_t *); 554df55fdeSJanie Lu static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t); 564df55fdeSJanie Lu static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t); 574df55fdeSJanie Lu static uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t); 584df55fdeSJanie Lu static uint32_t nxge_tcam_cls_to_flow(uint32_t); 594df55fdeSJanie Lu static uint8_t nxge_iptun_pkt_type_to_pid(uint8_t); 604df55fdeSJanie Lu static npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t, 614df55fdeSJanie Lu iptun_cfg_t *); 624df55fdeSJanie Lu static boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *); 636f45ec7bSml29623 646f45ec7bSml29623 /* 656f45ec7bSml29623 * functions used outside this file 666f45ec7bSml29623 */ 676f45ec7bSml29623 nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t); 686f45ec7bSml29623 nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t); 696f45ec7bSml29623 nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *); 706f45ec7bSml29623 static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t); 716f45ec7bSml29623 nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *); 726f45ec7bSml29623 nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *); 736f45ec7bSml29623 nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *, 746f45ec7bSml29623 uint32_t *, uint16_t *); 754df55fdeSJanie Lu int nxge_get_valid_tcam_cnt(p_nxge_t); 764df55fdeSJanie Lu void nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *); 774df55fdeSJanie Lu void nxge_get_tcam_entry(p_nxge_t, flow_resource_t *); 784df55fdeSJanie Lu void nxge_del_tcam_entry(p_nxge_t, uint32_t); 794df55fdeSJanie Lu void nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *); 804df55fdeSJanie Lu void nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t); 814df55fdeSJanie Lu void nxge_del_iptun_class(p_nxge_t, uint8_t); 824df55fdeSJanie Lu void nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t); 834df55fdeSJanie Lu void nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t); 844df55fdeSJanie Lu void nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *); 854df55fdeSJanie Lu 866f45ec7bSml29623 876f45ec7bSml29623 nxge_status_t 886f45ec7bSml29623 nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location) 896f45ec7bSml29623 { 906f45ec7bSml29623 tcam_entry_t tcam_rdptr; 916f45ec7bSml29623 uint64_t asc_ram = 0; 926f45ec7bSml29623 npi_handle_t handle; 936f45ec7bSml29623 npi_status_t status; 946f45ec7bSml29623 956f45ec7bSml29623 handle = nxgep->npi_reg_handle; 966f45ec7bSml29623 976f45ec7bSml29623 bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry)); 986f45ec7bSml29623 status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location, 996f45ec7bSml29623 (struct tcam_entry *)&tcam_rdptr); 1006f45ec7bSml29623 if (status & NPI_FAILURE) { 1016f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1026f45ec7bSml29623 " nxge_tcam_dump_entry:" 1036f45ec7bSml29623 " tcam read failed at location %d ", location)); 1046f45ec7bSml29623 return (NXGE_ERROR); 1056f45ec7bSml29623 } 1066f45ec7bSml29623 status = npi_fflp_tcam_asc_ram_entry_read(handle, 1076f45ec7bSml29623 (tcam_location_t)location, &asc_ram); 1086f45ec7bSml29623 1096f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n" 1106f45ec7bSml29623 " key: %llx %llx %llx %llx \n" 1116f45ec7bSml29623 " mask: %llx %llx %llx %llx \n" 1126f45ec7bSml29623 " ASC RAM %llx \n", location, 1136f45ec7bSml29623 tcam_rdptr.key0, tcam_rdptr.key1, 1146f45ec7bSml29623 tcam_rdptr.key2, tcam_rdptr.key3, 1156f45ec7bSml29623 tcam_rdptr.mask0, tcam_rdptr.mask1, 1166f45ec7bSml29623 tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram)); 1176f45ec7bSml29623 return (NXGE_OK); 1186f45ec7bSml29623 } 1196f45ec7bSml29623 1206f45ec7bSml29623 void 1216f45ec7bSml29623 nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp) 1226f45ec7bSml29623 { 1236f45ec7bSml29623 uint32_t tcam_loc; 1246f45ec7bSml29623 int *lptr; 1256f45ec7bSml29623 int location; 1266f45ec7bSml29623 1276f45ec7bSml29623 uint32_t start_location = 0; 1286f45ec7bSml29623 uint32_t stop_location = nxgep->classifier.tcam_size; 1296f45ec7bSml29623 lptr = (int *)mp->b_rptr; 1306f45ec7bSml29623 location = *lptr; 1316f45ec7bSml29623 1326f45ec7bSml29623 if ((location >= nxgep->classifier.tcam_size) || (location < -1)) { 1336f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1346f45ec7bSml29623 "nxge_tcam_dump: Invalid location %d \n", location)); 1356f45ec7bSml29623 return; 1366f45ec7bSml29623 } 1376f45ec7bSml29623 if (location == -1) { 1386f45ec7bSml29623 start_location = 0; 1396f45ec7bSml29623 stop_location = nxgep->classifier.tcam_size; 1406f45ec7bSml29623 } else { 1416f45ec7bSml29623 start_location = location; 1426f45ec7bSml29623 stop_location = location + 1; 1436f45ec7bSml29623 } 1446f45ec7bSml29623 for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++) 1456f45ec7bSml29623 (void) nxge_tcam_dump_entry(nxgep, tcam_loc); 1466f45ec7bSml29623 } 1476f45ec7bSml29623 1486f45ec7bSml29623 /* 1496f45ec7bSml29623 * nxge_fflp_vlan_table_invalidate_all 1506f45ec7bSml29623 * invalidates the vlan RDC table entries. 1516f45ec7bSml29623 * INPUT 1526f45ec7bSml29623 * nxge soft state data structure 1536f45ec7bSml29623 * Return 1546f45ec7bSml29623 * NXGE_OK 1556f45ec7bSml29623 * NXGE_ERROR 1566f45ec7bSml29623 * 1576f45ec7bSml29623 */ 1586f45ec7bSml29623 1596f45ec7bSml29623 static nxge_status_t 1606f45ec7bSml29623 nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep) 1616f45ec7bSml29623 { 1626f45ec7bSml29623 vlan_id_t vlan_id; 1636f45ec7bSml29623 npi_handle_t handle; 1646f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 1656f45ec7bSml29623 vlan_id_t start = 0, stop = NXGE_MAX_VLANS; 1666f45ec7bSml29623 1676f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all ")); 1686f45ec7bSml29623 handle = nxgep->npi_reg_handle; 1696f45ec7bSml29623 for (vlan_id = start; vlan_id < stop; vlan_id++) { 1706f45ec7bSml29623 rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id); 1716f45ec7bSml29623 if (rs != NPI_SUCCESS) { 1726f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1736f45ec7bSml29623 "VLAN Table invalidate failed for vlan id %d ", 1746f45ec7bSml29623 vlan_id)); 1756f45ec7bSml29623 return (NXGE_ERROR | rs); 1766f45ec7bSml29623 } 1776f45ec7bSml29623 } 1786f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all ")); 1796f45ec7bSml29623 return (NXGE_OK); 1806f45ec7bSml29623 } 1816f45ec7bSml29623 1826f45ec7bSml29623 /* 1836f45ec7bSml29623 * The following functions are used by other modules to init 1846f45ec7bSml29623 * the fflp module. 1856f45ec7bSml29623 * these functions are the basic API used to init 1866f45ec7bSml29623 * the fflp modules (tcam, fcram etc ......) 1876f45ec7bSml29623 * 1886f45ec7bSml29623 * The TCAM search future would be disabled by default. 1896f45ec7bSml29623 */ 1906f45ec7bSml29623 1916f45ec7bSml29623 static nxge_status_t 1926f45ec7bSml29623 nxge_fflp_tcam_init(p_nxge_t nxgep) 1936f45ec7bSml29623 { 1946f45ec7bSml29623 uint8_t access_ratio; 1956f45ec7bSml29623 tcam_class_t class; 1966f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 1976f45ec7bSml29623 npi_handle_t handle; 1986f45ec7bSml29623 1996f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init")); 2006f45ec7bSml29623 handle = nxgep->npi_reg_handle; 2016f45ec7bSml29623 2026f45ec7bSml29623 rs = npi_fflp_cfg_tcam_disable(handle); 2036f45ec7bSml29623 if (rs != NPI_SUCCESS) { 2046f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n")); 2056f45ec7bSml29623 return (NXGE_ERROR | rs); 2066f45ec7bSml29623 } 2076f45ec7bSml29623 2086f45ec7bSml29623 access_ratio = nxgep->param_arr[param_tcam_access_ratio].value; 2096f45ec7bSml29623 rs = npi_fflp_cfg_tcam_access(handle, access_ratio); 2106f45ec7bSml29623 if (rs != NPI_SUCCESS) { 2116f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2126f45ec7bSml29623 "failed TCAM Access cfg\n")); 2136f45ec7bSml29623 return (NXGE_ERROR | rs); 2146f45ec7bSml29623 } 2156f45ec7bSml29623 2166f45ec7bSml29623 /* disable configurable classes */ 2176f45ec7bSml29623 /* disable the configurable ethernet classes; */ 2186f45ec7bSml29623 for (class = TCAM_CLASS_ETYPE_1; 2196f45ec7bSml29623 class <= TCAM_CLASS_ETYPE_2; class++) { 2206f45ec7bSml29623 rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class); 2216f45ec7bSml29623 if (rs != NPI_SUCCESS) { 2226f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2236f45ec7bSml29623 "TCAM USR Ether Class config failed.")); 2246f45ec7bSml29623 return (NXGE_ERROR | rs); 2256f45ec7bSml29623 } 2266f45ec7bSml29623 } 2276f45ec7bSml29623 2286f45ec7bSml29623 /* disable the configurable ip classes; */ 2296f45ec7bSml29623 for (class = TCAM_CLASS_IP_USER_4; 2306f45ec7bSml29623 class <= TCAM_CLASS_IP_USER_7; class++) { 2316f45ec7bSml29623 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 2326f45ec7bSml29623 if (rs != NPI_SUCCESS) { 2336f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2346f45ec7bSml29623 "TCAM USR IP Class cnfg failed.")); 2356f45ec7bSml29623 return (NXGE_ERROR | rs); 2366f45ec7bSml29623 } 2376f45ec7bSml29623 } 2386f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init")); 2396f45ec7bSml29623 return (NXGE_OK); 2406f45ec7bSml29623 } 2416f45ec7bSml29623 2426f45ec7bSml29623 /* 2436f45ec7bSml29623 * nxge_fflp_tcam_invalidate_all 2446f45ec7bSml29623 * invalidates all the tcam entries. 2456f45ec7bSml29623 * INPUT 2466f45ec7bSml29623 * nxge soft state data structure 2476f45ec7bSml29623 * Return 2486f45ec7bSml29623 * NXGE_OK 2496f45ec7bSml29623 * NXGE_ERROR 2506f45ec7bSml29623 * 2516f45ec7bSml29623 */ 2526f45ec7bSml29623 2536f45ec7bSml29623 2546f45ec7bSml29623 static nxge_status_t 2556f45ec7bSml29623 nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep) 2566f45ec7bSml29623 { 2576f45ec7bSml29623 uint16_t location; 2586f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 2596f45ec7bSml29623 npi_handle_t handle; 2606f45ec7bSml29623 uint16_t start = 0, stop = nxgep->classifier.tcam_size; 2616f45ec7bSml29623 p_nxge_hw_list_t hw_p; 2626f45ec7bSml29623 2636f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2646f45ec7bSml29623 "==> nxge_fflp_tcam_invalidate_all")); 2656f45ec7bSml29623 handle = nxgep->npi_reg_handle; 2666f45ec7bSml29623 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 2676f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2686f45ec7bSml29623 " nxge_fflp_tcam_invalidate_all:" 2696f45ec7bSml29623 " common hardware not set", nxgep->niu_type)); 2706f45ec7bSml29623 return (NXGE_ERROR); 2716f45ec7bSml29623 } 2726f45ec7bSml29623 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 2736f45ec7bSml29623 for (location = start; location < stop; location++) { 2746f45ec7bSml29623 rs = npi_fflp_tcam_entry_invalidate(handle, location); 2756f45ec7bSml29623 if (rs != NPI_SUCCESS) { 2766f45ec7bSml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2776f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2786f45ec7bSml29623 "TCAM invalidate failed at loc %d ", location)); 2796f45ec7bSml29623 return (NXGE_ERROR | rs); 2806f45ec7bSml29623 } 2816f45ec7bSml29623 } 2826f45ec7bSml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2836f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2846f45ec7bSml29623 "<== nxge_fflp_tcam_invalidate_all")); 2856f45ec7bSml29623 return (NXGE_OK); 2866f45ec7bSml29623 } 2876f45ec7bSml29623 2886f45ec7bSml29623 /* 2896f45ec7bSml29623 * nxge_fflp_fcram_entry_invalidate_all 2906f45ec7bSml29623 * invalidates all the FCRAM entries. 2916f45ec7bSml29623 * INPUT 2926f45ec7bSml29623 * nxge soft state data structure 2936f45ec7bSml29623 * Return 2946f45ec7bSml29623 * NXGE_OK 2956f45ec7bSml29623 * NXGE_ERROR 2966f45ec7bSml29623 * 2976f45ec7bSml29623 */ 2986f45ec7bSml29623 2996f45ec7bSml29623 static nxge_status_t 3006f45ec7bSml29623 nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep) 3016f45ec7bSml29623 { 3026f45ec7bSml29623 npi_handle_t handle; 3036f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 3046f45ec7bSml29623 part_id_t pid = 0; 3056f45ec7bSml29623 uint8_t base_mask, base_reloc; 3066f45ec7bSml29623 fcram_entry_t fc; 3076f45ec7bSml29623 uint32_t location; 3086f45ec7bSml29623 uint32_t increment, last_location; 3096f45ec7bSml29623 3106f45ec7bSml29623 /* 3116f45ec7bSml29623 * (1) configure and enable partition 0 with no relocation 3126f45ec7bSml29623 * (2) Assume the FCRAM is used as IPv4 exact match entry cells 3136f45ec7bSml29623 * (3) Invalidate these cells by clearing the valid bit in 3146f45ec7bSml29623 * the subareas 0 and 4 3156f45ec7bSml29623 * (4) disable the partition 3166f45ec7bSml29623 * 3176f45ec7bSml29623 */ 3186f45ec7bSml29623 3196f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all")); 3206f45ec7bSml29623 3216f45ec7bSml29623 base_mask = base_reloc = 0x0; 3226f45ec7bSml29623 handle = nxgep->npi_reg_handle; 3236f45ec7bSml29623 rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc); 3246f45ec7bSml29623 3256f45ec7bSml29623 if (rs != NPI_SUCCESS) { 3266f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n")); 3276f45ec7bSml29623 return (NXGE_ERROR | rs); 3286f45ec7bSml29623 } 3296f45ec7bSml29623 rs = npi_fflp_cfg_fcram_partition_disable(handle, pid); 3306f45ec7bSml29623 3316f45ec7bSml29623 if (rs != NPI_SUCCESS) { 3326f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3336f45ec7bSml29623 "failed partition enable\n")); 3346f45ec7bSml29623 return (NXGE_ERROR | rs); 3356f45ec7bSml29623 } 3366f45ec7bSml29623 fc.dreg[0].value = 0; 3376f45ec7bSml29623 fc.hash_hdr_valid = 0; 3386f45ec7bSml29623 fc.hash_hdr_ext = 1; /* specify as IPV4 exact match entry */ 3396f45ec7bSml29623 increment = sizeof (hash_ipv4_t); 3406f45ec7bSml29623 last_location = FCRAM_SIZE * 0x40; 3416f45ec7bSml29623 3426f45ec7bSml29623 for (location = 0; location < last_location; location += increment) { 3436f45ec7bSml29623 rs = npi_fflp_fcram_subarea_write(handle, pid, 34452ccf843Smisaki location, fc.value[0]); 3456f45ec7bSml29623 if (rs != NPI_SUCCESS) { 3466f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 34752ccf843Smisaki "failed write at location %x ", location)); 3486f45ec7bSml29623 return (NXGE_ERROR | rs); 3496f45ec7bSml29623 } 3506f45ec7bSml29623 } 3516f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all")); 3526f45ec7bSml29623 return (NXGE_OK); 3536f45ec7bSml29623 } 3546f45ec7bSml29623 3556f45ec7bSml29623 static nxge_status_t 3566f45ec7bSml29623 nxge_fflp_fcram_init(p_nxge_t nxgep) 3576f45ec7bSml29623 { 3586f45ec7bSml29623 fflp_fcram_output_drive_t strength; 3596f45ec7bSml29623 fflp_fcram_qs_t qs; 3606f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 3616f45ec7bSml29623 uint8_t access_ratio; 3626f45ec7bSml29623 int partition; 3636f45ec7bSml29623 npi_handle_t handle; 3646f45ec7bSml29623 uint32_t min_time, max_time, sys_time; 3656f45ec7bSml29623 3666f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init")); 3676f45ec7bSml29623 3686f45ec7bSml29623 /* 3696f45ec7bSml29623 * Recommended values are needed. 3706f45ec7bSml29623 */ 3716f45ec7bSml29623 min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME; 3726f45ec7bSml29623 max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME; 3736f45ec7bSml29623 sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME; 3746f45ec7bSml29623 3756f45ec7bSml29623 handle = nxgep->npi_reg_handle; 3766f45ec7bSml29623 strength = FCRAM_OUTDR_NORMAL; 3776f45ec7bSml29623 qs = FCRAM_QS_MODE_QS; 3786f45ec7bSml29623 rs = npi_fflp_cfg_fcram_reset(handle, strength, qs); 3796f45ec7bSml29623 if (rs != NPI_SUCCESS) { 3806f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. ")); 3816f45ec7bSml29623 return (NXGE_ERROR | rs); 3826f45ec7bSml29623 } 3836f45ec7bSml29623 3846f45ec7bSml29623 access_ratio = nxgep->param_arr[param_fcram_access_ratio].value; 3856f45ec7bSml29623 rs = npi_fflp_cfg_fcram_access(handle, access_ratio); 3866f45ec7bSml29623 if (rs != NPI_SUCCESS) { 3876f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio" 3886f45ec7bSml29623 "configuration \n")); 3896f45ec7bSml29623 return (NXGE_ERROR | rs); 3906f45ec7bSml29623 } 3916f45ec7bSml29623 rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time, 3926f45ec7bSml29623 max_time, sys_time); 3936f45ec7bSml29623 if (rs != NPI_SUCCESS) { 3946f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3956f45ec7bSml29623 "failed FCRAM refresh cfg")); 3966f45ec7bSml29623 return (NXGE_ERROR); 3976f45ec7bSml29623 } 3986f45ec7bSml29623 3996f45ec7bSml29623 /* disable all the partitions until explicitly enabled */ 4006f45ec7bSml29623 for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) { 4016f45ec7bSml29623 rs = npi_fflp_cfg_fcram_partition_disable(handle, partition); 4026f45ec7bSml29623 if (rs != NPI_SUCCESS) { 4036f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4046f45ec7bSml29623 "failed FCRAM partition" 4056f45ec7bSml29623 " enable for partition %d ", partition)); 4066f45ec7bSml29623 return (NXGE_ERROR | rs); 4076f45ec7bSml29623 } 4086f45ec7bSml29623 } 4096f45ec7bSml29623 4106f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init")); 4116f45ec7bSml29623 return (NXGE_OK); 4126f45ec7bSml29623 } 4136f45ec7bSml29623 4146f45ec7bSml29623 nxge_status_t 4156f45ec7bSml29623 nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac) 4166f45ec7bSml29623 { 4176f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 4186f45ec7bSml29623 hostinfo_t mac_rdc; 4196f45ec7bSml29623 npi_handle_t handle; 4206f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 4216f45ec7bSml29623 4226f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 4236f45ec7bSml29623 if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) { 4246f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4256f45ec7bSml29623 " nxge_logical_mac_assign_rdc_table" 4266f45ec7bSml29623 " unconfigured alt MAC addr %d ", alt_mac)); 4276f45ec7bSml29623 return (NXGE_ERROR); 4286f45ec7bSml29623 } 4296f45ec7bSml29623 handle = nxgep->npi_reg_handle; 4306f45ec7bSml29623 mac_rdc.value = 0; 4316f45ec7bSml29623 mac_rdc.bits.w0.rdc_tbl_num = 4326f45ec7bSml29623 p_class_cfgp->mac_host_info[alt_mac].rdctbl; 4336f45ec7bSml29623 mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr; 4346f45ec7bSml29623 4356f45ec7bSml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET, 4366f45ec7bSml29623 nxgep->function_num, alt_mac, &mac_rdc); 4376f45ec7bSml29623 4386f45ec7bSml29623 if (rs != NPI_SUCCESS) { 4396f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4406f45ec7bSml29623 "failed Assign RDC table")); 4416f45ec7bSml29623 return (NXGE_ERROR | rs); 4426f45ec7bSml29623 } 4436f45ec7bSml29623 return (NXGE_OK); 4446f45ec7bSml29623 } 4456f45ec7bSml29623 4466f45ec7bSml29623 nxge_status_t 4476f45ec7bSml29623 nxge_main_mac_assign_rdc_table(p_nxge_t nxgep) 4486f45ec7bSml29623 { 4496f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 4506f45ec7bSml29623 hostinfo_t mac_rdc; 4516f45ec7bSml29623 npi_handle_t handle; 452*0dc2366fSVenugopal Iyer int i; 4536f45ec7bSml29623 4546f45ec7bSml29623 handle = nxgep->npi_reg_handle; 4556f45ec7bSml29623 mac_rdc.value = 0; 4566f45ec7bSml29623 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp; 4576f45ec7bSml29623 mac_rdc.bits.w0.mac_pref = 1; 4586f45ec7bSml29623 switch (nxgep->function_num) { 4596f45ec7bSml29623 case 0: 4606f45ec7bSml29623 case 1: 461*0dc2366fSVenugopal Iyer /* 462*0dc2366fSVenugopal Iyer * Tests indicate that it is OK not to re-initialize the 463*0dc2366fSVenugopal Iyer * hostinfo registers for the XMAC's alternate MAC 464*0dc2366fSVenugopal Iyer * addresses. But that is necessary for BMAC (case 2 465*0dc2366fSVenugopal Iyer * and case 3 below) 466*0dc2366fSVenugopal Iyer */ 4676f45ec7bSml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET, 46852ccf843Smisaki nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 4696f45ec7bSml29623 break; 4706f45ec7bSml29623 case 2: 4716f45ec7bSml29623 case 3: 4726f45ec7bSml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET, 47352ccf843Smisaki nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 474*0dc2366fSVenugopal Iyer for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++) 475*0dc2366fSVenugopal Iyer rs |= npi_mac_hostinfo_entry(handle, OP_SET, 476*0dc2366fSVenugopal Iyer nxgep->function_num, i, &mac_rdc); 4776f45ec7bSml29623 break; 4786f45ec7bSml29623 default: 4796f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4806f45ec7bSml29623 "failed Assign RDC table (invalid function #)")); 4816f45ec7bSml29623 return (NXGE_ERROR); 4826f45ec7bSml29623 } 4836f45ec7bSml29623 4846f45ec7bSml29623 if (rs != NPI_SUCCESS) { 4856f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4866f45ec7bSml29623 "failed Assign RDC table")); 4876f45ec7bSml29623 return (NXGE_ERROR | rs); 4886f45ec7bSml29623 } 4896f45ec7bSml29623 return (NXGE_OK); 4906f45ec7bSml29623 } 4916f45ec7bSml29623 4926f45ec7bSml29623 /* 4936f45ec7bSml29623 * Initialize hostinfo registers for alternate MAC addresses and 4946f45ec7bSml29623 * multicast MAC address. 4956f45ec7bSml29623 */ 4966f45ec7bSml29623 nxge_status_t 4976f45ec7bSml29623 nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep) 4986f45ec7bSml29623 { 4996f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 5006f45ec7bSml29623 hostinfo_t mac_rdc; 5016f45ec7bSml29623 npi_handle_t handle; 5026f45ec7bSml29623 5036f45ec7bSml29623 handle = nxgep->npi_reg_handle; 5046f45ec7bSml29623 mac_rdc.value = 0; 5056f45ec7bSml29623 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp; 5066f45ec7bSml29623 mac_rdc.bits.w0.mac_pref = 1; 5076f45ec7bSml29623 switch (nxgep->function_num) { 5086f45ec7bSml29623 case 0: 5096f45ec7bSml29623 case 1: 5106f45ec7bSml29623 rs = npi_mac_hostinfo_entry(handle, OP_SET, 511*0dc2366fSVenugopal Iyer nxgep->function_num, XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 5126f45ec7bSml29623 break; 5136f45ec7bSml29623 case 2: 5146f45ec7bSml29623 case 3: 515*0dc2366fSVenugopal Iyer rs = npi_mac_hostinfo_entry(handle, OP_SET, 516*0dc2366fSVenugopal Iyer nxgep->function_num, BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 5176f45ec7bSml29623 break; 5186f45ec7bSml29623 default: 5196f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 520f6485eecSyc148097 "failed Assign RDC table (invalid function #)")); 5216f45ec7bSml29623 return (NXGE_ERROR); 5226f45ec7bSml29623 } 5236f45ec7bSml29623 5246f45ec7bSml29623 if (rs != NPI_SUCCESS) { 5256f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5266f45ec7bSml29623 "failed Assign RDC table")); 5276f45ec7bSml29623 return (NXGE_ERROR | rs); 5286f45ec7bSml29623 } 5296f45ec7bSml29623 return (NXGE_OK); 5306f45ec7bSml29623 } 5316f45ec7bSml29623 5326f45ec7bSml29623 nxge_status_t 5336f45ec7bSml29623 nxge_fflp_init_hostinfo(p_nxge_t nxgep) 5346f45ec7bSml29623 { 5356f45ec7bSml29623 nxge_status_t status = NXGE_OK; 5366f45ec7bSml29623 5376f45ec7bSml29623 status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 5386f45ec7bSml29623 status |= nxge_main_mac_assign_rdc_table(nxgep); 5396f45ec7bSml29623 return (status); 5406f45ec7bSml29623 } 5416f45ec7bSml29623 5426f45ec7bSml29623 nxge_status_t 5436f45ec7bSml29623 nxge_fflp_hw_reset(p_nxge_t nxgep) 5446f45ec7bSml29623 { 5456f45ec7bSml29623 npi_handle_t handle; 5466f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 5476f45ec7bSml29623 nxge_status_t status = NXGE_OK; 5486f45ec7bSml29623 5496f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset")); 5506f45ec7bSml29623 5512e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 5526f45ec7bSml29623 status = nxge_fflp_fcram_init(nxgep); 5536f45ec7bSml29623 if (status != NXGE_OK) { 5546f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5556f45ec7bSml29623 " failed FCRAM init. ")); 5566f45ec7bSml29623 return (status); 5576f45ec7bSml29623 } 5586f45ec7bSml29623 } 5596f45ec7bSml29623 5606f45ec7bSml29623 status = nxge_fflp_tcam_init(nxgep); 5616f45ec7bSml29623 if (status != NXGE_OK) { 5626f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5636f45ec7bSml29623 "failed TCAM init.")); 5646f45ec7bSml29623 return (status); 5656f45ec7bSml29623 } 5666f45ec7bSml29623 5676f45ec7bSml29623 handle = nxgep->npi_reg_handle; 5686f45ec7bSml29623 rs = npi_fflp_cfg_llcsnap_enable(handle); 5696f45ec7bSml29623 if (rs != NPI_SUCCESS) { 5706f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5716f45ec7bSml29623 "failed LLCSNAP enable. ")); 5726f45ec7bSml29623 return (NXGE_ERROR | rs); 5736f45ec7bSml29623 } 5746f45ec7bSml29623 5756f45ec7bSml29623 rs = npi_fflp_cfg_cam_errorcheck_disable(handle); 5766f45ec7bSml29623 if (rs != NPI_SUCCESS) { 5776f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5786f45ec7bSml29623 "failed CAM Error Check enable. ")); 5796f45ec7bSml29623 return (NXGE_ERROR | rs); 5806f45ec7bSml29623 } 5816f45ec7bSml29623 5826f45ec7bSml29623 /* init the hash generators */ 5836f45ec7bSml29623 rs = npi_fflp_cfg_hash_h1poly(handle, 0); 5846f45ec7bSml29623 if (rs != NPI_SUCCESS) { 5856f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5866f45ec7bSml29623 "failed H1 Poly Init. ")); 5876f45ec7bSml29623 return (NXGE_ERROR | rs); 5886f45ec7bSml29623 } 5896f45ec7bSml29623 5906f45ec7bSml29623 rs = npi_fflp_cfg_hash_h2poly(handle, 0); 5916f45ec7bSml29623 if (rs != NPI_SUCCESS) { 5926f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5936f45ec7bSml29623 "failed H2 Poly Init. ")); 5946f45ec7bSml29623 return (NXGE_ERROR | rs); 5956f45ec7bSml29623 } 5966f45ec7bSml29623 5976f45ec7bSml29623 /* invalidate TCAM entries */ 5986f45ec7bSml29623 status = nxge_fflp_tcam_invalidate_all(nxgep); 5996f45ec7bSml29623 if (status != NXGE_OK) { 6006f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6016f45ec7bSml29623 "failed TCAM Entry Invalidate. ")); 6026f45ec7bSml29623 return (status); 6036f45ec7bSml29623 } 6046f45ec7bSml29623 6056f45ec7bSml29623 /* invalidate FCRAM entries */ 6062e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 6076f45ec7bSml29623 status = nxge_fflp_fcram_invalidate_all(nxgep); 6086f45ec7bSml29623 if (status != NXGE_OK) { 6096f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6106f45ec7bSml29623 "failed FCRAM Entry Invalidate.")); 6116f45ec7bSml29623 return (status); 6126f45ec7bSml29623 } 6136f45ec7bSml29623 } 6146f45ec7bSml29623 6156f45ec7bSml29623 /* invalidate VLAN RDC tables */ 6166f45ec7bSml29623 status = nxge_fflp_vlan_tbl_clear_all(nxgep); 6176f45ec7bSml29623 if (status != NXGE_OK) { 6186f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6196f45ec7bSml29623 "failed VLAN Table Invalidate. ")); 6206f45ec7bSml29623 return (status); 6216f45ec7bSml29623 } 6226f45ec7bSml29623 nxgep->classifier.state |= NXGE_FFLP_HW_RESET; 6236f45ec7bSml29623 6246f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset")); 6256f45ec7bSml29623 return (NXGE_OK); 6266f45ec7bSml29623 } 6276f45ec7bSml29623 6286f45ec7bSml29623 nxge_status_t 6296f45ec7bSml29623 nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class, 6306f45ec7bSml29623 uint32_t class_config) 6316f45ec7bSml29623 { 6326f45ec7bSml29623 flow_key_cfg_t fcfg; 6336f45ec7bSml29623 npi_handle_t handle; 6346f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 6356f45ec7bSml29623 6366f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key")); 6376f45ec7bSml29623 handle = nxgep->npi_reg_handle; 6386f45ec7bSml29623 bzero(&fcfg, sizeof (flow_key_cfg_t)); 6396f45ec7bSml29623 6406f45ec7bSml29623 if (class_config & NXGE_CLASS_FLOW_USE_PROTO) 6416f45ec7bSml29623 fcfg.use_proto = 1; 6426f45ec7bSml29623 if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT) 6436f45ec7bSml29623 fcfg.use_dport = 1; 6446f45ec7bSml29623 if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT) 6456f45ec7bSml29623 fcfg.use_sport = 1; 6466f45ec7bSml29623 if (class_config & NXGE_CLASS_FLOW_USE_IPDST) 6476f45ec7bSml29623 fcfg.use_daddr = 1; 6486f45ec7bSml29623 if (class_config & NXGE_CLASS_FLOW_USE_IPSRC) 6496f45ec7bSml29623 fcfg.use_saddr = 1; 6506f45ec7bSml29623 if (class_config & NXGE_CLASS_FLOW_USE_VLAN) 6516f45ec7bSml29623 fcfg.use_vlan = 1; 6526f45ec7bSml29623 if (class_config & NXGE_CLASS_FLOW_USE_L2DA) 6536f45ec7bSml29623 fcfg.use_l2da = 1; 6546f45ec7bSml29623 if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM) 6556f45ec7bSml29623 fcfg.use_portnum = 1; 6566f45ec7bSml29623 fcfg.ip_opts_exist = 0; 6576f45ec7bSml29623 6586f45ec7bSml29623 rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg); 6596f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 6606f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 66152ccf843Smisaki " opt %x for class %d failed ", class_config, l3_class)); 6626f45ec7bSml29623 return (NXGE_ERROR | rs); 6636f45ec7bSml29623 } 6646f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key")); 6656f45ec7bSml29623 return (NXGE_OK); 6666f45ec7bSml29623 } 6676f45ec7bSml29623 6686f45ec7bSml29623 nxge_status_t 6696f45ec7bSml29623 nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class, 6706f45ec7bSml29623 uint32_t *class_config) 6716f45ec7bSml29623 { 6726f45ec7bSml29623 flow_key_cfg_t fcfg; 6736f45ec7bSml29623 npi_handle_t handle; 6746f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 6756f45ec7bSml29623 uint32_t ccfg = 0; 6766f45ec7bSml29623 6776f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get")); 6786f45ec7bSml29623 handle = nxgep->npi_reg_handle; 6796f45ec7bSml29623 bzero(&fcfg, sizeof (flow_key_cfg_t)); 6806f45ec7bSml29623 6816f45ec7bSml29623 rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg); 6826f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 6836f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 68452ccf843Smisaki " opt %x for class %d failed ", class_config, l3_class)); 6856f45ec7bSml29623 return (NXGE_ERROR | rs); 6866f45ec7bSml29623 } 6876f45ec7bSml29623 6886f45ec7bSml29623 if (fcfg.use_proto) 6896f45ec7bSml29623 ccfg |= NXGE_CLASS_FLOW_USE_PROTO; 6906f45ec7bSml29623 if (fcfg.use_dport) 6916f45ec7bSml29623 ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT; 6926f45ec7bSml29623 if (fcfg.use_sport) 6936f45ec7bSml29623 ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT; 6946f45ec7bSml29623 if (fcfg.use_daddr) 6956f45ec7bSml29623 ccfg |= NXGE_CLASS_FLOW_USE_IPDST; 6966f45ec7bSml29623 if (fcfg.use_saddr) 6976f45ec7bSml29623 ccfg |= NXGE_CLASS_FLOW_USE_IPSRC; 6986f45ec7bSml29623 if (fcfg.use_vlan) 6996f45ec7bSml29623 ccfg |= NXGE_CLASS_FLOW_USE_VLAN; 7006f45ec7bSml29623 if (fcfg.use_l2da) 7016f45ec7bSml29623 ccfg |= NXGE_CLASS_FLOW_USE_L2DA; 7026f45ec7bSml29623 if (fcfg.use_portnum) 7036f45ec7bSml29623 ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM; 7046f45ec7bSml29623 7056f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 7066f45ec7bSml29623 " nxge_cfg_ip_cls_flow_key_get %x", ccfg)); 7076f45ec7bSml29623 *class_config = ccfg; 7086f45ec7bSml29623 7096f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 7106f45ec7bSml29623 " <== nxge_cfg_ip_cls_flow_key_get")); 7116f45ec7bSml29623 return (NXGE_OK); 7126f45ec7bSml29623 } 7136f45ec7bSml29623 7146f45ec7bSml29623 static nxge_status_t 7156f45ec7bSml29623 nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class, 7166f45ec7bSml29623 uint32_t *class_config) 7176f45ec7bSml29623 { 7186f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 7196f45ec7bSml29623 tcam_key_cfg_t cfg; 7206f45ec7bSml29623 npi_handle_t handle; 7216f45ec7bSml29623 uint32_t ccfg = 0; 7226f45ec7bSml29623 7236f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 7246f45ec7bSml29623 7256f45ec7bSml29623 bzero(&cfg, sizeof (tcam_key_cfg_t)); 7266f45ec7bSml29623 handle = nxgep->npi_reg_handle; 7276f45ec7bSml29623 7286f45ec7bSml29623 rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg); 7296f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 7306f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 73152ccf843Smisaki " opt %x for class %d failed ", class_config, class)); 7326f45ec7bSml29623 return (NXGE_ERROR | rs); 7336f45ec7bSml29623 } 7346f45ec7bSml29623 if (cfg.discard) 7356f45ec7bSml29623 ccfg |= NXGE_CLASS_DISCARD; 7366f45ec7bSml29623 if (cfg.lookup_enable) 7376f45ec7bSml29623 ccfg |= NXGE_CLASS_TCAM_LOOKUP; 7386f45ec7bSml29623 if (cfg.use_ip_daddr) 7396f45ec7bSml29623 ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR; 7406f45ec7bSml29623 *class_config = ccfg; 7416f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 7426f45ec7bSml29623 " ==> nxge_cfg_tcam_ip_class %x", ccfg)); 7436f45ec7bSml29623 return (NXGE_OK); 7446f45ec7bSml29623 } 7456f45ec7bSml29623 7466f45ec7bSml29623 static nxge_status_t 7476f45ec7bSml29623 nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class, 7486f45ec7bSml29623 uint32_t class_config) 7496f45ec7bSml29623 { 7506f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 7516f45ec7bSml29623 tcam_key_cfg_t cfg; 7526f45ec7bSml29623 npi_handle_t handle; 7536f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 7546f45ec7bSml29623 7556f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 7566f45ec7bSml29623 7576f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 7586f45ec7bSml29623 p_class_cfgp->class_cfg[class] = class_config; 7596f45ec7bSml29623 7606f45ec7bSml29623 bzero(&cfg, sizeof (tcam_key_cfg_t)); 7616f45ec7bSml29623 handle = nxgep->npi_reg_handle; 7626f45ec7bSml29623 cfg.discard = 0; 7636f45ec7bSml29623 cfg.lookup_enable = 0; 7646f45ec7bSml29623 cfg.use_ip_daddr = 0; 7656f45ec7bSml29623 if (class_config & NXGE_CLASS_DISCARD) 7666f45ec7bSml29623 cfg.discard = 1; 7676f45ec7bSml29623 if (class_config & NXGE_CLASS_TCAM_LOOKUP) 7686f45ec7bSml29623 cfg.lookup_enable = 1; 7696f45ec7bSml29623 if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR) 7706f45ec7bSml29623 cfg.use_ip_daddr = 1; 7716f45ec7bSml29623 7726f45ec7bSml29623 rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg); 7736f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 7746f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 77552ccf843Smisaki " opt %x for class %d failed ", class_config, class)); 7766f45ec7bSml29623 return (NXGE_ERROR | rs); 7776f45ec7bSml29623 } 7786f45ec7bSml29623 return (NXGE_OK); 7796f45ec7bSml29623 } 7806f45ec7bSml29623 7816f45ec7bSml29623 nxge_status_t 7826f45ec7bSml29623 nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1) 7836f45ec7bSml29623 { 7846f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 7856f45ec7bSml29623 npi_handle_t handle; 7866f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 7876f45ec7bSml29623 7886f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1")); 7896f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 7906f45ec7bSml29623 p_class_cfgp->init_h1 = h1; 7916f45ec7bSml29623 handle = nxgep->npi_reg_handle; 7926f45ec7bSml29623 rs = npi_fflp_cfg_hash_h1poly(handle, h1); 7936f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 7946f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 7956f45ec7bSml29623 " nxge_fflp_init_h1 %x failed ", h1)); 7966f45ec7bSml29623 return (NXGE_ERROR | rs); 7976f45ec7bSml29623 } 7986f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1")); 7996f45ec7bSml29623 return (NXGE_OK); 8006f45ec7bSml29623 } 8016f45ec7bSml29623 8026f45ec7bSml29623 nxge_status_t 8036f45ec7bSml29623 nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2) 8046f45ec7bSml29623 { 8056f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 8066f45ec7bSml29623 npi_handle_t handle; 8076f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 8086f45ec7bSml29623 8096f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2")); 8106f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 8116f45ec7bSml29623 p_class_cfgp->init_h2 = h2; 8126f45ec7bSml29623 8136f45ec7bSml29623 handle = nxgep->npi_reg_handle; 8146f45ec7bSml29623 rs = npi_fflp_cfg_hash_h2poly(handle, h2); 8156f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 8166f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8176f45ec7bSml29623 " nxge_fflp_init_h2 %x failed ", h2)); 8186f45ec7bSml29623 return (NXGE_ERROR | rs); 8196f45ec7bSml29623 } 8206f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2")); 8216f45ec7bSml29623 return (NXGE_OK); 8226f45ec7bSml29623 } 8236f45ec7bSml29623 8246f45ec7bSml29623 nxge_status_t 8256f45ec7bSml29623 nxge_classify_init_sw(p_nxge_t nxgep) 8266f45ec7bSml29623 { 8276f45ec7bSml29623 nxge_classify_t *classify_ptr; 8286f45ec7bSml29623 8296f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw")); 8306f45ec7bSml29623 classify_ptr = &nxgep->classifier; 8316f45ec7bSml29623 8326f45ec7bSml29623 if (classify_ptr->state & NXGE_FFLP_SW_INIT) { 8336f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 8346f45ec7bSml29623 "nxge_classify_init_sw already init")); 8356f45ec7bSml29623 return (NXGE_OK); 8366f45ec7bSml29623 } 8376f45ec7bSml29623 8384df55fdeSJanie Lu classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports; 8394df55fdeSJanie Lu classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam; 8404df55fdeSJanie Lu classify_ptr->tcam_top = nxgep->function_num; 8416f45ec7bSml29623 8426f45ec7bSml29623 /* Init defaults */ 8436f45ec7bSml29623 /* 8446f45ec7bSml29623 * add hacks required for HW shortcomings for example, code to handle 8456f45ec7bSml29623 * fragmented packets 8466f45ec7bSml29623 */ 8476f45ec7bSml29623 nxge_init_h1_table(); 8486f45ec7bSml29623 nxge_crc_ccitt_init(); 8496f45ec7bSml29623 nxgep->classifier.tcam_location = nxgep->function_num; 8506f45ec7bSml29623 nxgep->classifier.fragment_bug = 1; 8516f45ec7bSml29623 classify_ptr->state |= NXGE_FFLP_SW_INIT; 8526f45ec7bSml29623 8536f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw")); 8546f45ec7bSml29623 return (NXGE_OK); 8556f45ec7bSml29623 } 8566f45ec7bSml29623 8576f45ec7bSml29623 nxge_status_t 8586f45ec7bSml29623 nxge_classify_exit_sw(p_nxge_t nxgep) 8596f45ec7bSml29623 { 8606f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw")); 8616f45ec7bSml29623 nxgep->classifier.state = NULL; 8626f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw")); 8636f45ec7bSml29623 return (NXGE_OK); 8646f45ec7bSml29623 } 8656f45ec7bSml29623 8666f45ec7bSml29623 /* 8676f45ec7bSml29623 * Figures out the RDC Group for the entry 8686f45ec7bSml29623 * 8696f45ec7bSml29623 * The current implementation is just a place holder and it 8706f45ec7bSml29623 * returns 0. 8716f45ec7bSml29623 * The real location determining algorithm would consider 8726f45ec7bSml29623 * the partition etc ... before deciding w 8736f45ec7bSml29623 * 8746f45ec7bSml29623 */ 8756f45ec7bSml29623 8766f45ec7bSml29623 /* ARGSUSED */ 8776f45ec7bSml29623 static uint8_t 8784df55fdeSJanie Lu nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie) 8796f45ec7bSml29623 { 8806f45ec7bSml29623 int use_port_rdc_grp = 0; 8816f45ec7bSml29623 uint8_t rdc_grp = 0; 8826f45ec7bSml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp; 8836f45ec7bSml29623 p_nxge_hw_pt_cfg_t p_cfgp; 8846f45ec7bSml29623 p_nxge_rdc_grp_t rdc_grp_p; 8856f45ec7bSml29623 8866f45ec7bSml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 8876f45ec7bSml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 8886f45ec7bSml29623 rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp]; 889678453a8Sspeer rdc_grp = p_cfgp->def_mac_rxdma_grpid; 8906f45ec7bSml29623 8916f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8926f45ec7bSml29623 "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n", 8936f45ec7bSml29623 cookie, rdc_grp, rdc_grp_p)); 8946f45ec7bSml29623 return (rdc_grp); 8956f45ec7bSml29623 } 8966f45ec7bSml29623 8976f45ec7bSml29623 /* ARGSUSED */ 8986f45ec7bSml29623 static uint8_t 8994df55fdeSJanie Lu nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie) 9006f45ec7bSml29623 { 9016f45ec7bSml29623 return ((uint8_t)cookie); 9026f45ec7bSml29623 } 9036f45ec7bSml29623 9046f45ec7bSml29623 /* ARGSUSED */ 9056f45ec7bSml29623 static void 9066f45ec7bSml29623 nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec, 9076f45ec7bSml29623 tcam_entry_t *tcam_ptr) 9086f45ec7bSml29623 { 9096f45ec7bSml29623 udpip4_spec_t *fspec_key; 9106f45ec7bSml29623 udpip4_spec_t *fspec_mask; 9116f45ec7bSml29623 9126f45ec7bSml29623 fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec; 9136f45ec7bSml29623 fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec; 9146f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 9156f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 9166f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 9176f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 9186f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 9196f45ec7bSml29623 fspec_key->pdst, fspec_key->psrc); 9206f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 9216f45ec7bSml29623 fspec_mask->pdst, fspec_mask->psrc); 9226f45ec7bSml29623 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 9236f45ec7bSml29623 tcam_ptr->ip4_class_mask, 9246f45ec7bSml29623 TCAM_CLASS_UDP_IPV4); 9256f45ec7bSml29623 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 9266f45ec7bSml29623 tcam_ptr->ip4_proto_mask, 9276f45ec7bSml29623 IPPROTO_UDP); 9284df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 9294df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 9306f45ec7bSml29623 } 9316f45ec7bSml29623 9326f45ec7bSml29623 static void 9336f45ec7bSml29623 nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 9346f45ec7bSml29623 tcam_entry_t *tcam_ptr) 9356f45ec7bSml29623 { 9366f45ec7bSml29623 udpip6_spec_t *fspec_key; 9376f45ec7bSml29623 udpip6_spec_t *fspec_mask; 9386f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 9396f45ec7bSml29623 9406f45ec7bSml29623 fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec; 9416f45ec7bSml29623 fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec; 9426f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 9436f45ec7bSml29623 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 9446f45ec7bSml29623 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 9456f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 9466f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 9476f45ec7bSml29623 } else { 9486f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 9496f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 9506f45ec7bSml29623 } 9516f45ec7bSml29623 9526f45ec7bSml29623 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 9536f45ec7bSml29623 tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6); 9546f45ec7bSml29623 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 9556f45ec7bSml29623 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP); 9566f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 9576f45ec7bSml29623 fspec_key->pdst, fspec_key->psrc); 9586f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 9596f45ec7bSml29623 fspec_mask->pdst, fspec_mask->psrc); 9604df55fdeSJanie Lu tcam_ptr->ip6_tos_key = fspec_key->tos; 9614df55fdeSJanie Lu tcam_ptr->ip6_tos_mask = fspec_mask->tos; 9626f45ec7bSml29623 } 9636f45ec7bSml29623 9646f45ec7bSml29623 /* ARGSUSED */ 9656f45ec7bSml29623 static void 9666f45ec7bSml29623 nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec, 9676f45ec7bSml29623 tcam_entry_t *tcam_ptr) 9686f45ec7bSml29623 { 9696f45ec7bSml29623 tcpip4_spec_t *fspec_key; 9706f45ec7bSml29623 tcpip4_spec_t *fspec_mask; 9716f45ec7bSml29623 9726f45ec7bSml29623 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 9736f45ec7bSml29623 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 9746f45ec7bSml29623 9756f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 9766f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 9776f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 9786f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 9796f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 9806f45ec7bSml29623 fspec_key->pdst, fspec_key->psrc); 9816f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 9826f45ec7bSml29623 fspec_mask->pdst, fspec_mask->psrc); 9836f45ec7bSml29623 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 9846f45ec7bSml29623 tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4); 9856f45ec7bSml29623 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 9866f45ec7bSml29623 tcam_ptr->ip4_proto_mask, IPPROTO_TCP); 9874df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 9884df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 9896f45ec7bSml29623 } 9906f45ec7bSml29623 9916f45ec7bSml29623 /* ARGSUSED */ 9926f45ec7bSml29623 static void 9936f45ec7bSml29623 nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec, 9946f45ec7bSml29623 tcam_entry_t *tcam_ptr) 9956f45ec7bSml29623 { 9966f45ec7bSml29623 tcpip4_spec_t *fspec_key; 9976f45ec7bSml29623 tcpip4_spec_t *fspec_mask; 9986f45ec7bSml29623 9996f45ec7bSml29623 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 10006f45ec7bSml29623 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 10016f45ec7bSml29623 10026f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 10036f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 10046f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 10056f45ec7bSml29623 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 10066f45ec7bSml29623 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 10076f45ec7bSml29623 tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4); 10086f45ec7bSml29623 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 10096f45ec7bSml29623 tcam_ptr->ip4_proto_mask, IPPROTO_SCTP); 10106f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 10116f45ec7bSml29623 fspec_key->pdst, fspec_key->psrc); 10126f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 10136f45ec7bSml29623 fspec_mask->pdst, fspec_mask->psrc); 10144df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 10154df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 10166f45ec7bSml29623 } 10176f45ec7bSml29623 10186f45ec7bSml29623 static void 10196f45ec7bSml29623 nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 10206f45ec7bSml29623 tcam_entry_t *tcam_ptr) 10216f45ec7bSml29623 { 10226f45ec7bSml29623 tcpip6_spec_t *fspec_key; 10236f45ec7bSml29623 tcpip6_spec_t *fspec_mask; 10246f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 10256f45ec7bSml29623 10266f45ec7bSml29623 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 10276f45ec7bSml29623 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 10286f45ec7bSml29623 10296f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 10306f45ec7bSml29623 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 10316f45ec7bSml29623 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 10326f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 10336f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 10346f45ec7bSml29623 } else { 10356f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 10366f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 10376f45ec7bSml29623 } 10386f45ec7bSml29623 10396f45ec7bSml29623 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 10406f45ec7bSml29623 tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6); 10416f45ec7bSml29623 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 10426f45ec7bSml29623 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP); 10436f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 10446f45ec7bSml29623 fspec_key->pdst, fspec_key->psrc); 10456f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 10466f45ec7bSml29623 fspec_mask->pdst, fspec_mask->psrc); 10474df55fdeSJanie Lu tcam_ptr->ip6_tos_key = fspec_key->tos; 10484df55fdeSJanie Lu tcam_ptr->ip6_tos_mask = fspec_mask->tos; 10496f45ec7bSml29623 } 10506f45ec7bSml29623 10516f45ec7bSml29623 static void 10526f45ec7bSml29623 nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 10536f45ec7bSml29623 tcam_entry_t *tcam_ptr) 10546f45ec7bSml29623 { 10556f45ec7bSml29623 tcpip6_spec_t *fspec_key; 10566f45ec7bSml29623 tcpip6_spec_t *fspec_mask; 10576f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 10586f45ec7bSml29623 10596f45ec7bSml29623 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 10606f45ec7bSml29623 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 10616f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 10626f45ec7bSml29623 10636f45ec7bSml29623 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 10646f45ec7bSml29623 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 10656f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 10666f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 10676f45ec7bSml29623 } else { 10686f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 10696f45ec7bSml29623 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 10706f45ec7bSml29623 } 10716f45ec7bSml29623 10726f45ec7bSml29623 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 10736f45ec7bSml29623 tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6); 10746f45ec7bSml29623 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 10756f45ec7bSml29623 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP); 10766f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 10776f45ec7bSml29623 fspec_key->pdst, fspec_key->psrc); 10786f45ec7bSml29623 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 10796f45ec7bSml29623 fspec_mask->pdst, fspec_mask->psrc); 10804df55fdeSJanie Lu tcam_ptr->ip6_tos_key = fspec_key->tos; 10814df55fdeSJanie Lu tcam_ptr->ip6_tos_mask = fspec_mask->tos; 10826f45ec7bSml29623 } 10836f45ec7bSml29623 10844df55fdeSJanie Lu /* ARGSUSED */ 10854df55fdeSJanie Lu static void 10864df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec, 10874df55fdeSJanie Lu tcam_entry_t *tcam_ptr) 10884df55fdeSJanie Lu { 10894df55fdeSJanie Lu ahip4_spec_t *fspec_key; 10904df55fdeSJanie Lu ahip4_spec_t *fspec_mask; 10914df55fdeSJanie Lu 10924df55fdeSJanie Lu fspec_key = (ahip4_spec_t *)&flow_spec->uh.ahip4spec; 10934df55fdeSJanie Lu fspec_mask = (ahip4_spec_t *)&flow_spec->um.ahip4spec; 10944df55fdeSJanie Lu 10954df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 10964df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 10974df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 10984df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 10994df55fdeSJanie Lu 11004df55fdeSJanie Lu tcam_ptr->ip4_port_key = fspec_key->spi; 11014df55fdeSJanie Lu tcam_ptr->ip4_port_mask = fspec_mask->spi; 11024df55fdeSJanie Lu 11034df55fdeSJanie Lu TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 11044df55fdeSJanie Lu tcam_ptr->ip4_class_mask, 11054df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV4); 11064df55fdeSJanie Lu 11074df55fdeSJanie Lu if (flow_spec->flow_type == FSPEC_AHIP4) { 11084df55fdeSJanie Lu TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 11094df55fdeSJanie Lu tcam_ptr->ip4_proto_mask, IPPROTO_AH); 11104df55fdeSJanie Lu } else { 11114df55fdeSJanie Lu TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 11124df55fdeSJanie Lu tcam_ptr->ip4_proto_mask, IPPROTO_ESP); 11134df55fdeSJanie Lu } 11144df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 11154df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 11164df55fdeSJanie Lu } 11174df55fdeSJanie Lu 11184df55fdeSJanie Lu static void 11194df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 11204df55fdeSJanie Lu tcam_entry_t *tcam_ptr) 11214df55fdeSJanie Lu { 11224df55fdeSJanie Lu ahip6_spec_t *fspec_key; 11234df55fdeSJanie Lu ahip6_spec_t *fspec_mask; 11244df55fdeSJanie Lu p_nxge_class_pt_cfg_t p_class_cfgp; 11254df55fdeSJanie Lu 11264df55fdeSJanie Lu fspec_key = (ahip6_spec_t *)&flow_spec->uh.ahip6spec; 11274df55fdeSJanie Lu fspec_mask = (ahip6_spec_t *)&flow_spec->um.ahip6spec; 11284df55fdeSJanie Lu 11294df55fdeSJanie Lu p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 11304df55fdeSJanie Lu if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] & 11314df55fdeSJanie Lu NXGE_CLASS_TCAM_USE_SRC_ADDR) { 11324df55fdeSJanie Lu TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 11334df55fdeSJanie Lu TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 11344df55fdeSJanie Lu } else { 11354df55fdeSJanie Lu TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 11364df55fdeSJanie Lu TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 11374df55fdeSJanie Lu } 11384df55fdeSJanie Lu 11394df55fdeSJanie Lu TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 11404df55fdeSJanie Lu tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6); 11414df55fdeSJanie Lu 11424df55fdeSJanie Lu if (flow_spec->flow_type == FSPEC_AHIP6) { 11434df55fdeSJanie Lu TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 11444df55fdeSJanie Lu tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH); 11454df55fdeSJanie Lu } else { 11464df55fdeSJanie Lu TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 11474df55fdeSJanie Lu tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP); 11484df55fdeSJanie Lu } 11494df55fdeSJanie Lu tcam_ptr->ip6_port_key = fspec_key->spi; 11504df55fdeSJanie Lu tcam_ptr->ip6_port_mask = fspec_mask->spi; 11514df55fdeSJanie Lu tcam_ptr->ip6_tos_key = fspec_key->tos; 11524df55fdeSJanie Lu tcam_ptr->ip6_tos_mask = fspec_mask->tos; 11534df55fdeSJanie Lu } 11544df55fdeSJanie Lu 11554df55fdeSJanie Lu /* ARGSUSED */ 11564df55fdeSJanie Lu static void 11574df55fdeSJanie Lu nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec, 11584df55fdeSJanie Lu tcam_entry_t *tcam_ptr, tcam_class_t class) 11594df55fdeSJanie Lu { 11604df55fdeSJanie Lu ip_user_spec_t *fspec_key; 11614df55fdeSJanie Lu ip_user_spec_t *fspec_mask; 11624df55fdeSJanie Lu 11634df55fdeSJanie Lu fspec_key = (ip_user_spec_t *)&flow_spec->uh.ip_usr_spec; 11644df55fdeSJanie Lu fspec_mask = (ip_user_spec_t *)&flow_spec->um.ip_usr_spec; 11654df55fdeSJanie Lu 11664df55fdeSJanie Lu if (fspec_key->ip_ver == FSPEC_IP4) { 11674df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 11684df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 11694df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 11704df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 11714df55fdeSJanie Lu 11724df55fdeSJanie Lu tcam_ptr->ip4_port_key = fspec_key->l4_4_bytes; 11734df55fdeSJanie Lu tcam_ptr->ip4_port_mask = fspec_mask->l4_4_bytes; 11744df55fdeSJanie Lu 11754df55fdeSJanie Lu TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 11764df55fdeSJanie Lu tcam_ptr->ip4_class_mask, class); 11774df55fdeSJanie Lu 11784df55fdeSJanie Lu tcam_ptr->ip4_proto_key = fspec_key->proto; 11794df55fdeSJanie Lu tcam_ptr->ip4_proto_mask = fspec_mask->proto; 11804df55fdeSJanie Lu 11814df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 11824df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 11834df55fdeSJanie Lu } 11844df55fdeSJanie Lu } 11854df55fdeSJanie Lu 11864df55fdeSJanie Lu 11876f45ec7bSml29623 nxge_status_t 11886f45ec7bSml29623 nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res, 11896f45ec7bSml29623 uint32_t *H1, uint16_t *H2) 11906f45ec7bSml29623 { 11916f45ec7bSml29623 flow_spec_t *flow_spec; 11926f45ec7bSml29623 uint32_t class_cfg; 11936f45ec7bSml29623 flow_template_t ft; 11946f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 11956f45ec7bSml29623 11966f45ec7bSml29623 int ft_size = sizeof (flow_template_t); 11976f45ec7bSml29623 11986f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash")); 11996f45ec7bSml29623 12006f45ec7bSml29623 flow_spec = (flow_spec_t *)&flow_res->flow_spec; 12016f45ec7bSml29623 bzero((char *)&ft, ft_size); 12026f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 12036f45ec7bSml29623 12046f45ec7bSml29623 switch (flow_spec->flow_type) { 12056f45ec7bSml29623 case FSPEC_TCPIP4: 12066f45ec7bSml29623 class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4]; 12076f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 12086f45ec7bSml29623 ft.ip_proto = IPPROTO_TCP; 12096f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 12106f45ec7bSml29623 ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src; 12116f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 12126f45ec7bSml29623 ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst; 12136f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 12146f45ec7bSml29623 ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc; 12156f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 12166f45ec7bSml29623 ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst; 12176f45ec7bSml29623 break; 12186f45ec7bSml29623 12196f45ec7bSml29623 case FSPEC_UDPIP4: 12206f45ec7bSml29623 class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4]; 12216f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 12226f45ec7bSml29623 ft.ip_proto = IPPROTO_UDP; 12236f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 12246f45ec7bSml29623 ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src; 12256f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 12266f45ec7bSml29623 ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst; 12276f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 12286f45ec7bSml29623 ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc; 12296f45ec7bSml29623 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 12306f45ec7bSml29623 ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst; 12316f45ec7bSml29623 break; 12326f45ec7bSml29623 12336f45ec7bSml29623 default: 12346f45ec7bSml29623 return (NXGE_ERROR); 12356f45ec7bSml29623 } 12366f45ec7bSml29623 12376f45ec7bSml29623 *H1 = nxge_compute_h1(p_class_cfgp->init_h1, 12386f45ec7bSml29623 (uint32_t *)&ft, ft_size) & 0xfffff; 12396f45ec7bSml29623 *H2 = nxge_compute_h2(p_class_cfgp->init_h2, 12406f45ec7bSml29623 (uint8_t *)&ft, ft_size); 12416f45ec7bSml29623 12426f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash")); 12436f45ec7bSml29623 return (NXGE_OK); 12446f45ec7bSml29623 } 12456f45ec7bSml29623 12466f45ec7bSml29623 nxge_status_t 12476f45ec7bSml29623 nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 12486f45ec7bSml29623 { 12496f45ec7bSml29623 uint32_t H1; 12506f45ec7bSml29623 uint16_t H2; 12516f45ec7bSml29623 nxge_status_t status = NXGE_OK; 12526f45ec7bSml29623 12536f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry")); 12546f45ec7bSml29623 status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2); 12556f45ec7bSml29623 if (status != NXGE_OK) { 12566f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 12576f45ec7bSml29623 " nxge_add_fcram_entry failed ")); 12586f45ec7bSml29623 return (status); 12596f45ec7bSml29623 } 12606f45ec7bSml29623 12616f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry")); 12626f45ec7bSml29623 return (NXGE_OK); 12636f45ec7bSml29623 } 12646f45ec7bSml29623 12656f45ec7bSml29623 /* 12666f45ec7bSml29623 * Already decided this flow goes into the tcam 12676f45ec7bSml29623 */ 12686f45ec7bSml29623 12696f45ec7bSml29623 nxge_status_t 12706f45ec7bSml29623 nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 12716f45ec7bSml29623 { 12726f45ec7bSml29623 npi_handle_t handle; 12734df55fdeSJanie Lu uint64_t channel_cookie; 12744df55fdeSJanie Lu uint64_t flow_cookie; 12756f45ec7bSml29623 flow_spec_t *flow_spec; 12766f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 12776f45ec7bSml29623 tcam_entry_t tcam_ptr; 12784df55fdeSJanie Lu tcam_location_t location; 12796f45ec7bSml29623 uint8_t offset, rdc_grp; 12806f45ec7bSml29623 p_nxge_hw_list_t hw_p; 12814df55fdeSJanie Lu uint64_t class; 12826f45ec7bSml29623 12836f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry")); 12846f45ec7bSml29623 handle = nxgep->npi_reg_handle; 12856f45ec7bSml29623 12866f45ec7bSml29623 bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 12876f45ec7bSml29623 flow_spec = (flow_spec_t *)&flow_res->flow_spec; 12886f45ec7bSml29623 flow_cookie = flow_res->flow_cookie; 12896f45ec7bSml29623 channel_cookie = flow_res->channel_cookie; 12904df55fdeSJanie Lu location = (tcam_location_t)nxge_tcam_get_index(nxgep, 12914df55fdeSJanie Lu (uint16_t)flow_res->location); 12924df55fdeSJanie Lu 12934df55fdeSJanie Lu if ((hw_p = nxgep->nxge_hw_p) == NULL) { 12944df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 12954df55fdeSJanie Lu " nxge_add_tcam_entry: common hardware not set", 12964df55fdeSJanie Lu nxgep->niu_type)); 12974df55fdeSJanie Lu return (NXGE_ERROR); 12984df55fdeSJanie Lu } 12994df55fdeSJanie Lu 13004df55fdeSJanie Lu if (flow_spec->flow_type == FSPEC_IP_USR) { 13014df55fdeSJanie Lu int i; 13024df55fdeSJanie Lu int add_usr_cls = 0; 13034df55fdeSJanie Lu int ipv6 = 0; 13044df55fdeSJanie Lu ip_user_spec_t *uspec = &flow_spec->uh.ip_usr_spec; 13054df55fdeSJanie Lu ip_user_spec_t *umask = &flow_spec->um.ip_usr_spec; 13064df55fdeSJanie Lu nxge_usr_l3_cls_t *l3_ucls_p; 13074df55fdeSJanie Lu 13084df55fdeSJanie Lu MUTEX_ENTER(&hw_p->nxge_tcam_lock); 13094df55fdeSJanie Lu 13104df55fdeSJanie Lu for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 13114df55fdeSJanie Lu l3_ucls_p = &hw_p->tcam_l3_prog_cls[i]; 13124df55fdeSJanie Lu if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) { 13134df55fdeSJanie Lu if (uspec->proto == l3_ucls_p->pid) { 13144df55fdeSJanie Lu class = l3_ucls_p->cls; 13154df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt++; 13164df55fdeSJanie Lu add_usr_cls = 1; 13174df55fdeSJanie Lu break; 13184df55fdeSJanie Lu } 13194df55fdeSJanie Lu } else if (l3_ucls_p->valid == 0) { 13204df55fdeSJanie Lu /* Program new user IP class */ 13214df55fdeSJanie Lu switch (i) { 13224df55fdeSJanie Lu case 0: 13234df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_4; 13244df55fdeSJanie Lu break; 13254df55fdeSJanie Lu case 1: 13264df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_5; 13274df55fdeSJanie Lu break; 13284df55fdeSJanie Lu case 2: 13294df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_6; 13304df55fdeSJanie Lu break; 13314df55fdeSJanie Lu case 3: 13324df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_7; 13334df55fdeSJanie Lu break; 13344df55fdeSJanie Lu default: 13354df55fdeSJanie Lu break; 13364df55fdeSJanie Lu } 13374df55fdeSJanie Lu if (uspec->ip_ver == FSPEC_IP6) 13384df55fdeSJanie Lu ipv6 = 1; 13394df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set(handle, 13404df55fdeSJanie Lu (tcam_class_t)class, uspec->tos, 13414df55fdeSJanie Lu umask->tos, uspec->proto, ipv6); 13424df55fdeSJanie Lu if (rs != NPI_SUCCESS) 13434df55fdeSJanie Lu goto fail; 13444df55fdeSJanie Lu 13454df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 13464df55fdeSJanie Lu (tcam_class_t)class); 13474df55fdeSJanie Lu if (rs != NPI_SUCCESS) 13484df55fdeSJanie Lu goto fail; 13494df55fdeSJanie Lu 13504df55fdeSJanie Lu l3_ucls_p->cls = class; 13514df55fdeSJanie Lu l3_ucls_p->pid = uspec->proto; 13524df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt++; 13534df55fdeSJanie Lu l3_ucls_p->valid = 1; 13544df55fdeSJanie Lu add_usr_cls = 1; 13554df55fdeSJanie Lu break; 13564df55fdeSJanie Lu } else if (l3_ucls_p->tcam_ref_cnt == 0 && 13574df55fdeSJanie Lu uspec->proto == l3_ucls_p->pid) { 13584df55fdeSJanie Lu /* 13594df55fdeSJanie Lu * The class has already been programmed, 13604df55fdeSJanie Lu * probably for flow hash 13614df55fdeSJanie Lu */ 13624df55fdeSJanie Lu class = l3_ucls_p->cls; 13634df55fdeSJanie Lu if (uspec->ip_ver == FSPEC_IP6) 13644df55fdeSJanie Lu ipv6 = 1; 13654df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set(handle, 13664df55fdeSJanie Lu (tcam_class_t)class, uspec->tos, 13674df55fdeSJanie Lu umask->tos, uspec->proto, ipv6); 13684df55fdeSJanie Lu if (rs != NPI_SUCCESS) 13694df55fdeSJanie Lu goto fail; 13704df55fdeSJanie Lu 13714df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 13724df55fdeSJanie Lu (tcam_class_t)class); 13734df55fdeSJanie Lu if (rs != NPI_SUCCESS) 13744df55fdeSJanie Lu goto fail; 13754df55fdeSJanie Lu 13764df55fdeSJanie Lu l3_ucls_p->pid = uspec->proto; 13774df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt++; 13784df55fdeSJanie Lu add_usr_cls = 1; 13794df55fdeSJanie Lu break; 13804df55fdeSJanie Lu } 13814df55fdeSJanie Lu } 13824df55fdeSJanie Lu if (!add_usr_cls) { 13834df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 13844df55fdeSJanie Lu "nxge_add_tcam_entry: Could not find/insert class" 13854df55fdeSJanie Lu "for pid %d", uspec->proto)); 13864df55fdeSJanie Lu goto fail; 13874df55fdeSJanie Lu } 13884df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 13894df55fdeSJanie Lu } 13906f45ec7bSml29623 13916f45ec7bSml29623 switch (flow_spec->flow_type) { 13926f45ec7bSml29623 case FSPEC_TCPIP4: 13936f45ec7bSml29623 nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr); 13946f45ec7bSml29623 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4, 13956f45ec7bSml29623 flow_cookie); 13966f45ec7bSml29623 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4, 13976f45ec7bSml29623 channel_cookie); 13986f45ec7bSml29623 break; 13996f45ec7bSml29623 14006f45ec7bSml29623 case FSPEC_UDPIP4: 14016f45ec7bSml29623 nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr); 14026f45ec7bSml29623 rdc_grp = nxge_get_rdc_group(nxgep, 14036f45ec7bSml29623 TCAM_CLASS_UDP_IPV4, 14046f45ec7bSml29623 flow_cookie); 14056f45ec7bSml29623 offset = nxge_get_rdc_offset(nxgep, 14066f45ec7bSml29623 TCAM_CLASS_UDP_IPV4, 14076f45ec7bSml29623 channel_cookie); 14086f45ec7bSml29623 break; 14096f45ec7bSml29623 14106f45ec7bSml29623 case FSPEC_TCPIP6: 14116f45ec7bSml29623 nxge_fill_tcam_entry_tcp_ipv6(nxgep, 14126f45ec7bSml29623 flow_spec, &tcam_ptr); 14136f45ec7bSml29623 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6, 14146f45ec7bSml29623 flow_cookie); 14156f45ec7bSml29623 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6, 14166f45ec7bSml29623 channel_cookie); 14176f45ec7bSml29623 break; 14186f45ec7bSml29623 14196f45ec7bSml29623 case FSPEC_UDPIP6: 14206f45ec7bSml29623 nxge_fill_tcam_entry_udp_ipv6(nxgep, 14216f45ec7bSml29623 flow_spec, &tcam_ptr); 14226f45ec7bSml29623 rdc_grp = nxge_get_rdc_group(nxgep, 14236f45ec7bSml29623 TCAM_CLASS_UDP_IPV6, 14244df55fdeSJanie Lu flow_cookie); 14256f45ec7bSml29623 offset = nxge_get_rdc_offset(nxgep, 14266f45ec7bSml29623 TCAM_CLASS_UDP_IPV6, 14274df55fdeSJanie Lu channel_cookie); 14286f45ec7bSml29623 break; 14296f45ec7bSml29623 14306f45ec7bSml29623 case FSPEC_SCTPIP4: 14316f45ec7bSml29623 nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr); 14326f45ec7bSml29623 rdc_grp = nxge_get_rdc_group(nxgep, 14336f45ec7bSml29623 TCAM_CLASS_SCTP_IPV4, 14344df55fdeSJanie Lu flow_cookie); 14356f45ec7bSml29623 offset = nxge_get_rdc_offset(nxgep, 14366f45ec7bSml29623 TCAM_CLASS_SCTP_IPV4, 14374df55fdeSJanie Lu channel_cookie); 14386f45ec7bSml29623 break; 14396f45ec7bSml29623 14406f45ec7bSml29623 case FSPEC_SCTPIP6: 14416f45ec7bSml29623 nxge_fill_tcam_entry_sctp_ipv6(nxgep, 14426f45ec7bSml29623 flow_spec, &tcam_ptr); 14436f45ec7bSml29623 rdc_grp = nxge_get_rdc_group(nxgep, 14446f45ec7bSml29623 TCAM_CLASS_SCTP_IPV6, 14454df55fdeSJanie Lu flow_cookie); 14466f45ec7bSml29623 offset = nxge_get_rdc_offset(nxgep, 14476f45ec7bSml29623 TCAM_CLASS_SCTP_IPV6, 14484df55fdeSJanie Lu channel_cookie); 14496f45ec7bSml29623 break; 14506f45ec7bSml29623 14514df55fdeSJanie Lu case FSPEC_AHIP4: 14524df55fdeSJanie Lu case FSPEC_ESPIP4: 14534df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp(nxgep, flow_spec, &tcam_ptr); 14544df55fdeSJanie Lu rdc_grp = nxge_get_rdc_group(nxgep, 14554df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV4, 14564df55fdeSJanie Lu flow_cookie); 14574df55fdeSJanie Lu offset = nxge_get_rdc_offset(nxgep, 14584df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV4, 14594df55fdeSJanie Lu channel_cookie); 14604df55fdeSJanie Lu break; 14614df55fdeSJanie Lu 14624df55fdeSJanie Lu case FSPEC_AHIP6: 14634df55fdeSJanie Lu case FSPEC_ESPIP6: 14644df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp_ipv6(nxgep, 14654df55fdeSJanie Lu flow_spec, &tcam_ptr); 14664df55fdeSJanie Lu rdc_grp = nxge_get_rdc_group(nxgep, 14674df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV6, 14684df55fdeSJanie Lu flow_cookie); 14694df55fdeSJanie Lu offset = nxge_get_rdc_offset(nxgep, 14704df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV6, 14714df55fdeSJanie Lu channel_cookie); 14724df55fdeSJanie Lu break; 14734df55fdeSJanie Lu 14744df55fdeSJanie Lu case FSPEC_IP_USR: 14754df55fdeSJanie Lu nxge_fill_tcam_entry_ip_usr(nxgep, flow_spec, &tcam_ptr, 14764df55fdeSJanie Lu (tcam_class_t)class); 14774df55fdeSJanie Lu rdc_grp = nxge_get_rdc_group(nxgep, 14784df55fdeSJanie Lu (tcam_class_t)class, flow_cookie); 14794df55fdeSJanie Lu offset = nxge_get_rdc_offset(nxgep, 14804df55fdeSJanie Lu (tcam_class_t)class, channel_cookie); 14814df55fdeSJanie Lu break; 14826f45ec7bSml29623 default: 14834df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 14844df55fdeSJanie Lu "nxge_add_tcam_entry: Unknown flow spec 0x%x", 14854df55fdeSJanie Lu flow_spec->flow_type)); 14864df55fdeSJanie Lu return (NXGE_ERROR); 14876f45ec7bSml29623 } 14886f45ec7bSml29623 14896f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 14906f45ec7bSml29623 " nxge_add_tcam_entry write" 14916f45ec7bSml29623 " for location %d offset %d", location, offset)); 14926f45ec7bSml29623 14936f45ec7bSml29623 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 14946f45ec7bSml29623 rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr); 14956f45ec7bSml29623 14966f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 14976f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 14986f45ec7bSml29623 " nxge_add_tcam_entry write" 14996f45ec7bSml29623 " failed for location %d", location)); 15004df55fdeSJanie Lu goto fail; 15016f45ec7bSml29623 } 15026f45ec7bSml29623 15036f45ec7bSml29623 tcam_ptr.match_action.value = 0; 15046f45ec7bSml29623 tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp; 15056f45ec7bSml29623 tcam_ptr.match_action.bits.ldw.offset = offset; 15066f45ec7bSml29623 tcam_ptr.match_action.bits.ldw.tres = 15076f45ec7bSml29623 TRES_TERM_OVRD_L2RDC; 15084df55fdeSJanie Lu if (channel_cookie == NXGE_PKT_DISCARD) 15096f45ec7bSml29623 tcam_ptr.match_action.bits.ldw.disc = 1; 15106f45ec7bSml29623 rs = npi_fflp_tcam_asc_ram_entry_write(handle, 15116f45ec7bSml29623 location, tcam_ptr.match_action.value); 15126f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 15136f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 15146f45ec7bSml29623 " nxge_add_tcam_entry write" 15156f45ec7bSml29623 " failed for ASC RAM location %d", location)); 15164df55fdeSJanie Lu goto fail; 15176f45ec7bSml29623 } 15186f45ec7bSml29623 bcopy((void *) &tcam_ptr, 15196f45ec7bSml29623 (void *) &nxgep->classifier.tcam_entries[location].tce, 15206f45ec7bSml29623 sizeof (tcam_entry_t)); 15214df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt++; 15224df55fdeSJanie Lu nxgep->classifier.tcam_entries[location].valid = 1; 15236f45ec7bSml29623 15246f45ec7bSml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 15256f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry")); 15266f45ec7bSml29623 return (NXGE_OK); 15274df55fdeSJanie Lu fail: 15284df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 15294df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_tcam_entry FAILED")); 15304df55fdeSJanie Lu return (NXGE_ERROR); 15316f45ec7bSml29623 } 15326f45ec7bSml29623 15336f45ec7bSml29623 static nxge_status_t 15346f45ec7bSml29623 nxge_tcam_handle_ip_fragment(p_nxge_t nxgep) 15356f45ec7bSml29623 { 15366f45ec7bSml29623 tcam_entry_t tcam_ptr; 15376f45ec7bSml29623 tcam_location_t location; 15386f45ec7bSml29623 uint8_t class; 15396f45ec7bSml29623 uint32_t class_config; 15406f45ec7bSml29623 npi_handle_t handle; 15416f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 15426f45ec7bSml29623 p_nxge_hw_list_t hw_p; 15436f45ec7bSml29623 nxge_status_t status = NXGE_OK; 15446f45ec7bSml29623 15456f45ec7bSml29623 handle = nxgep->npi_reg_handle; 15466f45ec7bSml29623 class = 0; 15476f45ec7bSml29623 bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 15486f45ec7bSml29623 tcam_ptr.ip4_noport_key = 1; 15496f45ec7bSml29623 tcam_ptr.ip4_noport_mask = 1; 15506f45ec7bSml29623 location = nxgep->function_num; 15516f45ec7bSml29623 nxgep->classifier.fragment_bug_location = location; 15526f45ec7bSml29623 15536f45ec7bSml29623 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 15546f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 155552ccf843Smisaki " nxge_tcam_handle_ip_fragment: common hardware not set", 15566f45ec7bSml29623 nxgep->niu_type)); 15576f45ec7bSml29623 return (NXGE_ERROR); 15586f45ec7bSml29623 } 15596f45ec7bSml29623 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 15606f45ec7bSml29623 rs = npi_fflp_tcam_entry_write(handle, 15616f45ec7bSml29623 location, &tcam_ptr); 15626f45ec7bSml29623 15636f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 15646f45ec7bSml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 15656f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 15666f45ec7bSml29623 " nxge_tcam_handle_ip_fragment " 15676f45ec7bSml29623 " tcam_entry write" 15686f45ec7bSml29623 " failed for location %d", location)); 15696f45ec7bSml29623 return (NXGE_ERROR); 15706f45ec7bSml29623 } 15716f45ec7bSml29623 tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp; 15726f45ec7bSml29623 tcam_ptr.match_action.bits.ldw.offset = 0; /* use the default */ 15736f45ec7bSml29623 tcam_ptr.match_action.bits.ldw.tres = 15746f45ec7bSml29623 TRES_TERM_USE_OFFSET; 15756f45ec7bSml29623 rs = npi_fflp_tcam_asc_ram_entry_write(handle, 15766f45ec7bSml29623 location, tcam_ptr.match_action.value); 15776f45ec7bSml29623 15786f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 15796f45ec7bSml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 15806f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, 15816f45ec7bSml29623 FFLP_CTL, 15826f45ec7bSml29623 " nxge_tcam_handle_ip_fragment " 15836f45ec7bSml29623 " tcam_entry write" 15846f45ec7bSml29623 " failed for ASC RAM location %d", location)); 15856f45ec7bSml29623 return (NXGE_ERROR); 15866f45ec7bSml29623 } 15876f45ec7bSml29623 bcopy((void *) &tcam_ptr, 15886f45ec7bSml29623 (void *) &nxgep->classifier.tcam_entries[location].tce, 15896f45ec7bSml29623 sizeof (tcam_entry_t)); 15904df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt++; 15914df55fdeSJanie Lu nxgep->classifier.tcam_entries[location].valid = 1; 15926f45ec7bSml29623 for (class = TCAM_CLASS_TCP_IPV4; 15936f45ec7bSml29623 class <= TCAM_CLASS_SCTP_IPV6; class++) { 15946f45ec7bSml29623 class_config = nxgep->class_config.class_cfg[class]; 15956f45ec7bSml29623 class_config |= NXGE_CLASS_TCAM_LOOKUP; 15966f45ec7bSml29623 status = nxge_fflp_ip_class_config(nxgep, class, class_config); 15976f45ec7bSml29623 15986f45ec7bSml29623 if (status & NPI_FFLP_ERROR) { 15996f45ec7bSml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 16006f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16016f45ec7bSml29623 "nxge_tcam_handle_ip_fragment " 16026f45ec7bSml29623 "nxge_fflp_ip_class_config failed " 16036f45ec7bSml29623 " class %d config %x ", class, class_config)); 16046f45ec7bSml29623 return (NXGE_ERROR); 16056f45ec7bSml29623 } 16066f45ec7bSml29623 } 16076f45ec7bSml29623 16086f45ec7bSml29623 rs = npi_fflp_cfg_tcam_enable(handle); 16096f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 16106f45ec7bSml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 16116f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16126f45ec7bSml29623 "nxge_tcam_handle_ip_fragment " 16136f45ec7bSml29623 " nxge_fflp_config_tcam_enable failed")); 16146f45ec7bSml29623 return (NXGE_ERROR); 16156f45ec7bSml29623 } 16166f45ec7bSml29623 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 16176f45ec7bSml29623 return (NXGE_OK); 16186f45ec7bSml29623 } 16196f45ec7bSml29623 16206f45ec7bSml29623 /* ARGSUSED */ 16216f45ec7bSml29623 static int 16226f45ec7bSml29623 nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res) 16236f45ec7bSml29623 { 16246f45ec7bSml29623 return (0); 16256f45ec7bSml29623 } 16266f45ec7bSml29623 16276f45ec7bSml29623 nxge_status_t 16286f45ec7bSml29623 nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res) 16296f45ec7bSml29623 { 16306f45ec7bSml29623 16316f45ec7bSml29623 int insert_hash = 0; 16326f45ec7bSml29623 nxge_status_t status = NXGE_OK; 16336f45ec7bSml29623 16342e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 16356f45ec7bSml29623 /* determine whether to do TCAM or Hash flow */ 16366f45ec7bSml29623 insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res); 16376f45ec7bSml29623 } 16386f45ec7bSml29623 if (insert_hash) { 16396f45ec7bSml29623 status = nxge_add_fcram_entry(nxgep, flow_res); 16406f45ec7bSml29623 } else { 16416f45ec7bSml29623 status = nxge_add_tcam_entry(nxgep, flow_res); 16426f45ec7bSml29623 } 16436f45ec7bSml29623 return (status); 16446f45ec7bSml29623 } 16456f45ec7bSml29623 16466f45ec7bSml29623 void 16476f45ec7bSml29623 nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp) 16486f45ec7bSml29623 { 16496f45ec7bSml29623 flow_resource_t *fs; 16506f45ec7bSml29623 16516f45ec7bSml29623 fs = (flow_resource_t *)mp->b_rptr; 16526f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16536f45ec7bSml29623 "nxge_put_tcam addr fs $%p type %x offset %x", 16546f45ec7bSml29623 fs, fs->flow_spec.flow_type, fs->channel_cookie)); 16556f45ec7bSml29623 (void) nxge_add_tcam_entry(nxgep, fs); 16566f45ec7bSml29623 } 16576f45ec7bSml29623 16586f45ec7bSml29623 nxge_status_t 16596f45ec7bSml29623 nxge_fflp_config_tcam_enable(p_nxge_t nxgep) 16606f45ec7bSml29623 { 16616f45ec7bSml29623 npi_handle_t handle = nxgep->npi_reg_handle; 16626f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 16636f45ec7bSml29623 16646f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable")); 16656f45ec7bSml29623 rs = npi_fflp_cfg_tcam_enable(handle); 16666f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 16676f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16686f45ec7bSml29623 " nxge_fflp_config_tcam_enable failed")); 16696f45ec7bSml29623 return (NXGE_ERROR | rs); 16706f45ec7bSml29623 } 16716f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable")); 16726f45ec7bSml29623 return (NXGE_OK); 16736f45ec7bSml29623 } 16746f45ec7bSml29623 16756f45ec7bSml29623 nxge_status_t 16766f45ec7bSml29623 nxge_fflp_config_tcam_disable(p_nxge_t nxgep) 16776f45ec7bSml29623 { 16786f45ec7bSml29623 npi_handle_t handle = nxgep->npi_reg_handle; 16796f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 16806f45ec7bSml29623 16816f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 16826f45ec7bSml29623 " ==> nxge_fflp_config_tcam_disable")); 16836f45ec7bSml29623 rs = npi_fflp_cfg_tcam_disable(handle); 16846f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 16856f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16866f45ec7bSml29623 " nxge_fflp_config_tcam_disable failed")); 16876f45ec7bSml29623 return (NXGE_ERROR | rs); 16886f45ec7bSml29623 } 16896f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 16906f45ec7bSml29623 " <== nxge_fflp_config_tcam_disable")); 16916f45ec7bSml29623 return (NXGE_OK); 16926f45ec7bSml29623 } 16936f45ec7bSml29623 16946f45ec7bSml29623 nxge_status_t 16956f45ec7bSml29623 nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep) 16966f45ec7bSml29623 { 16976f45ec7bSml29623 npi_handle_t handle = nxgep->npi_reg_handle; 16986f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 16996f45ec7bSml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp; 17006f45ec7bSml29623 p_nxge_hw_pt_cfg_t p_cfgp; 17016f45ec7bSml29623 uint8_t partition; 17026f45ec7bSml29623 17036f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17046f45ec7bSml29623 " ==> nxge_fflp_config_hash_lookup_enable")); 17056f45ec7bSml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 17066f45ec7bSml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 17076f45ec7bSml29623 1708678453a8Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 1709678453a8Sspeer if (p_cfgp->grpids[partition]) { 1710678453a8Sspeer rs = npi_fflp_cfg_fcram_partition_enable( 1711678453a8Sspeer handle, partition); 17126f45ec7bSml29623 if (rs != NPI_SUCCESS) { 17136f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17146f45ec7bSml29623 " nxge_fflp_config_hash_lookup_enable" 17156f45ec7bSml29623 "failed FCRAM partition" 17166f45ec7bSml29623 " enable for partition %d ", partition)); 17176f45ec7bSml29623 return (NXGE_ERROR | rs); 17186f45ec7bSml29623 } 17196f45ec7bSml29623 } 1720678453a8Sspeer } 17216f45ec7bSml29623 17226f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17236f45ec7bSml29623 " <== nxge_fflp_config_hash_lookup_enable")); 17246f45ec7bSml29623 return (NXGE_OK); 17256f45ec7bSml29623 } 17266f45ec7bSml29623 17276f45ec7bSml29623 nxge_status_t 17286f45ec7bSml29623 nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep) 17296f45ec7bSml29623 { 17306f45ec7bSml29623 npi_handle_t handle = nxgep->npi_reg_handle; 17316f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 17326f45ec7bSml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp; 17336f45ec7bSml29623 p_nxge_hw_pt_cfg_t p_cfgp; 17346f45ec7bSml29623 uint8_t partition; 17356f45ec7bSml29623 17366f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17376f45ec7bSml29623 " ==> nxge_fflp_config_hash_lookup_disable")); 17386f45ec7bSml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 17396f45ec7bSml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 17406f45ec7bSml29623 1741678453a8Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 1742678453a8Sspeer if (p_cfgp->grpids[partition]) { 17436f45ec7bSml29623 rs = npi_fflp_cfg_fcram_partition_disable(handle, 17446f45ec7bSml29623 partition); 17456f45ec7bSml29623 if (rs != NPI_SUCCESS) { 17466f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17476f45ec7bSml29623 " nxge_fflp_config_hash_lookup_disable" 17486f45ec7bSml29623 " failed FCRAM partition" 17496f45ec7bSml29623 " disable for partition %d ", partition)); 17506f45ec7bSml29623 return (NXGE_ERROR | rs); 17516f45ec7bSml29623 } 17526f45ec7bSml29623 } 1753678453a8Sspeer } 17546f45ec7bSml29623 17556f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17566f45ec7bSml29623 " <== nxge_fflp_config_hash_lookup_disable")); 17576f45ec7bSml29623 return (NXGE_OK); 17586f45ec7bSml29623 } 17596f45ec7bSml29623 17606f45ec7bSml29623 nxge_status_t 17616f45ec7bSml29623 nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep) 17626f45ec7bSml29623 { 17636f45ec7bSml29623 npi_handle_t handle = nxgep->npi_reg_handle; 17646f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 17656f45ec7bSml29623 17666f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17676f45ec7bSml29623 " ==> nxge_fflp_config_llc_snap_enable")); 17686f45ec7bSml29623 rs = npi_fflp_cfg_llcsnap_enable(handle); 17696f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 17706f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17716f45ec7bSml29623 " nxge_fflp_config_llc_snap_enable failed")); 17726f45ec7bSml29623 return (NXGE_ERROR | rs); 17736f45ec7bSml29623 } 17746f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17756f45ec7bSml29623 " <== nxge_fflp_config_llc_snap_enable")); 17766f45ec7bSml29623 return (NXGE_OK); 17776f45ec7bSml29623 } 17786f45ec7bSml29623 17796f45ec7bSml29623 nxge_status_t 17806f45ec7bSml29623 nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep) 17816f45ec7bSml29623 { 17826f45ec7bSml29623 npi_handle_t handle = nxgep->npi_reg_handle; 17836f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 17846f45ec7bSml29623 17856f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17866f45ec7bSml29623 " ==> nxge_fflp_config_llc_snap_disable")); 17876f45ec7bSml29623 rs = npi_fflp_cfg_llcsnap_disable(handle); 17886f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 17896f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17906f45ec7bSml29623 " nxge_fflp_config_llc_snap_disable failed")); 17916f45ec7bSml29623 return (NXGE_ERROR | rs); 17926f45ec7bSml29623 } 17936f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 17946f45ec7bSml29623 " <== nxge_fflp_config_llc_snap_disable")); 17956f45ec7bSml29623 return (NXGE_OK); 17966f45ec7bSml29623 } 17976f45ec7bSml29623 17986f45ec7bSml29623 nxge_status_t 17996f45ec7bSml29623 nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class, 18006f45ec7bSml29623 uint32_t config) 18016f45ec7bSml29623 { 18026f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 18036f45ec7bSml29623 npi_handle_t handle = nxgep->npi_reg_handle; 18046f45ec7bSml29623 uint8_t tos, tos_mask, proto, ver = 0; 18056f45ec7bSml29623 uint8_t class_enable = 0; 18066f45ec7bSml29623 18076f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config")); 18086f45ec7bSml29623 18096f45ec7bSml29623 tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >> 18106f45ec7bSml29623 NXGE_CLASS_CFG_IP_TOS_SHIFT; 18116f45ec7bSml29623 tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >> 18126f45ec7bSml29623 NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT; 18136f45ec7bSml29623 proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >> 18146f45ec7bSml29623 NXGE_CLASS_CFG_IP_PROTO_SHIFT; 18156f45ec7bSml29623 if (config & NXGE_CLASS_CFG_IP_IPV6_MASK) 18166f45ec7bSml29623 ver = 1; 18176f45ec7bSml29623 if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK) 18186f45ec7bSml29623 class_enable = 1; 18196f45ec7bSml29623 rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask, 18206f45ec7bSml29623 proto, ver); 18216f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 18226f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18236f45ec7bSml29623 " nxge_fflp_ip_usr_class_config" 18246f45ec7bSml29623 " for class %d failed ", class)); 18256f45ec7bSml29623 return (NXGE_ERROR | rs); 18266f45ec7bSml29623 } 18276f45ec7bSml29623 if (class_enable) 18286f45ec7bSml29623 rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class); 18296f45ec7bSml29623 else 18306f45ec7bSml29623 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 18316f45ec7bSml29623 18326f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 18336f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18346f45ec7bSml29623 " nxge_fflp_ip_usr_class_config" 18356f45ec7bSml29623 " TCAM enable/disable for class %d failed ", class)); 18366f45ec7bSml29623 return (NXGE_ERROR | rs); 18376f45ec7bSml29623 } 18386f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config")); 18396f45ec7bSml29623 return (NXGE_OK); 18406f45ec7bSml29623 } 18416f45ec7bSml29623 18426f45ec7bSml29623 nxge_status_t 18436f45ec7bSml29623 nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config) 18446f45ec7bSml29623 { 18456f45ec7bSml29623 uint32_t class_config; 18466f45ec7bSml29623 nxge_status_t t_status = NXGE_OK; 18476f45ec7bSml29623 nxge_status_t f_status = NXGE_OK; 18486f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 18496f45ec7bSml29623 18506f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 18516f45ec7bSml29623 18526f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 18536f45ec7bSml29623 class_config = p_class_cfgp->class_cfg[class]; 18546f45ec7bSml29623 18556f45ec7bSml29623 if (class_config != config) { 18566f45ec7bSml29623 p_class_cfgp->class_cfg[class] = config; 18576f45ec7bSml29623 class_config = config; 18586f45ec7bSml29623 } 18596f45ec7bSml29623 18606f45ec7bSml29623 t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config); 18616f45ec7bSml29623 f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config); 18626f45ec7bSml29623 18636f45ec7bSml29623 if (t_status & NPI_FFLP_ERROR) { 18646f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 18656f45ec7bSml29623 " nxge_fflp_ip_class_config %x" 18666f45ec7bSml29623 " for class %d tcam failed", config, class)); 18676f45ec7bSml29623 return (t_status); 18686f45ec7bSml29623 } 18696f45ec7bSml29623 if (f_status & NPI_FFLP_ERROR) { 18706f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18716f45ec7bSml29623 " nxge_fflp_ip_class_config %x" 18726f45ec7bSml29623 " for class %d flow key failed", config, class)); 18736f45ec7bSml29623 return (f_status); 18746f45ec7bSml29623 } 18756f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 18766f45ec7bSml29623 return (NXGE_OK); 18776f45ec7bSml29623 } 18786f45ec7bSml29623 18796f45ec7bSml29623 nxge_status_t 18806f45ec7bSml29623 nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class, 18816f45ec7bSml29623 uint32_t *config) 18826f45ec7bSml29623 { 18836f45ec7bSml29623 uint32_t t_class_config, f_class_config; 18846f45ec7bSml29623 int t_status = NXGE_OK; 18856f45ec7bSml29623 int f_status = NXGE_OK; 18866f45ec7bSml29623 18876f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 18886f45ec7bSml29623 18896f45ec7bSml29623 t_class_config = f_class_config = 0; 18906f45ec7bSml29623 t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config); 18916f45ec7bSml29623 f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config); 18926f45ec7bSml29623 18936f45ec7bSml29623 if (t_status & NPI_FFLP_ERROR) { 18946f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18956f45ec7bSml29623 " nxge_fflp_ip_class_config_get " 18966f45ec7bSml29623 " for class %d tcam failed", class)); 18976f45ec7bSml29623 return (t_status); 18986f45ec7bSml29623 } 18996f45ec7bSml29623 19006f45ec7bSml29623 if (f_status & NPI_FFLP_ERROR) { 19016f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 19026f45ec7bSml29623 " nxge_fflp_ip_class_config_get " 19036f45ec7bSml29623 " for class %d flow key failed", class)); 19046f45ec7bSml29623 return (f_status); 19056f45ec7bSml29623 } 19066f45ec7bSml29623 19076f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 19086f45ec7bSml29623 " nxge_fflp_ip_class_config tcam %x flow %x", 19096f45ec7bSml29623 t_class_config, f_class_config)); 19106f45ec7bSml29623 19116f45ec7bSml29623 *config = t_class_config | f_class_config; 19126f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get")); 19136f45ec7bSml29623 return (NXGE_OK); 19146f45ec7bSml29623 } 19156f45ec7bSml29623 19166f45ec7bSml29623 nxge_status_t 19176f45ec7bSml29623 nxge_fflp_ip_class_config_all(p_nxge_t nxgep) 19186f45ec7bSml29623 { 19196f45ec7bSml29623 uint32_t class_config; 19206f45ec7bSml29623 tcam_class_t class; 19216f45ec7bSml29623 19226f45ec7bSml29623 #ifdef NXGE_DEBUG 19236f45ec7bSml29623 int status = NXGE_OK; 19246f45ec7bSml29623 #endif 19256f45ec7bSml29623 19266f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config")); 19276f45ec7bSml29623 for (class = TCAM_CLASS_TCP_IPV4; 19286f45ec7bSml29623 class <= TCAM_CLASS_SCTP_IPV6; class++) { 19296f45ec7bSml29623 class_config = nxgep->class_config.class_cfg[class]; 19306f45ec7bSml29623 #ifndef NXGE_DEBUG 19316f45ec7bSml29623 (void) nxge_fflp_ip_class_config(nxgep, class, class_config); 19326f45ec7bSml29623 #else 19336f45ec7bSml29623 status = nxge_fflp_ip_class_config(nxgep, class, class_config); 19346f45ec7bSml29623 if (status & NPI_FFLP_ERROR) { 19356f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19366f45ec7bSml29623 "nxge_fflp_ip_class_config failed " 19376f45ec7bSml29623 " class %d config %x ", 19386f45ec7bSml29623 class, class_config)); 19396f45ec7bSml29623 } 19406f45ec7bSml29623 #endif 19416f45ec7bSml29623 } 19426f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 19436f45ec7bSml29623 return (NXGE_OK); 19446f45ec7bSml29623 } 19456f45ec7bSml29623 19466f45ec7bSml29623 nxge_status_t 19476f45ec7bSml29623 nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id) 19486f45ec7bSml29623 { 19496f45ec7bSml29623 uint8_t port, rdc_grp; 19506f45ec7bSml29623 npi_handle_t handle; 19516f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 19526f45ec7bSml29623 uint8_t priority = 1; 19536f45ec7bSml29623 p_nxge_mv_cfg_t vlan_table; 19546f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 19556f45ec7bSml29623 p_nxge_hw_list_t hw_p; 19566f45ec7bSml29623 19576f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table")); 19586f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 19596f45ec7bSml29623 handle = nxgep->npi_reg_handle; 19606f45ec7bSml29623 vlan_table = p_class_cfgp->vlan_tbl; 19616f45ec7bSml29623 port = nxgep->function_num; 19626f45ec7bSml29623 19636f45ec7bSml29623 if (vlan_table[vlan_id].flag == 0) { 19646f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19656f45ec7bSml29623 " nxge_fflp_config_vlan_table" 19666f45ec7bSml29623 " vlan id is not configured %d", vlan_id)); 19676f45ec7bSml29623 return (NXGE_ERROR); 19686f45ec7bSml29623 } 19696f45ec7bSml29623 19706f45ec7bSml29623 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 19716f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19726f45ec7bSml29623 " nxge_fflp_config_vlan_table:" 19736f45ec7bSml29623 " common hardware not set", nxgep->niu_type)); 19746f45ec7bSml29623 return (NXGE_ERROR); 19756f45ec7bSml29623 } 19766f45ec7bSml29623 MUTEX_ENTER(&hw_p->nxge_vlan_lock); 19776f45ec7bSml29623 rdc_grp = vlan_table[vlan_id].rdctbl; 19786f45ec7bSml29623 rs = npi_fflp_cfg_enet_vlan_table_assoc(handle, 19796f45ec7bSml29623 port, vlan_id, 19806f45ec7bSml29623 rdc_grp, priority); 19816f45ec7bSml29623 19826f45ec7bSml29623 MUTEX_EXIT(&hw_p->nxge_vlan_lock); 19836f45ec7bSml29623 if (rs & NPI_FFLP_ERROR) { 19846f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19856f45ec7bSml29623 "nxge_fflp_config_vlan_table failed " 19866f45ec7bSml29623 " Port %d vlan_id %d rdc_grp %d", 19876f45ec7bSml29623 port, vlan_id, rdc_grp)); 19886f45ec7bSml29623 return (NXGE_ERROR | rs); 19896f45ec7bSml29623 } 19906f45ec7bSml29623 19916f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table")); 19926f45ec7bSml29623 return (NXGE_OK); 19936f45ec7bSml29623 } 19946f45ec7bSml29623 19956f45ec7bSml29623 nxge_status_t 19966f45ec7bSml29623 nxge_fflp_update_hw(p_nxge_t nxgep) 19976f45ec7bSml29623 { 19986f45ec7bSml29623 nxge_status_t status = NXGE_OK; 19996f45ec7bSml29623 p_nxge_param_t pa; 20006f45ec7bSml29623 uint64_t cfgd_vlans; 20016f45ec7bSml29623 uint64_t *val_ptr; 20026f45ec7bSml29623 int i; 20036f45ec7bSml29623 int num_macs; 20046f45ec7bSml29623 uint8_t alt_mac; 20056f45ec7bSml29623 nxge_param_map_t *p_map; 20066f45ec7bSml29623 p_nxge_mv_cfg_t vlan_table; 20076f45ec7bSml29623 p_nxge_class_pt_cfg_t p_class_cfgp; 20086f45ec7bSml29623 p_nxge_dma_pt_cfg_t p_all_cfgp; 20096f45ec7bSml29623 p_nxge_hw_pt_cfg_t p_cfgp; 20106f45ec7bSml29623 20116f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw")); 20126f45ec7bSml29623 20136f45ec7bSml29623 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 20146f45ec7bSml29623 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 20156f45ec7bSml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 20166f45ec7bSml29623 20176f45ec7bSml29623 status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1); 20186f45ec7bSml29623 if (status != NXGE_OK) { 20196f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20206f45ec7bSml29623 "nxge_fflp_set_hash1 Failed")); 20216f45ec7bSml29623 return (NXGE_ERROR); 20226f45ec7bSml29623 } 20236f45ec7bSml29623 20246f45ec7bSml29623 status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2); 20256f45ec7bSml29623 if (status != NXGE_OK) { 20266f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20276f45ec7bSml29623 "nxge_fflp_set_hash2 Failed")); 20286f45ec7bSml29623 return (NXGE_ERROR); 20296f45ec7bSml29623 } 20306f45ec7bSml29623 vlan_table = p_class_cfgp->vlan_tbl; 20316f45ec7bSml29623 20326f45ec7bSml29623 /* configure vlan tables */ 20336f45ec7bSml29623 pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp]; 2034adfcba55Sjoycey #if defined(__i386) 2035adfcba55Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value; 2036adfcba55Sjoycey #else 20376f45ec7bSml29623 val_ptr = (uint64_t *)pa->value; 2038adfcba55Sjoycey #endif 20396f45ec7bSml29623 cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >> 20406f45ec7bSml29623 NXGE_PARAM_ARRAY_CNT_SHIFT); 20416f45ec7bSml29623 20426f45ec7bSml29623 for (i = 0; i < cfgd_vlans; i++) { 20436f45ec7bSml29623 p_map = (nxge_param_map_t *)&val_ptr[i]; 20446f45ec7bSml29623 if (vlan_table[p_map->param_id].flag) { 20456f45ec7bSml29623 status = nxge_fflp_config_vlan_table(nxgep, 20466f45ec7bSml29623 p_map->param_id); 20476f45ec7bSml29623 if (status != NXGE_OK) { 20486f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20496f45ec7bSml29623 "nxge_fflp_config_vlan_table Failed")); 20506f45ec7bSml29623 return (NXGE_ERROR); 20516f45ec7bSml29623 } 20526f45ec7bSml29623 } 20536f45ec7bSml29623 } 20546f45ec7bSml29623 20556f45ec7bSml29623 /* config MAC addresses */ 20566f45ec7bSml29623 num_macs = p_cfgp->max_macs; 20576f45ec7bSml29623 pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp]; 2058adfcba55Sjoycey #if defined(__i386) 2059adfcba55Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value; 2060adfcba55Sjoycey #else 20616f45ec7bSml29623 val_ptr = (uint64_t *)pa->value; 2062adfcba55Sjoycey #endif 20636f45ec7bSml29623 20646f45ec7bSml29623 for (alt_mac = 0; alt_mac < num_macs; alt_mac++) { 20656f45ec7bSml29623 if (p_class_cfgp->mac_host_info[alt_mac].flag) { 20666f45ec7bSml29623 status = nxge_logical_mac_assign_rdc_table(nxgep, 20676f45ec7bSml29623 alt_mac); 20686f45ec7bSml29623 if (status != NXGE_OK) { 20696f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20706f45ec7bSml29623 "nxge_logical_mac_assign_rdc_table" 20716f45ec7bSml29623 " Failed")); 20726f45ec7bSml29623 return (NXGE_ERROR); 20736f45ec7bSml29623 } 20746f45ec7bSml29623 } 20756f45ec7bSml29623 } 20766f45ec7bSml29623 20776f45ec7bSml29623 /* Config Hash values */ 2078f6485eecSyc148097 /* config classes */ 20796f45ec7bSml29623 status = nxge_fflp_ip_class_config_all(nxgep); 20806f45ec7bSml29623 if (status != NXGE_OK) { 20816f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 20826f45ec7bSml29623 "nxge_fflp_ip_class_config_all Failed")); 20836f45ec7bSml29623 return (NXGE_ERROR); 20846f45ec7bSml29623 } 20856f45ec7bSml29623 return (NXGE_OK); 20866f45ec7bSml29623 } 20876f45ec7bSml29623 20886f45ec7bSml29623 nxge_status_t 20896f45ec7bSml29623 nxge_classify_init_hw(p_nxge_t nxgep) 20906f45ec7bSml29623 { 20916f45ec7bSml29623 nxge_status_t status = NXGE_OK; 20926f45ec7bSml29623 20936f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw")); 20946f45ec7bSml29623 20956f45ec7bSml29623 if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) { 20966f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 20976f45ec7bSml29623 "nxge_classify_init_hw already init")); 20986f45ec7bSml29623 return (NXGE_OK); 20996f45ec7bSml29623 } 21006f45ec7bSml29623 21016f45ec7bSml29623 /* Now do a real configuration */ 21026f45ec7bSml29623 status = nxge_fflp_update_hw(nxgep); 21036f45ec7bSml29623 if (status != NXGE_OK) { 21046f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21056f45ec7bSml29623 "nxge_fflp_update_hw failed")); 21066f45ec7bSml29623 return (NXGE_ERROR); 21076f45ec7bSml29623 } 21086f45ec7bSml29623 21096f45ec7bSml29623 /* Init RDC tables? ? who should do that? rxdma or fflp ? */ 21106f45ec7bSml29623 /* attach rdc table to the MAC port. */ 21116f45ec7bSml29623 status = nxge_main_mac_assign_rdc_table(nxgep); 21126f45ec7bSml29623 if (status != NXGE_OK) { 21136f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21146f45ec7bSml29623 "nxge_main_mac_assign_rdc_table failed")); 21156f45ec7bSml29623 return (NXGE_ERROR); 21166f45ec7bSml29623 } 21176f45ec7bSml29623 21186f45ec7bSml29623 status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 21196f45ec7bSml29623 if (status != NXGE_OK) { 21206f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21216f45ec7bSml29623 "nxge_multicast_mac_assign_rdc_table failed")); 21226f45ec7bSml29623 return (NXGE_ERROR); 21236f45ec7bSml29623 } 21246f45ec7bSml29623 21254df55fdeSJanie Lu if (nxgep->classifier.fragment_bug == 1) { 21266f45ec7bSml29623 status = nxge_tcam_handle_ip_fragment(nxgep); 21276f45ec7bSml29623 if (status != NXGE_OK) { 21286f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21296f45ec7bSml29623 "nxge_tcam_handle_ip_fragment failed")); 21306f45ec7bSml29623 return (NXGE_ERROR); 21316f45ec7bSml29623 } 21324df55fdeSJanie Lu } 21336f45ec7bSml29623 21346f45ec7bSml29623 nxgep->classifier.state |= NXGE_FFLP_HW_INIT; 21356f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw")); 21366f45ec7bSml29623 return (NXGE_OK); 21376f45ec7bSml29623 } 21386f45ec7bSml29623 21396f45ec7bSml29623 nxge_status_t 21406f45ec7bSml29623 nxge_fflp_handle_sys_errors(p_nxge_t nxgep) 21416f45ec7bSml29623 { 21426f45ec7bSml29623 npi_handle_t handle; 21436f45ec7bSml29623 p_nxge_fflp_stats_t statsp; 21446f45ec7bSml29623 uint8_t portn, rdc_grp; 21456f45ec7bSml29623 p_nxge_dma_pt_cfg_t p_dma_cfgp; 21466f45ec7bSml29623 p_nxge_hw_pt_cfg_t p_cfgp; 21476f45ec7bSml29623 vlan_par_err_t vlan_err; 21486f45ec7bSml29623 tcam_err_t tcam_err; 21496f45ec7bSml29623 hash_lookup_err_log1_t fcram1_err; 21506f45ec7bSml29623 hash_lookup_err_log2_t fcram2_err; 21516f45ec7bSml29623 hash_tbl_data_log_t fcram_err; 21526f45ec7bSml29623 21536f45ec7bSml29623 handle = nxgep->npi_handle; 21546f45ec7bSml29623 statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats; 21556f45ec7bSml29623 portn = nxgep->mac.portnum; 21566f45ec7bSml29623 21576f45ec7bSml29623 /* 21586f45ec7bSml29623 * need to read the fflp error registers to figure out what the error 21596f45ec7bSml29623 * is 21606f45ec7bSml29623 */ 21616f45ec7bSml29623 npi_fflp_vlan_error_get(handle, &vlan_err); 21626f45ec7bSml29623 npi_fflp_tcam_error_get(handle, &tcam_err); 21636f45ec7bSml29623 21646f45ec7bSml29623 if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) { 21656f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 21666f45ec7bSml29623 " vlan table parity error on port %d" 21676f45ec7bSml29623 " addr: 0x%x data: 0x%x", 21686f45ec7bSml29623 portn, vlan_err.bits.ldw.addr, 21696f45ec7bSml29623 vlan_err.bits.ldw.data)); 21706f45ec7bSml29623 statsp->vlan_parity_err++; 21716f45ec7bSml29623 21726f45ec7bSml29623 if (vlan_err.bits.ldw.m_err) { 21736f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 21746f45ec7bSml29623 " vlan table multiple errors on port %d", 21756f45ec7bSml29623 portn)); 21766f45ec7bSml29623 } 21776f45ec7bSml29623 statsp->errlog.vlan = (uint32_t)vlan_err.value; 21786f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 21796f45ec7bSml29623 NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR); 21806f45ec7bSml29623 npi_fflp_vlan_error_clear(handle); 21816f45ec7bSml29623 } 21826f45ec7bSml29623 21836f45ec7bSml29623 if (tcam_err.bits.ldw.err) { 21846f45ec7bSml29623 if (tcam_err.bits.ldw.p_ecc != 0) { 21856f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 21866f45ec7bSml29623 " TCAM ECC error on port %d" 21876f45ec7bSml29623 " TCAM entry: 0x%x syndrome: 0x%x", 21886f45ec7bSml29623 portn, tcam_err.bits.ldw.addr, 21896f45ec7bSml29623 tcam_err.bits.ldw.syndrome)); 21906f45ec7bSml29623 statsp->tcam_ecc_err++; 21916f45ec7bSml29623 } else { 21926f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 21936f45ec7bSml29623 " TCAM Parity error on port %d" 21946f45ec7bSml29623 " addr: 0x%x parity value: 0x%x", 21956f45ec7bSml29623 portn, tcam_err.bits.ldw.addr, 21966f45ec7bSml29623 tcam_err.bits.ldw.syndrome)); 21976f45ec7bSml29623 statsp->tcam_parity_err++; 21986f45ec7bSml29623 } 21996f45ec7bSml29623 22006f45ec7bSml29623 if (tcam_err.bits.ldw.mult) { 22016f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 22026f45ec7bSml29623 " TCAM Multiple errors on port %d", portn)); 22036f45ec7bSml29623 } else { 22046f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 220552ccf843Smisaki " TCAM PIO error on port %d", portn)); 22066f45ec7bSml29623 } 22076f45ec7bSml29623 22086f45ec7bSml29623 statsp->errlog.tcam = (uint32_t)tcam_err.value; 22096f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 22106f45ec7bSml29623 NXGE_FM_EREPORT_FFLP_TCAM_ERR); 22116f45ec7bSml29623 npi_fflp_tcam_error_clear(handle); 22126f45ec7bSml29623 } 22136f45ec7bSml29623 22146f45ec7bSml29623 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 22156f45ec7bSml29623 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 22166f45ec7bSml29623 2217678453a8Sspeer for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) { 2218678453a8Sspeer if (p_cfgp->grpids[rdc_grp]) { 22196f45ec7bSml29623 npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp); 22206f45ec7bSml29623 if (fcram_err.bits.ldw.pio_err) { 22216f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 22226f45ec7bSml29623 " FCRAM PIO ECC error on port %d" 22236f45ec7bSml29623 " rdc group: %d Hash Table addr: 0x%x" 22246f45ec7bSml29623 " syndrome: 0x%x", 22256f45ec7bSml29623 portn, rdc_grp, 22266f45ec7bSml29623 fcram_err.bits.ldw.fcram_addr, 22276f45ec7bSml29623 fcram_err.bits.ldw.syndrome)); 22286f45ec7bSml29623 statsp->hash_pio_err[rdc_grp]++; 22296f45ec7bSml29623 statsp->errlog.hash_pio[rdc_grp] = 22306f45ec7bSml29623 (uint32_t)fcram_err.value; 22316f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 22326f45ec7bSml29623 NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR); 22336f45ec7bSml29623 npi_fflp_fcram_error_clear(handle, rdc_grp); 22346f45ec7bSml29623 } 22356f45ec7bSml29623 } 2236678453a8Sspeer } 22376f45ec7bSml29623 22386f45ec7bSml29623 npi_fflp_fcram_error_log1_get(handle, &fcram1_err); 22396f45ec7bSml29623 if (fcram1_err.bits.ldw.ecc_err) { 22406f45ec7bSml29623 char *multi_str = ""; 22416f45ec7bSml29623 char *multi_bit_str = ""; 22426f45ec7bSml29623 22436f45ec7bSml29623 npi_fflp_fcram_error_log2_get(handle, &fcram2_err); 22446f45ec7bSml29623 if (fcram1_err.bits.ldw.mult_lk) { 22456f45ec7bSml29623 multi_str = "multiple"; 22466f45ec7bSml29623 } 22476f45ec7bSml29623 if (fcram1_err.bits.ldw.mult_bit) { 22486f45ec7bSml29623 multi_bit_str = "multiple bits"; 22496f45ec7bSml29623 } 2250f6485eecSyc148097 statsp->hash_lookup_err++; 22516f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 22526f45ec7bSml29623 " FCRAM %s lookup %s ECC error on port %d" 22536f45ec7bSml29623 " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x", 22546f45ec7bSml29623 multi_str, multi_bit_str, portn, 22556f45ec7bSml29623 fcram2_err.bits.ldw.h1, 22566f45ec7bSml29623 fcram2_err.bits.ldw.subarea, 22576f45ec7bSml29623 fcram2_err.bits.ldw.syndrome)); 22586f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 22596f45ec7bSml29623 NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR); 22606f45ec7bSml29623 } 22616f45ec7bSml29623 statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value; 22626f45ec7bSml29623 statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value; 22636f45ec7bSml29623 return (NXGE_OK); 22646f45ec7bSml29623 } 22654df55fdeSJanie Lu 22664df55fdeSJanie Lu int 22674df55fdeSJanie Lu nxge_get_valid_tcam_cnt(p_nxge_t nxgep) { 22684df55fdeSJanie Lu return ((nxgep->classifier.fragment_bug == 1) ? 22694df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt - 1 : 22704df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt); 22714df55fdeSJanie Lu } 22724df55fdeSJanie Lu 22734df55fdeSJanie Lu int 22744df55fdeSJanie Lu nxge_rxdma_channel_cnt(p_nxge_t nxgep) 22754df55fdeSJanie Lu { 22764df55fdeSJanie Lu p_nxge_dma_pt_cfg_t p_dma_cfgp; 22774df55fdeSJanie Lu p_nxge_hw_pt_cfg_t p_cfgp; 22784df55fdeSJanie Lu 22794df55fdeSJanie Lu p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 22804df55fdeSJanie Lu p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 22814df55fdeSJanie Lu return (p_cfgp->max_rdcs); 22824df55fdeSJanie Lu } 22834df55fdeSJanie Lu 22844df55fdeSJanie Lu /* ARGSUSED */ 22854df55fdeSJanie Lu int 22864df55fdeSJanie Lu nxge_rxclass_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 22874df55fdeSJanie Lu { 22884df55fdeSJanie Lu uint32_t cmd; 22894df55fdeSJanie Lu rx_class_cfg_t *cfg_info = (rx_class_cfg_t *)mp->b_rptr; 22904df55fdeSJanie Lu 22914df55fdeSJanie Lu if (nxgep == NULL) { 22924df55fdeSJanie Lu return (-1); 22934df55fdeSJanie Lu } 22944df55fdeSJanie Lu cmd = cfg_info->cmd; 22954df55fdeSJanie Lu switch (cmd) { 22964df55fdeSJanie Lu default: 22974df55fdeSJanie Lu return (-1); 22984df55fdeSJanie Lu 22994df55fdeSJanie Lu case NXGE_RX_CLASS_GCHAN: 23004df55fdeSJanie Lu cfg_info->data = nxge_rxdma_channel_cnt(nxgep); 23014df55fdeSJanie Lu break; 23024df55fdeSJanie Lu case NXGE_RX_CLASS_GRULE_CNT: 23034df55fdeSJanie Lu MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 23044df55fdeSJanie Lu cfg_info->rule_cnt = nxge_get_valid_tcam_cnt(nxgep); 23054df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 23064df55fdeSJanie Lu break; 23074df55fdeSJanie Lu case NXGE_RX_CLASS_GRULE: 23084df55fdeSJanie Lu nxge_get_tcam_entry(nxgep, &cfg_info->fs); 23094df55fdeSJanie Lu break; 23104df55fdeSJanie Lu case NXGE_RX_CLASS_GRULE_ALL: 23114df55fdeSJanie Lu nxge_get_tcam_entry_all(nxgep, cfg_info); 23124df55fdeSJanie Lu break; 23134df55fdeSJanie Lu case NXGE_RX_CLASS_RULE_DEL: 23144df55fdeSJanie Lu nxge_del_tcam_entry(nxgep, cfg_info->fs.location); 23154df55fdeSJanie Lu break; 23164df55fdeSJanie Lu case NXGE_RX_CLASS_RULE_INS: 23174df55fdeSJanie Lu (void) nxge_add_tcam_entry(nxgep, &cfg_info->fs); 23184df55fdeSJanie Lu break; 23194df55fdeSJanie Lu } 23204df55fdeSJanie Lu return (0); 23214df55fdeSJanie Lu } 23224df55fdeSJanie Lu /* ARGSUSED */ 23234df55fdeSJanie Lu int 23244df55fdeSJanie Lu nxge_rxhash_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 23254df55fdeSJanie Lu { 23264df55fdeSJanie Lu uint32_t cmd; 23274df55fdeSJanie Lu cfg_cmd_t *cfg_info = (cfg_cmd_t *)mp->b_rptr; 23284df55fdeSJanie Lu 23294df55fdeSJanie Lu if (nxgep == NULL) { 23304df55fdeSJanie Lu return (-1); 23314df55fdeSJanie Lu } 23324df55fdeSJanie Lu cmd = cfg_info->cmd; 23334df55fdeSJanie Lu 23344df55fdeSJanie Lu switch (cmd) { 23354df55fdeSJanie Lu default: 23364df55fdeSJanie Lu return (-1); 23374df55fdeSJanie Lu case NXGE_IPTUN_CFG_ADD_CLS: 23384df55fdeSJanie Lu nxge_add_iptun_class(nxgep, &cfg_info->iptun_cfg, 23394df55fdeSJanie Lu &cfg_info->class_id); 23404df55fdeSJanie Lu break; 23414df55fdeSJanie Lu case NXGE_IPTUN_CFG_SET_HASH: 23424df55fdeSJanie Lu nxge_cfg_iptun_hash(nxgep, &cfg_info->iptun_cfg, 23434df55fdeSJanie Lu cfg_info->class_id); 23444df55fdeSJanie Lu break; 23454df55fdeSJanie Lu case NXGE_IPTUN_CFG_DEL_CLS: 23464df55fdeSJanie Lu nxge_del_iptun_class(nxgep, cfg_info->class_id); 23474df55fdeSJanie Lu break; 23484df55fdeSJanie Lu case NXGE_IPTUN_CFG_GET_CLS: 23494df55fdeSJanie Lu nxge_get_iptun_class(nxgep, &cfg_info->iptun_cfg, 23504df55fdeSJanie Lu cfg_info->class_id); 23514df55fdeSJanie Lu break; 23524df55fdeSJanie Lu case NXGE_CLS_CFG_SET_SYM: 23534df55fdeSJanie Lu nxge_set_ip_cls_sym(nxgep, cfg_info->class_id, cfg_info->sym); 23544df55fdeSJanie Lu break; 23554df55fdeSJanie Lu case NXGE_CLS_CFG_GET_SYM: 23564df55fdeSJanie Lu nxge_get_ip_cls_sym(nxgep, cfg_info->class_id, &cfg_info->sym); 23574df55fdeSJanie Lu break; 23584df55fdeSJanie Lu } 23594df55fdeSJanie Lu return (0); 23604df55fdeSJanie Lu } 23614df55fdeSJanie Lu 23624df55fdeSJanie Lu void 23634df55fdeSJanie Lu nxge_get_tcam_entry_all(p_nxge_t nxgep, rx_class_cfg_t *cfgp) 23644df55fdeSJanie Lu { 23654df55fdeSJanie Lu nxge_classify_t *clasp = &nxgep->classifier; 23664df55fdeSJanie Lu uint16_t n_entries; 23674df55fdeSJanie Lu int i, j, k; 23684df55fdeSJanie Lu tcam_flow_spec_t *tcam_entryp; 23694df55fdeSJanie Lu 23704df55fdeSJanie Lu cfgp->data = clasp->tcam_size; 23714df55fdeSJanie Lu MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 23724df55fdeSJanie Lu n_entries = cfgp->rule_cnt; 23734df55fdeSJanie Lu 23744df55fdeSJanie Lu for (i = 0, j = 0; j < cfgp->data; j++) { 23754df55fdeSJanie Lu k = nxge_tcam_get_index(nxgep, j); 23764df55fdeSJanie Lu tcam_entryp = &clasp->tcam_entries[k]; 23774df55fdeSJanie Lu if (tcam_entryp->valid != 1) 23784df55fdeSJanie Lu continue; 23794df55fdeSJanie Lu cfgp->rule_locs[i] = j; 23804df55fdeSJanie Lu i++; 23814df55fdeSJanie Lu }; 23824df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 23834df55fdeSJanie Lu 23844df55fdeSJanie Lu if (n_entries != i) { 23854df55fdeSJanie Lu /* print warning, this should not happen */ 23864df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry_all" 23874df55fdeSJanie Lu "n_entries[%d] != i[%d]!!!", n_entries, i)); 23884df55fdeSJanie Lu } 23894df55fdeSJanie Lu } 23904df55fdeSJanie Lu 23914df55fdeSJanie Lu 23924df55fdeSJanie Lu /* Entries for the ports are interleaved in the TCAM */ 23934df55fdeSJanie Lu static uint16_t 23944df55fdeSJanie Lu nxge_tcam_get_index(p_nxge_t nxgep, uint16_t index) 23954df55fdeSJanie Lu { 23964df55fdeSJanie Lu /* One entry reserved for IP fragment rule */ 23974df55fdeSJanie Lu if (index >= (nxgep->classifier.tcam_size - 1)) 23984df55fdeSJanie Lu index = 0; 23994df55fdeSJanie Lu if (nxgep->classifier.fragment_bug == 1) 24004df55fdeSJanie Lu index++; 24014df55fdeSJanie Lu return (nxgep->classifier.tcam_top + (index * nxgep->nports)); 24024df55fdeSJanie Lu } 24034df55fdeSJanie Lu 24044df55fdeSJanie Lu static uint32_t 24054df55fdeSJanie Lu nxge_tcam_cls_to_flow(uint32_t class_code) { 24064df55fdeSJanie Lu switch (class_code) { 24074df55fdeSJanie Lu case TCAM_CLASS_TCP_IPV4: 24084df55fdeSJanie Lu return (FSPEC_TCPIP4); 24094df55fdeSJanie Lu case TCAM_CLASS_UDP_IPV4: 24104df55fdeSJanie Lu return (FSPEC_UDPIP4); 24114df55fdeSJanie Lu case TCAM_CLASS_AH_ESP_IPV4: 24124df55fdeSJanie Lu return (FSPEC_AHIP4); 24134df55fdeSJanie Lu case TCAM_CLASS_SCTP_IPV4: 24144df55fdeSJanie Lu return (FSPEC_SCTPIP4); 24154df55fdeSJanie Lu case TCAM_CLASS_TCP_IPV6: 24164df55fdeSJanie Lu return (FSPEC_TCPIP6); 24174df55fdeSJanie Lu case TCAM_CLASS_UDP_IPV6: 24184df55fdeSJanie Lu return (FSPEC_UDPIP6); 24194df55fdeSJanie Lu case TCAM_CLASS_AH_ESP_IPV6: 24204df55fdeSJanie Lu return (FSPEC_AHIP6); 24214df55fdeSJanie Lu case TCAM_CLASS_SCTP_IPV6: 24224df55fdeSJanie Lu return (FSPEC_SCTPIP6); 24234df55fdeSJanie Lu case TCAM_CLASS_IP_USER_4: 24244df55fdeSJanie Lu case TCAM_CLASS_IP_USER_5: 24254df55fdeSJanie Lu case TCAM_CLASS_IP_USER_6: 24264df55fdeSJanie Lu case TCAM_CLASS_IP_USER_7: 24274df55fdeSJanie Lu return (FSPEC_IP_USR); 24284df55fdeSJanie Lu default: 24294df55fdeSJanie Lu NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "nxge_tcam_cls_to_flow" 24304df55fdeSJanie Lu ": Unknown class code [0x%x]", class_code)); 24314df55fdeSJanie Lu break; 24324df55fdeSJanie Lu } 24334df55fdeSJanie Lu return (0); 24344df55fdeSJanie Lu } 24354df55fdeSJanie Lu 24364df55fdeSJanie Lu void 24374df55fdeSJanie Lu nxge_get_tcam_entry(p_nxge_t nxgep, flow_resource_t *fs) 24384df55fdeSJanie Lu { 24394df55fdeSJanie Lu uint16_t index; 24404df55fdeSJanie Lu tcam_flow_spec_t *tcam_ep; 24414df55fdeSJanie Lu tcam_entry_t *tp; 24424df55fdeSJanie Lu flow_spec_t *fspec; 24434df55fdeSJanie Lu tcpip4_spec_t *fspec_key; 24444df55fdeSJanie Lu tcpip4_spec_t *fspec_mask; 24454df55fdeSJanie Lu 24464df55fdeSJanie Lu index = nxge_tcam_get_index(nxgep, (uint16_t)fs->location); 24474df55fdeSJanie Lu tcam_ep = &nxgep->classifier.tcam_entries[index]; 24484df55fdeSJanie Lu if (tcam_ep->valid != 1) { 24494df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry: :" 24504df55fdeSJanie Lu "Entry [%d] invalid for index [%d]", fs->location, index)); 24514df55fdeSJanie Lu return; 24524df55fdeSJanie Lu } 24534df55fdeSJanie Lu 24544df55fdeSJanie Lu /* Fill the flow spec entry */ 24554df55fdeSJanie Lu tp = &tcam_ep->tce; 24564df55fdeSJanie Lu fspec = &fs->flow_spec; 24574df55fdeSJanie Lu fspec->flow_type = nxge_tcam_cls_to_flow(tp->ip4_class_key); 24584df55fdeSJanie Lu 24594df55fdeSJanie Lu /* TODO - look at proto field to differentiate between AH and ESP */ 24604df55fdeSJanie Lu if (fspec->flow_type == FSPEC_AHIP4) { 24614df55fdeSJanie Lu if (tp->ip4_proto_key == IPPROTO_ESP) 24624df55fdeSJanie Lu fspec->flow_type = FSPEC_ESPIP4; 24634df55fdeSJanie Lu } 24644df55fdeSJanie Lu 24654df55fdeSJanie Lu switch (tp->ip4_class_key) { 24664df55fdeSJanie Lu case TCAM_CLASS_TCP_IPV4: 24674df55fdeSJanie Lu case TCAM_CLASS_UDP_IPV4: 24684df55fdeSJanie Lu case TCAM_CLASS_AH_ESP_IPV4: 24694df55fdeSJanie Lu case TCAM_CLASS_SCTP_IPV4: 24704df55fdeSJanie Lu fspec_key = (tcpip4_spec_t *)&fspec->uh.tcpip4spec; 24714df55fdeSJanie Lu fspec_mask = (tcpip4_spec_t *)&fspec->um.tcpip4spec; 24724df55fdeSJanie Lu FSPEC_IPV4_ADDR(fspec_key->ip4dst, tp->ip4_dest_key); 24734df55fdeSJanie Lu FSPEC_IPV4_ADDR(fspec_mask->ip4dst, tp->ip4_dest_mask); 24744df55fdeSJanie Lu FSPEC_IPV4_ADDR(fspec_key->ip4src, tp->ip4_src_key); 24754df55fdeSJanie Lu FSPEC_IPV4_ADDR(fspec_mask->ip4src, tp->ip4_src_mask); 24764df55fdeSJanie Lu fspec_key->tos = tp->ip4_tos_key; 24774df55fdeSJanie Lu fspec_mask->tos = tp->ip4_tos_mask; 24784df55fdeSJanie Lu break; 24794df55fdeSJanie Lu default: 24804df55fdeSJanie Lu break; 24814df55fdeSJanie Lu } 24824df55fdeSJanie Lu 24834df55fdeSJanie Lu switch (tp->ip4_class_key) { 24844df55fdeSJanie Lu case TCAM_CLASS_TCP_IPV4: 24854df55fdeSJanie Lu case TCAM_CLASS_UDP_IPV4: 24864df55fdeSJanie Lu case TCAM_CLASS_SCTP_IPV4: 24874df55fdeSJanie Lu FSPEC_IP_PORTS(fspec_key->pdst, fspec_key->psrc, 24884df55fdeSJanie Lu tp->ip4_port_key); 24894df55fdeSJanie Lu FSPEC_IP_PORTS(fspec_mask->pdst, fspec_mask->psrc, 24904df55fdeSJanie Lu tp->ip4_port_mask); 24914df55fdeSJanie Lu break; 24924df55fdeSJanie Lu case TCAM_CLASS_AH_ESP_IPV4: 24934df55fdeSJanie Lu fspec->uh.ahip4spec.spi = tp->ip4_port_key; 24944df55fdeSJanie Lu fspec->um.ahip4spec.spi = tp->ip4_port_mask; 24954df55fdeSJanie Lu break; 24964df55fdeSJanie Lu case TCAM_CLASS_IP_USER_4: 24974df55fdeSJanie Lu case TCAM_CLASS_IP_USER_5: 24984df55fdeSJanie Lu case TCAM_CLASS_IP_USER_6: 24994df55fdeSJanie Lu case TCAM_CLASS_IP_USER_7: 25004df55fdeSJanie Lu fspec->uh.ip_usr_spec.l4_4_bytes = tp->ip4_port_key; 25014df55fdeSJanie Lu fspec->um.ip_usr_spec.l4_4_bytes = tp->ip4_port_mask; 25024df55fdeSJanie Lu fspec->uh.ip_usr_spec.ip_ver = FSPEC_IP4; 25034df55fdeSJanie Lu fspec->uh.ip_usr_spec.proto = tp->ip4_proto_key; 25044df55fdeSJanie Lu fspec->um.ip_usr_spec.proto = tp->ip4_proto_mask; 25054df55fdeSJanie Lu break; 25064df55fdeSJanie Lu default: 25074df55fdeSJanie Lu break; 25084df55fdeSJanie Lu } 25094df55fdeSJanie Lu 25104df55fdeSJanie Lu if (tp->match_action.bits.ldw.disc == 1) { 25114df55fdeSJanie Lu fs->channel_cookie = NXGE_PKT_DISCARD; 25124df55fdeSJanie Lu } else { 25134df55fdeSJanie Lu fs->channel_cookie = tp->match_action.bits.ldw.offset; 25144df55fdeSJanie Lu } 25154df55fdeSJanie Lu } 25164df55fdeSJanie Lu 25174df55fdeSJanie Lu void 25184df55fdeSJanie Lu nxge_del_tcam_entry(p_nxge_t nxgep, uint32_t location) 25194df55fdeSJanie Lu { 25204df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 25214df55fdeSJanie Lu uint16_t index; 25224df55fdeSJanie Lu tcam_flow_spec_t *tcam_ep; 25234df55fdeSJanie Lu tcam_entry_t *tp; 25244df55fdeSJanie Lu tcam_class_t class; 25254df55fdeSJanie Lu 25264df55fdeSJanie Lu MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 25274df55fdeSJanie Lu index = nxge_tcam_get_index(nxgep, (uint16_t)location); 25284df55fdeSJanie Lu tcam_ep = &nxgep->classifier.tcam_entries[index]; 25294df55fdeSJanie Lu if (tcam_ep->valid != 1) { 25304df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_tcam_entry: :" 25314df55fdeSJanie Lu "Entry [%d] invalid for index [%d]", location, index)); 25324df55fdeSJanie Lu goto fail; 25334df55fdeSJanie Lu } 25344df55fdeSJanie Lu 25354df55fdeSJanie Lu /* Fill the flow spec entry */ 25364df55fdeSJanie Lu tp = &tcam_ep->tce; 25374df55fdeSJanie Lu class = tp->ip4_class_key; 25384df55fdeSJanie Lu if (class >= TCAM_CLASS_IP_USER_4 && class <= TCAM_CLASS_IP_USER_7) { 25394df55fdeSJanie Lu int i; 25404df55fdeSJanie Lu nxge_usr_l3_cls_t *l3_ucls_p; 25414df55fdeSJanie Lu p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 25424df55fdeSJanie Lu 25434df55fdeSJanie Lu for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 25444df55fdeSJanie Lu l3_ucls_p = &hw_p->tcam_l3_prog_cls[i]; 25454df55fdeSJanie Lu if (l3_ucls_p->valid) { 25464df55fdeSJanie Lu if (l3_ucls_p->cls == class && 25474df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt) { 25484df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt--; 25494df55fdeSJanie Lu if (l3_ucls_p->tcam_ref_cnt > 0) 25504df55fdeSJanie Lu continue; 25514df55fdeSJanie Lu /* disable class */ 25524df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_disable( 25534df55fdeSJanie Lu nxgep->npi_reg_handle, 25544df55fdeSJanie Lu (tcam_class_t)class); 25554df55fdeSJanie Lu if (rs != NPI_SUCCESS) 25564df55fdeSJanie Lu goto fail; 25574df55fdeSJanie Lu l3_ucls_p->cls = 0; 25584df55fdeSJanie Lu l3_ucls_p->pid = 0; 25594df55fdeSJanie Lu l3_ucls_p->valid = 0; 25604df55fdeSJanie Lu break; 25614df55fdeSJanie Lu } 25624df55fdeSJanie Lu } 25634df55fdeSJanie Lu } 25644df55fdeSJanie Lu if (i == NXGE_L3_PROG_CLS) { 25654df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 25664df55fdeSJanie Lu "nxge_del_tcam_entry: Usr class " 25674df55fdeSJanie Lu "0x%llx not found", (unsigned long long) class)); 25684df55fdeSJanie Lu goto fail; 25694df55fdeSJanie Lu } 25704df55fdeSJanie Lu } 25714df55fdeSJanie Lu 25724df55fdeSJanie Lu rs = npi_fflp_tcam_entry_invalidate(nxgep->npi_reg_handle, index); 25734df55fdeSJanie Lu if (rs != NPI_SUCCESS) { 25744df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 25754df55fdeSJanie Lu "nxge_del_tcam_entry: TCAM invalidate failed " 25764df55fdeSJanie Lu "at loc %d ", location)); 25774df55fdeSJanie Lu goto fail; 25784df55fdeSJanie Lu } 25794df55fdeSJanie Lu 25804df55fdeSJanie Lu nxgep->classifier.tcam_entries[index].valid = 0; 25814df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt--; 25824df55fdeSJanie Lu 25834df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 25844df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_del_tcam_entry")); 25854df55fdeSJanie Lu return; 25864df55fdeSJanie Lu fail: 25874df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 25884df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 25894df55fdeSJanie Lu "<== nxge_del_tcam_entry FAILED")); 25904df55fdeSJanie Lu } 25914df55fdeSJanie Lu 25924df55fdeSJanie Lu static uint8_t 25934df55fdeSJanie Lu nxge_iptun_pkt_type_to_pid(uint8_t pkt_type) 25944df55fdeSJanie Lu { 25954df55fdeSJanie Lu uint8_t pid = 0; 25964df55fdeSJanie Lu 25974df55fdeSJanie Lu switch (pkt_type) { 25984df55fdeSJanie Lu case IPTUN_PKT_IPV4: 25994df55fdeSJanie Lu pid = 4; 26004df55fdeSJanie Lu break; 26014df55fdeSJanie Lu case IPTUN_PKT_IPV6: 26024df55fdeSJanie Lu pid = 41; 26034df55fdeSJanie Lu break; 26044df55fdeSJanie Lu case IPTUN_PKT_GRE: 26054df55fdeSJanie Lu pid = 47; 26064df55fdeSJanie Lu break; 26074df55fdeSJanie Lu case IPTUN_PKT_GTP: 26084df55fdeSJanie Lu pid = 17; 26094df55fdeSJanie Lu break; 26104df55fdeSJanie Lu default: 26114df55fdeSJanie Lu NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 26124df55fdeSJanie Lu "nxge_iptun_pkt_type_to_pid: Unknown pkt type 0x%x", 26134df55fdeSJanie Lu pkt_type)); 26144df55fdeSJanie Lu break; 26154df55fdeSJanie Lu } 26164df55fdeSJanie Lu 26174df55fdeSJanie Lu return (pid); 26184df55fdeSJanie Lu } 26194df55fdeSJanie Lu 26204df55fdeSJanie Lu static npi_status_t 26214df55fdeSJanie Lu nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep, uint64_t class, 26224df55fdeSJanie Lu iptun_cfg_t *iptunp) 26234df55fdeSJanie Lu { 26244df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 26254df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 26264df55fdeSJanie Lu 26274df55fdeSJanie Lu switch (iptunp->in_pkt_type) { 26284df55fdeSJanie Lu case IPTUN_PKT_IPV4: 26294df55fdeSJanie Lu case IPTUN_PKT_IPV6: 26304df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 26314df55fdeSJanie Lu (tcam_class_t)class, 0, 0, 0, 0); 26324df55fdeSJanie Lu break; 26334df55fdeSJanie Lu case IPTUN_PKT_GRE: 26344df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 26354df55fdeSJanie Lu (tcam_class_t)class, iptunp->l4b0_val, 26364df55fdeSJanie Lu iptunp->l4b0_mask, 0, 0); 26374df55fdeSJanie Lu break; 26384df55fdeSJanie Lu case IPTUN_PKT_GTP: 26394df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 26404df55fdeSJanie Lu (tcam_class_t)class, 0, 0, iptunp->l4b23_val, 26414df55fdeSJanie Lu (iptunp->l4b23_sel & 0x01)); 26424df55fdeSJanie Lu break; 26434df55fdeSJanie Lu default: 26444df55fdeSJanie Lu rs = NPI_FFLP_TCAM_CLASS_INVALID; 26454df55fdeSJanie Lu break; 26464df55fdeSJanie Lu } 26474df55fdeSJanie Lu return (rs); 26484df55fdeSJanie Lu } 26494df55fdeSJanie Lu 26504df55fdeSJanie Lu void 26514df55fdeSJanie Lu nxge_add_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, 26524df55fdeSJanie Lu uint8_t *cls_idp) 26534df55fdeSJanie Lu { 26544df55fdeSJanie Lu int i, add_cls; 26554df55fdeSJanie Lu uint8_t pid; 26564df55fdeSJanie Lu uint64_t class; 26574df55fdeSJanie Lu p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 26584df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 26594df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 26604df55fdeSJanie Lu 26614df55fdeSJanie Lu pid = nxge_iptun_pkt_type_to_pid(iptunp->in_pkt_type); 26624df55fdeSJanie Lu if (pid == 0) 26634df55fdeSJanie Lu return; 26644df55fdeSJanie Lu 26654df55fdeSJanie Lu add_cls = 0; 26664df55fdeSJanie Lu MUTEX_ENTER(&hw_p->nxge_tcam_lock); 26674df55fdeSJanie Lu 26684df55fdeSJanie Lu /* Get an user programmable class ID */ 26694df55fdeSJanie Lu for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 26704df55fdeSJanie Lu if (hw_p->tcam_l3_prog_cls[i].valid == 0) { 26714df55fdeSJanie Lu /* todo add new usr class reg */ 26724df55fdeSJanie Lu switch (i) { 26734df55fdeSJanie Lu case 0: 26744df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_4; 26754df55fdeSJanie Lu break; 26764df55fdeSJanie Lu case 1: 26774df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_5; 26784df55fdeSJanie Lu break; 26794df55fdeSJanie Lu case 2: 26804df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_6; 26814df55fdeSJanie Lu break; 26824df55fdeSJanie Lu case 3: 26834df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_7; 26844df55fdeSJanie Lu break; 26854df55fdeSJanie Lu default: 26864df55fdeSJanie Lu break; 26874df55fdeSJanie Lu } 26884df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set(handle, 26894df55fdeSJanie Lu (tcam_class_t)class, 0, 0, pid, 0); 26904df55fdeSJanie Lu if (rs != NPI_SUCCESS) 26914df55fdeSJanie Lu goto fail; 26924df55fdeSJanie Lu 26934df55fdeSJanie Lu rs = nxge_set_iptun_usr_cls_reg(nxgep, class, iptunp); 26944df55fdeSJanie Lu 26954df55fdeSJanie Lu if (rs != NPI_SUCCESS) 26964df55fdeSJanie Lu goto fail; 26974df55fdeSJanie Lu 26984df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 26994df55fdeSJanie Lu (tcam_class_t)class); 27004df55fdeSJanie Lu if (rs != NPI_SUCCESS) 27014df55fdeSJanie Lu goto fail; 27024df55fdeSJanie Lu 27034df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].cls = class; 27044df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].pid = pid; 27054df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 27064df55fdeSJanie Lu iptunp->in_pkt_type; 27074df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].valid = 1; 27084df55fdeSJanie Lu *cls_idp = (uint8_t)class; 27094df55fdeSJanie Lu add_cls = 1; 27104df55fdeSJanie Lu break; 27114df55fdeSJanie Lu } else if (hw_p->tcam_l3_prog_cls[i].pid == pid) { 27124df55fdeSJanie Lu if (hw_p->tcam_l3_prog_cls[i].flow_pkt_type == 0) { 27134df55fdeSJanie Lu /* there is no flow key */ 27144df55fdeSJanie Lu /* todo program the existing usr class reg */ 27154df55fdeSJanie Lu 27164df55fdeSJanie Lu rs = nxge_set_iptun_usr_cls_reg(nxgep, class, 27174df55fdeSJanie Lu iptunp); 27184df55fdeSJanie Lu if (rs != NPI_SUCCESS) 27194df55fdeSJanie Lu goto fail; 27204df55fdeSJanie Lu 27214df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 27224df55fdeSJanie Lu (tcam_class_t)class); 27234df55fdeSJanie Lu if (rs != NPI_SUCCESS) 27244df55fdeSJanie Lu goto fail; 27254df55fdeSJanie Lu 27264df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 27274df55fdeSJanie Lu iptunp->in_pkt_type; 27284df55fdeSJanie Lu *cls_idp = (uint8_t)class; 27294df55fdeSJanie Lu add_cls = 1; 27304df55fdeSJanie Lu } else { 27314df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 27324df55fdeSJanie Lu "nxge_add_iptun_class: L3 usr " 27334df55fdeSJanie Lu "programmable class with pid %d " 27344df55fdeSJanie Lu "already exists", pid)); 27354df55fdeSJanie Lu } 27364df55fdeSJanie Lu break; 27374df55fdeSJanie Lu } 27384df55fdeSJanie Lu } 27394df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 27404df55fdeSJanie Lu 27414df55fdeSJanie Lu if (add_cls != 1) { 27424df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 27434df55fdeSJanie Lu "nxge_add_iptun_class: Could not add IP tunneling class")); 27444df55fdeSJanie Lu } 27454df55fdeSJanie Lu return; 27464df55fdeSJanie Lu fail: 27474df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 27484df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_iptun_class: FAILED")); 27494df55fdeSJanie Lu } 27504df55fdeSJanie Lu 27514df55fdeSJanie Lu static boolean_t 27524df55fdeSJanie Lu nxge_is_iptun_cls_present(p_nxge_t nxgep, uint8_t cls_id, int *idx) 27534df55fdeSJanie Lu { 27544df55fdeSJanie Lu int i; 27554df55fdeSJanie Lu p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 27564df55fdeSJanie Lu 27574df55fdeSJanie Lu MUTEX_ENTER(&hw_p->nxge_tcam_lock); 27584df55fdeSJanie Lu for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 27594df55fdeSJanie Lu if (hw_p->tcam_l3_prog_cls[i].valid && 27604df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].flow_pkt_type != 0) { 27614df55fdeSJanie Lu if (hw_p->tcam_l3_prog_cls[i].cls == cls_id) 27624df55fdeSJanie Lu break; 27634df55fdeSJanie Lu } 27644df55fdeSJanie Lu } 27654df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 27664df55fdeSJanie Lu 27674df55fdeSJanie Lu if (i == NXGE_L3_PROG_CLS) { 27684df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 27694df55fdeSJanie Lu "nxge_is_iptun_cls_present: Invalid class %d", cls_id)); 27704df55fdeSJanie Lu return (B_FALSE); 27714df55fdeSJanie Lu } else { 27724df55fdeSJanie Lu *idx = i; 27734df55fdeSJanie Lu return (B_TRUE); 27744df55fdeSJanie Lu } 27754df55fdeSJanie Lu } 27764df55fdeSJanie Lu 27774df55fdeSJanie Lu void 27784df55fdeSJanie Lu nxge_cfg_iptun_hash(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id) 27794df55fdeSJanie Lu { 27804df55fdeSJanie Lu int idx; 27814df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 27824df55fdeSJanie Lu flow_key_cfg_t cfg; 27834df55fdeSJanie Lu 27844df55fdeSJanie Lu /* check to see that this is a valid class ID */ 27854df55fdeSJanie Lu if (!nxge_is_iptun_cls_present(nxgep, cls_id, &idx)) { 27864df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 27874df55fdeSJanie Lu "nxge_cfg_iptun_hash: nxge_is_iptun_cls_present " 27884df55fdeSJanie Lu "failed for cls_id %d", cls_id)); 27894df55fdeSJanie Lu return; 27904df55fdeSJanie Lu } 27914df55fdeSJanie Lu 27924df55fdeSJanie Lu bzero((void *)&cfg, sizeof (flow_key_cfg_t)); 27934df55fdeSJanie Lu 27944df55fdeSJanie Lu /* 27954df55fdeSJanie Lu * This ensures that all 4 bytes of the XOR value are loaded to the 27964df55fdeSJanie Lu * hash key. 27974df55fdeSJanie Lu */ 27984df55fdeSJanie Lu cfg.use_dport = cfg.use_sport = cfg.ip_opts_exist = 1; 27994df55fdeSJanie Lu 28004df55fdeSJanie Lu cfg.l4_xor_sel = (iptunp->l4xor_sel & FL_KEY_USR_L4XOR_MSK); 28014df55fdeSJanie Lu cfg.use_l4_md = 1; 28024df55fdeSJanie Lu 28034df55fdeSJanie Lu if (iptunp->hash_flags & HASH_L3PROTO) 28044df55fdeSJanie Lu cfg.use_proto = 1; 28054df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_IPDA) 28064df55fdeSJanie Lu cfg.use_daddr = 1; 28074df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_IPSA) 28084df55fdeSJanie Lu cfg.use_saddr = 1; 28094df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_VLAN) 28104df55fdeSJanie Lu cfg.use_vlan = 1; 28114df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_L2DA) 28124df55fdeSJanie Lu cfg.use_l2da = 1; 28134df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_IFPORT) 28144df55fdeSJanie Lu cfg.use_portnum = 1; 28154df55fdeSJanie Lu 28164df55fdeSJanie Lu (void) npi_fflp_cfg_ip_cls_flow_key_rfnl(handle, (tcam_class_t)cls_id, 28174df55fdeSJanie Lu &cfg); 28184df55fdeSJanie Lu } 28194df55fdeSJanie Lu 28204df55fdeSJanie Lu void 28214df55fdeSJanie Lu nxge_del_iptun_class(p_nxge_t nxgep, uint8_t cls_id) 28224df55fdeSJanie Lu { 28234df55fdeSJanie Lu int i; 28244df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 28254df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 28264df55fdeSJanie Lu 28274df55fdeSJanie Lu 28284df55fdeSJanie Lu /* check to see that this is a valid class ID */ 28294df55fdeSJanie Lu if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) { 28304df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 28314df55fdeSJanie Lu "nxge_del_iptun_class: Invalid class ID 0x%x", cls_id)); 28324df55fdeSJanie Lu return; 28334df55fdeSJanie Lu } 28344df55fdeSJanie Lu 28354df55fdeSJanie Lu MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 28364df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_disable(handle, (tcam_class_t)cls_id); 28374df55fdeSJanie Lu if (rs != NPI_SUCCESS) 28384df55fdeSJanie Lu goto fail; 28394df55fdeSJanie Lu nxgep->nxge_hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 0; 28404df55fdeSJanie Lu if (nxgep->nxge_hw_p->tcam_l3_prog_cls[i].tcam_ref_cnt == 0) 28414df55fdeSJanie Lu nxgep->nxge_hw_p->tcam_l3_prog_cls[i].valid = 0; 28424df55fdeSJanie Lu 28434df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 28444df55fdeSJanie Lu return; 28454df55fdeSJanie Lu fail: 28464df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 28474df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_iptun_class: FAILED")); 28484df55fdeSJanie Lu } 28494df55fdeSJanie Lu 28504df55fdeSJanie Lu void 28514df55fdeSJanie Lu nxge_get_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id) 28524df55fdeSJanie Lu { 28534df55fdeSJanie Lu int i; 28544df55fdeSJanie Lu uint8_t pid; 28554df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 28564df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 28574df55fdeSJanie Lu flow_key_cfg_t cfg; 28584df55fdeSJanie Lu 28594df55fdeSJanie Lu 28604df55fdeSJanie Lu /* check to see that this is a valid class ID */ 28614df55fdeSJanie Lu if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) 28624df55fdeSJanie Lu return; 28634df55fdeSJanie Lu 28644df55fdeSJanie Lu bzero((void *)iptunp, sizeof (iptun_cfg_t)); 28654df55fdeSJanie Lu 28664df55fdeSJanie Lu pid = nxgep->nxge_hw_p->tcam_l3_prog_cls[i].pid; 28674df55fdeSJanie Lu 28684df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_get_iptun(handle, (tcam_class_t)cls_id, 28694df55fdeSJanie Lu &iptunp->l4b0_val, &iptunp->l4b0_mask, &iptunp->l4b23_val, 28704df55fdeSJanie Lu &iptunp->l4b23_sel); 28714df55fdeSJanie Lu if (rs != NPI_SUCCESS) 28724df55fdeSJanie Lu goto fail; 28734df55fdeSJanie Lu 28744df55fdeSJanie Lu rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle, 28754df55fdeSJanie Lu (tcam_class_t)cls_id, &cfg); 28764df55fdeSJanie Lu if (rs != NPI_SUCCESS) 28774df55fdeSJanie Lu goto fail; 28784df55fdeSJanie Lu 28794df55fdeSJanie Lu iptunp->l4xor_sel = cfg.l4_xor_sel; 28804df55fdeSJanie Lu if (cfg.use_proto) 28814df55fdeSJanie Lu iptunp->hash_flags |= HASH_L3PROTO; 28824df55fdeSJanie Lu else if (cfg.use_daddr) 28834df55fdeSJanie Lu iptunp->hash_flags |= HASH_IPDA; 28844df55fdeSJanie Lu else if (cfg.use_saddr) 28854df55fdeSJanie Lu iptunp->hash_flags |= HASH_IPSA; 28864df55fdeSJanie Lu else if (cfg.use_vlan) 28874df55fdeSJanie Lu iptunp->hash_flags |= HASH_VLAN; 28884df55fdeSJanie Lu else if (cfg.use_l2da) 28894df55fdeSJanie Lu iptunp->hash_flags |= HASH_L2DA; 28904df55fdeSJanie Lu else if (cfg.use_portnum) 28914df55fdeSJanie Lu iptunp->hash_flags |= HASH_IFPORT; 28924df55fdeSJanie Lu 28934df55fdeSJanie Lu switch (pid) { 28944df55fdeSJanie Lu case 4: 28954df55fdeSJanie Lu iptunp->in_pkt_type = IPTUN_PKT_IPV4; 28964df55fdeSJanie Lu break; 28974df55fdeSJanie Lu case 41: 28984df55fdeSJanie Lu iptunp->in_pkt_type = IPTUN_PKT_IPV6; 28994df55fdeSJanie Lu break; 29004df55fdeSJanie Lu case 47: 29014df55fdeSJanie Lu iptunp->in_pkt_type = IPTUN_PKT_GRE; 29024df55fdeSJanie Lu break; 29034df55fdeSJanie Lu case 17: 29044df55fdeSJanie Lu iptunp->in_pkt_type = IPTUN_PKT_GTP; 29054df55fdeSJanie Lu break; 29064df55fdeSJanie Lu default: 29074df55fdeSJanie Lu iptunp->in_pkt_type = 0; 29084df55fdeSJanie Lu break; 29094df55fdeSJanie Lu } 29104df55fdeSJanie Lu 29114df55fdeSJanie Lu return; 29124df55fdeSJanie Lu fail: 29134df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_iptun_class: FAILED")); 29144df55fdeSJanie Lu } 29154df55fdeSJanie Lu 29164df55fdeSJanie Lu void 29174df55fdeSJanie Lu nxge_set_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t sym) 29184df55fdeSJanie Lu { 29194df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 29204df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 29214df55fdeSJanie Lu boolean_t sym_en = (sym == 1) ? B_TRUE : B_FALSE; 29224df55fdeSJanie Lu 29234df55fdeSJanie Lu rs = npi_fflp_cfg_sym_ip_cls_flow_key(handle, (tcam_class_t)cls_id, 29244df55fdeSJanie Lu sym_en); 29254df55fdeSJanie Lu if (rs != NPI_SUCCESS) 29264df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 29274df55fdeSJanie Lu "nxge_set_ip_cls_sym: FAILED")); 29284df55fdeSJanie Lu } 29294df55fdeSJanie Lu 29304df55fdeSJanie Lu void 29314df55fdeSJanie Lu nxge_get_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t *sym) 29324df55fdeSJanie Lu { 29334df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 29344df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 29354df55fdeSJanie Lu flow_key_cfg_t cfg; 29364df55fdeSJanie Lu 29374df55fdeSJanie Lu rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle, 29384df55fdeSJanie Lu (tcam_class_t)cls_id, &cfg); 29394df55fdeSJanie Lu if (rs != NPI_SUCCESS) 29404df55fdeSJanie Lu goto fail; 29414df55fdeSJanie Lu 29424df55fdeSJanie Lu if (cfg.use_sym) 29434df55fdeSJanie Lu *sym = 1; 29444df55fdeSJanie Lu else 29454df55fdeSJanie Lu *sym = 0; 29464df55fdeSJanie Lu return; 29474df55fdeSJanie Lu fail: 29484df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_ip_cls_sym: FAILED")); 29494df55fdeSJanie Lu } 2950