144961713Sgirish /* 244961713Sgirish * CDDL HEADER START 344961713Sgirish * 444961713Sgirish * The contents of this file are subject to the terms of the 544961713Sgirish * Common Development and Distribution License (the "License"). 644961713Sgirish * You may not use this file except in compliance with the License. 744961713Sgirish * 844961713Sgirish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 944961713Sgirish * or http://www.opensolaris.org/os/licensing. 1044961713Sgirish * See the License for the specific language governing permissions 1144961713Sgirish * and limitations under the License. 1244961713Sgirish * 1344961713Sgirish * When distributing Covered Code, include this CDDL HEADER in each 1444961713Sgirish * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1544961713Sgirish * If applicable, add the following below this CDDL HEADER, with the 1644961713Sgirish * fields enclosed by brackets "[]" replaced with your own identifying 1744961713Sgirish * information: Portions Copyright [yyyy] [name of copyright owner] 1844961713Sgirish * 1944961713Sgirish * CDDL HEADER END 2044961713Sgirish */ 2144961713Sgirish /* 22*4df55fdeSJanie Lu * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2344961713Sgirish * Use is subject to license terms. 2444961713Sgirish */ 2544961713Sgirish 2644961713Sgirish #include <npi_fflp.h> 2744961713Sgirish #include <npi_mac.h> 2844961713Sgirish #include <nxge_defs.h> 2944961713Sgirish #include <nxge_flow.h> 3044961713Sgirish #include <nxge_fflp.h> 3144961713Sgirish #include <nxge_impl.h> 3244961713Sgirish #include <nxge_fflp_hash.h> 3344961713Sgirish #include <nxge_common.h> 3444961713Sgirish 3544961713Sgirish 36a3c5bd6dSspeer /* 37a3c5bd6dSspeer * Function prototypes 38a3c5bd6dSspeer */ 3944961713Sgirish static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t); 4044961713Sgirish static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t); 4144961713Sgirish static nxge_status_t nxge_fflp_tcam_init(p_nxge_t); 4244961713Sgirish static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t); 4344961713Sgirish static nxge_status_t nxge_fflp_fcram_init(p_nxge_t); 4444961713Sgirish static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *); 45a3c5bd6dSspeer static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 46a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 47a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 4844961713Sgirish static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *, 49a3c5bd6dSspeer tcam_entry_t *); 50a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *, 51a3c5bd6dSspeer tcam_entry_t *); 52a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *, 53a3c5bd6dSspeer tcam_entry_t *); 54*4df55fdeSJanie Lu static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t); 55*4df55fdeSJanie Lu static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t); 56*4df55fdeSJanie Lu static uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t); 57*4df55fdeSJanie Lu static uint32_t nxge_tcam_cls_to_flow(uint32_t); 58*4df55fdeSJanie Lu static uint8_t nxge_iptun_pkt_type_to_pid(uint8_t); 59*4df55fdeSJanie Lu static npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t, 60*4df55fdeSJanie Lu iptun_cfg_t *); 61*4df55fdeSJanie Lu static boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *); 6244961713Sgirish 63a3c5bd6dSspeer /* 64a3c5bd6dSspeer * functions used outside this file 65a3c5bd6dSspeer */ 6644961713Sgirish nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t); 6744961713Sgirish nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t); 6844961713Sgirish nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *); 6914ea4bb7Ssd static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t); 7044961713Sgirish nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *); 7144961713Sgirish nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *); 7244961713Sgirish nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *, 73a3c5bd6dSspeer uint32_t *, uint16_t *); 74*4df55fdeSJanie Lu int nxge_get_valid_tcam_cnt(p_nxge_t); 75*4df55fdeSJanie Lu void nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *); 76*4df55fdeSJanie Lu void nxge_get_tcam_entry(p_nxge_t, flow_resource_t *); 77*4df55fdeSJanie Lu void nxge_del_tcam_entry(p_nxge_t, uint32_t); 78*4df55fdeSJanie Lu void nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *); 79*4df55fdeSJanie Lu void nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t); 80*4df55fdeSJanie Lu void nxge_del_iptun_class(p_nxge_t, uint8_t); 81*4df55fdeSJanie Lu void nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t); 82*4df55fdeSJanie Lu void nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t); 83*4df55fdeSJanie Lu void nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *); 84*4df55fdeSJanie Lu 8544961713Sgirish 8644961713Sgirish nxge_status_t 8744961713Sgirish nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location) 8844961713Sgirish { 8944961713Sgirish tcam_entry_t tcam_rdptr; 9044961713Sgirish uint64_t asc_ram = 0; 9144961713Sgirish npi_handle_t handle; 9244961713Sgirish npi_status_t status; 9344961713Sgirish 9444961713Sgirish handle = nxgep->npi_reg_handle; 9544961713Sgirish 9644961713Sgirish bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry)); 9744961713Sgirish status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location, 9852ccf843Smisaki (struct tcam_entry *)&tcam_rdptr); 9944961713Sgirish if (status & NPI_FAILURE) { 10044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 10152ccf843Smisaki " nxge_tcam_dump_entry:" 10252ccf843Smisaki " tcam read failed at location %d ", location)); 10344961713Sgirish return (NXGE_ERROR); 10444961713Sgirish } 10544961713Sgirish status = npi_fflp_tcam_asc_ram_entry_read(handle, 10652ccf843Smisaki (tcam_location_t)location, &asc_ram); 10744961713Sgirish 10844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n" 10952ccf843Smisaki " key: %llx %llx %llx %llx \n" 11052ccf843Smisaki " mask: %llx %llx %llx %llx \n" 11152ccf843Smisaki " ASC RAM %llx \n", location, 11252ccf843Smisaki tcam_rdptr.key0, tcam_rdptr.key1, 11352ccf843Smisaki tcam_rdptr.key2, tcam_rdptr.key3, 11452ccf843Smisaki tcam_rdptr.mask0, tcam_rdptr.mask1, 11552ccf843Smisaki tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram)); 11644961713Sgirish return (NXGE_OK); 11744961713Sgirish } 11844961713Sgirish 11944961713Sgirish void 12044961713Sgirish nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp) 12144961713Sgirish { 12244961713Sgirish uint32_t tcam_loc; 12344961713Sgirish int *lptr; 12444961713Sgirish int location; 12544961713Sgirish 12644961713Sgirish uint32_t start_location = 0; 12744961713Sgirish uint32_t stop_location = nxgep->classifier.tcam_size; 12844961713Sgirish lptr = (int *)mp->b_rptr; 12944961713Sgirish location = *lptr; 13044961713Sgirish 13144961713Sgirish if ((location >= nxgep->classifier.tcam_size) || (location < -1)) { 13244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 13352ccf843Smisaki "nxge_tcam_dump: Invalid location %d \n", location)); 13444961713Sgirish return; 13544961713Sgirish } 13644961713Sgirish if (location == -1) { 13744961713Sgirish start_location = 0; 13844961713Sgirish stop_location = nxgep->classifier.tcam_size; 13944961713Sgirish } else { 14044961713Sgirish start_location = location; 141a3c5bd6dSspeer stop_location = location + 1; 14244961713Sgirish } 14344961713Sgirish for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++) 14444961713Sgirish (void) nxge_tcam_dump_entry(nxgep, tcam_loc); 14544961713Sgirish } 14644961713Sgirish 14744961713Sgirish /* 14844961713Sgirish * nxge_fflp_vlan_table_invalidate_all 14944961713Sgirish * invalidates the vlan RDC table entries. 15044961713Sgirish * INPUT 15144961713Sgirish * nxge soft state data structure 15244961713Sgirish * Return 15344961713Sgirish * NXGE_OK 15444961713Sgirish * NXGE_ERROR 15544961713Sgirish * 15644961713Sgirish */ 157a3c5bd6dSspeer 15844961713Sgirish static nxge_status_t 15944961713Sgirish nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep) 16044961713Sgirish { 16144961713Sgirish vlan_id_t vlan_id; 16244961713Sgirish npi_handle_t handle; 16344961713Sgirish npi_status_t rs = NPI_SUCCESS; 16444961713Sgirish vlan_id_t start = 0, stop = NXGE_MAX_VLANS; 16544961713Sgirish 16644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all ")); 16744961713Sgirish handle = nxgep->npi_reg_handle; 16844961713Sgirish for (vlan_id = start; vlan_id < stop; vlan_id++) { 16944961713Sgirish rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id); 17044961713Sgirish if (rs != NPI_SUCCESS) { 17144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17252ccf843Smisaki "VLAN Table invalidate failed for vlan id %d ", 17352ccf843Smisaki vlan_id)); 17444961713Sgirish return (NXGE_ERROR | rs); 17544961713Sgirish } 17644961713Sgirish } 17744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all ")); 17844961713Sgirish return (NXGE_OK); 17944961713Sgirish } 18044961713Sgirish 18144961713Sgirish /* 18244961713Sgirish * The following functions are used by other modules to init 18344961713Sgirish * the fflp module. 18444961713Sgirish * these functions are the basic API used to init 18544961713Sgirish * the fflp modules (tcam, fcram etc ......) 18644961713Sgirish * 18744961713Sgirish * The TCAM search future would be disabled by default. 18844961713Sgirish */ 18944961713Sgirish 19044961713Sgirish static nxge_status_t 19144961713Sgirish nxge_fflp_tcam_init(p_nxge_t nxgep) 19244961713Sgirish { 19344961713Sgirish uint8_t access_ratio; 19444961713Sgirish tcam_class_t class; 19544961713Sgirish npi_status_t rs = NPI_SUCCESS; 19644961713Sgirish npi_handle_t handle; 19744961713Sgirish 19844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init")); 19944961713Sgirish handle = nxgep->npi_reg_handle; 20044961713Sgirish 20144961713Sgirish rs = npi_fflp_cfg_tcam_disable(handle); 20244961713Sgirish if (rs != NPI_SUCCESS) { 20344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n")); 20444961713Sgirish return (NXGE_ERROR | rs); 20544961713Sgirish } 20644961713Sgirish 20744961713Sgirish access_ratio = nxgep->param_arr[param_tcam_access_ratio].value; 20844961713Sgirish rs = npi_fflp_cfg_tcam_access(handle, access_ratio); 20944961713Sgirish if (rs != NPI_SUCCESS) { 21044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21152ccf843Smisaki "failed TCAM Access cfg\n")); 21244961713Sgirish return (NXGE_ERROR | rs); 21344961713Sgirish } 21444961713Sgirish 215a3c5bd6dSspeer /* disable configurable classes */ 216a3c5bd6dSspeer /* disable the configurable ethernet classes; */ 21744961713Sgirish for (class = TCAM_CLASS_ETYPE_1; 21852ccf843Smisaki class <= TCAM_CLASS_ETYPE_2; class++) { 21944961713Sgirish rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class); 22044961713Sgirish if (rs != NPI_SUCCESS) { 22144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 22252ccf843Smisaki "TCAM USR Ether Class config failed.")); 22344961713Sgirish return (NXGE_ERROR | rs); 22444961713Sgirish } 22544961713Sgirish } 22644961713Sgirish 227a3c5bd6dSspeer /* disable the configurable ip classes; */ 22844961713Sgirish for (class = TCAM_CLASS_IP_USER_4; 22952ccf843Smisaki class <= TCAM_CLASS_IP_USER_7; class++) { 23044961713Sgirish rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 23144961713Sgirish if (rs != NPI_SUCCESS) { 23244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 23352ccf843Smisaki "TCAM USR IP Class cnfg failed.")); 23444961713Sgirish return (NXGE_ERROR | rs); 23544961713Sgirish } 23644961713Sgirish } 23744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init")); 23844961713Sgirish return (NXGE_OK); 23944961713Sgirish } 24044961713Sgirish 24144961713Sgirish /* 24244961713Sgirish * nxge_fflp_tcam_invalidate_all 24344961713Sgirish * invalidates all the tcam entries. 24444961713Sgirish * INPUT 24544961713Sgirish * nxge soft state data structure 24644961713Sgirish * Return 24744961713Sgirish * NXGE_OK 24844961713Sgirish * NXGE_ERROR 24944961713Sgirish * 25044961713Sgirish */ 251a3c5bd6dSspeer 252a3c5bd6dSspeer 25344961713Sgirish static nxge_status_t 25444961713Sgirish nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep) 25544961713Sgirish { 25644961713Sgirish uint16_t location; 25744961713Sgirish npi_status_t rs = NPI_SUCCESS; 25844961713Sgirish npi_handle_t handle; 25944961713Sgirish uint16_t start = 0, stop = nxgep->classifier.tcam_size; 260a3c5bd6dSspeer p_nxge_hw_list_t hw_p; 26144961713Sgirish 26244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 26352ccf843Smisaki "==> nxge_fflp_tcam_invalidate_all")); 26444961713Sgirish handle = nxgep->npi_reg_handle; 26544961713Sgirish if ((hw_p = nxgep->nxge_hw_p) == NULL) { 26644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 26752ccf843Smisaki " nxge_fflp_tcam_invalidate_all:" 26852ccf843Smisaki " common hardware not set", nxgep->niu_type)); 26944961713Sgirish return (NXGE_ERROR); 27044961713Sgirish } 27144961713Sgirish MUTEX_ENTER(&hw_p->nxge_tcam_lock); 27244961713Sgirish for (location = start; location < stop; location++) { 27344961713Sgirish rs = npi_fflp_tcam_entry_invalidate(handle, location); 27444961713Sgirish if (rs != NPI_SUCCESS) { 27544961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 27644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 27752ccf843Smisaki "TCAM invalidate failed at loc %d ", location)); 27844961713Sgirish return (NXGE_ERROR | rs); 27944961713Sgirish } 28044961713Sgirish } 28144961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 28244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 28352ccf843Smisaki "<== nxge_fflp_tcam_invalidate_all")); 28444961713Sgirish return (NXGE_OK); 28544961713Sgirish } 28644961713Sgirish 28744961713Sgirish /* 28844961713Sgirish * nxge_fflp_fcram_entry_invalidate_all 28944961713Sgirish * invalidates all the FCRAM entries. 29044961713Sgirish * INPUT 29144961713Sgirish * nxge soft state data structure 29244961713Sgirish * Return 29344961713Sgirish * NXGE_OK 29444961713Sgirish * NXGE_ERROR 29544961713Sgirish * 29644961713Sgirish */ 297a3c5bd6dSspeer 29844961713Sgirish static nxge_status_t 29944961713Sgirish nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep) 30044961713Sgirish { 301a3c5bd6dSspeer npi_handle_t handle; 302a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 303a3c5bd6dSspeer part_id_t pid = 0; 304a3c5bd6dSspeer uint8_t base_mask, base_reloc; 305a3c5bd6dSspeer fcram_entry_t fc; 306a3c5bd6dSspeer uint32_t location; 307a3c5bd6dSspeer uint32_t increment, last_location; 30844961713Sgirish 309a3c5bd6dSspeer /* 310a3c5bd6dSspeer * (1) configure and enable partition 0 with no relocation 311a3c5bd6dSspeer * (2) Assume the FCRAM is used as IPv4 exact match entry cells 312a3c5bd6dSspeer * (3) Invalidate these cells by clearing the valid bit in 313a3c5bd6dSspeer * the subareas 0 and 4 314a3c5bd6dSspeer * (4) disable the partition 315a3c5bd6dSspeer * 316a3c5bd6dSspeer */ 31744961713Sgirish 31844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all")); 31944961713Sgirish 32044961713Sgirish base_mask = base_reloc = 0x0; 32144961713Sgirish handle = nxgep->npi_reg_handle; 322a3c5bd6dSspeer rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc); 32344961713Sgirish 32444961713Sgirish if (rs != NPI_SUCCESS) { 325a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n")); 32644961713Sgirish return (NXGE_ERROR | rs); 32744961713Sgirish } 328a3c5bd6dSspeer rs = npi_fflp_cfg_fcram_partition_disable(handle, pid); 32944961713Sgirish 33044961713Sgirish if (rs != NPI_SUCCESS) { 33144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 33252ccf843Smisaki "failed partition enable\n")); 33344961713Sgirish return (NXGE_ERROR | rs); 33444961713Sgirish } 335a3c5bd6dSspeer fc.dreg[0].value = 0; 336a3c5bd6dSspeer fc.hash_hdr_valid = 0; 337a3c5bd6dSspeer fc.hash_hdr_ext = 1; /* specify as IPV4 exact match entry */ 338a3c5bd6dSspeer increment = sizeof (hash_ipv4_t); 339a3c5bd6dSspeer last_location = FCRAM_SIZE * 0x40; 34044961713Sgirish 341a3c5bd6dSspeer for (location = 0; location < last_location; location += increment) { 34244961713Sgirish rs = npi_fflp_fcram_subarea_write(handle, pid, 34352ccf843Smisaki location, fc.value[0]); 34444961713Sgirish if (rs != NPI_SUCCESS) { 34544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 34652ccf843Smisaki "failed write at location %x ", location)); 34744961713Sgirish return (NXGE_ERROR | rs); 34844961713Sgirish } 34944961713Sgirish } 35044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all")); 351a3c5bd6dSspeer return (NXGE_OK); 35244961713Sgirish } 35344961713Sgirish 35444961713Sgirish static nxge_status_t 35544961713Sgirish nxge_fflp_fcram_init(p_nxge_t nxgep) 35644961713Sgirish { 35744961713Sgirish fflp_fcram_output_drive_t strength; 35844961713Sgirish fflp_fcram_qs_t qs; 35944961713Sgirish npi_status_t rs = NPI_SUCCESS; 36044961713Sgirish uint8_t access_ratio; 361a3c5bd6dSspeer int partition; 36244961713Sgirish npi_handle_t handle; 363a3c5bd6dSspeer uint32_t min_time, max_time, sys_time; 36444961713Sgirish 36544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init")); 36644961713Sgirish 367a3c5bd6dSspeer /* 368a3c5bd6dSspeer * Recommended values are needed. 369a3c5bd6dSspeer */ 37044961713Sgirish min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME; 37144961713Sgirish max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME; 37244961713Sgirish sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME; 373a3c5bd6dSspeer 37444961713Sgirish handle = nxgep->npi_reg_handle; 37544961713Sgirish strength = FCRAM_OUTDR_NORMAL; 37644961713Sgirish qs = FCRAM_QS_MODE_QS; 37744961713Sgirish rs = npi_fflp_cfg_fcram_reset(handle, strength, qs); 37844961713Sgirish if (rs != NPI_SUCCESS) { 37944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. ")); 38044961713Sgirish return (NXGE_ERROR | rs); 38144961713Sgirish } 38244961713Sgirish 383a3c5bd6dSspeer access_ratio = nxgep->param_arr[param_fcram_access_ratio].value; 384a3c5bd6dSspeer rs = npi_fflp_cfg_fcram_access(handle, access_ratio); 385a3c5bd6dSspeer if (rs != NPI_SUCCESS) { 38644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio" 38752ccf843Smisaki "configuration \n")); 38844961713Sgirish return (NXGE_ERROR | rs); 38944961713Sgirish } 39044961713Sgirish rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time, 39152ccf843Smisaki max_time, sys_time); 39244961713Sgirish if (rs != NPI_SUCCESS) { 39344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 39452ccf843Smisaki "failed FCRAM refresh cfg")); 39544961713Sgirish return (NXGE_ERROR); 39644961713Sgirish } 39744961713Sgirish 39844961713Sgirish /* disable all the partitions until explicitly enabled */ 39944961713Sgirish for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) { 400a3c5bd6dSspeer rs = npi_fflp_cfg_fcram_partition_disable(handle, partition); 40144961713Sgirish if (rs != NPI_SUCCESS) { 40244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 40352ccf843Smisaki "failed FCRAM partition" 40452ccf843Smisaki " enable for partition %d ", partition)); 40544961713Sgirish return (NXGE_ERROR | rs); 40644961713Sgirish } 40744961713Sgirish } 40844961713Sgirish 40944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init")); 410a3c5bd6dSspeer return (NXGE_OK); 41144961713Sgirish } 41244961713Sgirish 41344961713Sgirish nxge_status_t 41444961713Sgirish nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac) 41544961713Sgirish { 41644961713Sgirish npi_status_t rs = NPI_SUCCESS; 41744961713Sgirish hostinfo_t mac_rdc; 41844961713Sgirish npi_handle_t handle; 419a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 42044961713Sgirish 421a3c5bd6dSspeer p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 42244961713Sgirish if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) { 423a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 42452ccf843Smisaki " nxge_logical_mac_assign_rdc_table" 42552ccf843Smisaki " unconfigured alt MAC addr %d ", alt_mac)); 42644961713Sgirish return (NXGE_ERROR); 42744961713Sgirish } 42844961713Sgirish handle = nxgep->npi_reg_handle; 42944961713Sgirish mac_rdc.value = 0; 43044961713Sgirish mac_rdc.bits.w0.rdc_tbl_num = 43152ccf843Smisaki p_class_cfgp->mac_host_info[alt_mac].rdctbl; 43244961713Sgirish mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr; 43344961713Sgirish 43444961713Sgirish rs = npi_mac_hostinfo_entry(handle, OP_SET, 43552ccf843Smisaki nxgep->function_num, alt_mac, &mac_rdc); 43644961713Sgirish 43744961713Sgirish if (rs != NPI_SUCCESS) { 43844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 43952ccf843Smisaki "failed Assign RDC table")); 44044961713Sgirish return (NXGE_ERROR | rs); 44144961713Sgirish } 44244961713Sgirish return (NXGE_OK); 44344961713Sgirish } 44444961713Sgirish 44544961713Sgirish nxge_status_t 44644961713Sgirish nxge_main_mac_assign_rdc_table(p_nxge_t nxgep) 44744961713Sgirish { 44844961713Sgirish npi_status_t rs = NPI_SUCCESS; 44944961713Sgirish hostinfo_t mac_rdc; 45044961713Sgirish npi_handle_t handle; 45144961713Sgirish 45244961713Sgirish handle = nxgep->npi_reg_handle; 45344961713Sgirish mac_rdc.value = 0; 45444961713Sgirish mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp; 45544961713Sgirish mac_rdc.bits.w0.mac_pref = 1; 45644961713Sgirish switch (nxgep->function_num) { 457a3c5bd6dSspeer case 0: 458a3c5bd6dSspeer case 1: 459a3c5bd6dSspeer rs = npi_mac_hostinfo_entry(handle, OP_SET, 46052ccf843Smisaki nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 461a3c5bd6dSspeer break; 462a3c5bd6dSspeer case 2: 463a3c5bd6dSspeer case 3: 464a3c5bd6dSspeer rs = npi_mac_hostinfo_entry(handle, OP_SET, 46552ccf843Smisaki nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 466a3c5bd6dSspeer break; 467a3c5bd6dSspeer default: 468a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 46952ccf843Smisaki "failed Assign RDC table (invalid function #)")); 470a3c5bd6dSspeer return (NXGE_ERROR); 47144961713Sgirish } 47244961713Sgirish 47344961713Sgirish if (rs != NPI_SUCCESS) { 47444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 47552ccf843Smisaki "failed Assign RDC table")); 47644961713Sgirish return (NXGE_ERROR | rs); 47744961713Sgirish } 47844961713Sgirish return (NXGE_OK); 47944961713Sgirish } 48044961713Sgirish 48158324dfcSspeer /* 48258324dfcSspeer * Initialize hostinfo registers for alternate MAC addresses and 48358324dfcSspeer * multicast MAC address. 48458324dfcSspeer */ 48544961713Sgirish nxge_status_t 48658324dfcSspeer nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep) 48744961713Sgirish { 48844961713Sgirish npi_status_t rs = NPI_SUCCESS; 48944961713Sgirish hostinfo_t mac_rdc; 49044961713Sgirish npi_handle_t handle; 49158324dfcSspeer int i; 49244961713Sgirish 49344961713Sgirish handle = nxgep->npi_reg_handle; 49444961713Sgirish mac_rdc.value = 0; 49544961713Sgirish mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp; 49644961713Sgirish mac_rdc.bits.w0.mac_pref = 1; 49744961713Sgirish switch (nxgep->function_num) { 498a3c5bd6dSspeer case 0: 499a3c5bd6dSspeer case 1: 50058324dfcSspeer /* 50158324dfcSspeer * Tests indicate that it is OK not to re-initialize the 50258324dfcSspeer * hostinfo registers for the XMAC's alternate MAC 50358324dfcSspeer * addresses. But that is necessary for BMAC (case 2 50458324dfcSspeer * and case 3 below) 50558324dfcSspeer */ 506a3c5bd6dSspeer rs = npi_mac_hostinfo_entry(handle, OP_SET, 50752ccf843Smisaki nxgep->function_num, 50852ccf843Smisaki XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 509a3c5bd6dSspeer break; 510a3c5bd6dSspeer case 2: 511a3c5bd6dSspeer case 3: 51258324dfcSspeer for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++) 51358324dfcSspeer rs |= npi_mac_hostinfo_entry(handle, OP_SET, 51452ccf843Smisaki nxgep->function_num, i, &mac_rdc); 51558324dfcSspeer 51658324dfcSspeer rs |= npi_mac_hostinfo_entry(handle, OP_SET, 51752ccf843Smisaki nxgep->function_num, 51852ccf843Smisaki BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 519a3c5bd6dSspeer break; 520a3c5bd6dSspeer default: 521a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 52252ccf843Smisaki "failed Assign RDC table (invalid function #)")); 523a3c5bd6dSspeer return (NXGE_ERROR); 52444961713Sgirish } 52544961713Sgirish 52644961713Sgirish if (rs != NPI_SUCCESS) { 52744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 52852ccf843Smisaki "failed Assign RDC table")); 52944961713Sgirish return (NXGE_ERROR | rs); 53044961713Sgirish } 53144961713Sgirish return (NXGE_OK); 53244961713Sgirish } 53344961713Sgirish 53444961713Sgirish nxge_status_t 53544961713Sgirish nxge_fflp_init_hostinfo(p_nxge_t nxgep) 53644961713Sgirish { 53744961713Sgirish nxge_status_t status = NXGE_OK; 538a3c5bd6dSspeer 53958324dfcSspeer status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 54058324dfcSspeer status |= nxge_main_mac_assign_rdc_table(nxgep); 54144961713Sgirish return (status); 54244961713Sgirish } 54344961713Sgirish 54444961713Sgirish nxge_status_t 54544961713Sgirish nxge_fflp_hw_reset(p_nxge_t nxgep) 54644961713Sgirish { 54744961713Sgirish npi_handle_t handle; 54844961713Sgirish npi_status_t rs = NPI_SUCCESS; 54944961713Sgirish nxge_status_t status = NXGE_OK; 55044961713Sgirish 55144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset")); 55244961713Sgirish 5532e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 55444961713Sgirish status = nxge_fflp_fcram_init(nxgep); 555a3c5bd6dSspeer if (status != NXGE_OK) { 55644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 55752ccf843Smisaki " failed FCRAM init. ")); 55844961713Sgirish return (status); 55944961713Sgirish } 56044961713Sgirish } 56144961713Sgirish 56244961713Sgirish status = nxge_fflp_tcam_init(nxgep); 56344961713Sgirish if (status != NXGE_OK) { 564a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 56552ccf843Smisaki "failed TCAM init.")); 566a3c5bd6dSspeer return (status); 56744961713Sgirish } 56844961713Sgirish 56944961713Sgirish handle = nxgep->npi_reg_handle; 57044961713Sgirish rs = npi_fflp_cfg_llcsnap_enable(handle); 57144961713Sgirish if (rs != NPI_SUCCESS) { 572a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 57352ccf843Smisaki "failed LLCSNAP enable. ")); 574a3c5bd6dSspeer return (NXGE_ERROR | rs); 57544961713Sgirish } 57644961713Sgirish 57744961713Sgirish rs = npi_fflp_cfg_cam_errorcheck_disable(handle); 57844961713Sgirish if (rs != NPI_SUCCESS) { 57944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 58052ccf843Smisaki "failed CAM Error Check enable. ")); 58144961713Sgirish return (NXGE_ERROR | rs); 58244961713Sgirish } 58344961713Sgirish 584a3c5bd6dSspeer /* init the hash generators */ 58544961713Sgirish rs = npi_fflp_cfg_hash_h1poly(handle, 0); 58644961713Sgirish if (rs != NPI_SUCCESS) { 587a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 58852ccf843Smisaki "failed H1 Poly Init. ")); 589a3c5bd6dSspeer return (NXGE_ERROR | rs); 59044961713Sgirish } 59144961713Sgirish 59244961713Sgirish rs = npi_fflp_cfg_hash_h2poly(handle, 0); 59344961713Sgirish if (rs != NPI_SUCCESS) { 594a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 59552ccf843Smisaki "failed H2 Poly Init. ")); 596a3c5bd6dSspeer return (NXGE_ERROR | rs); 59744961713Sgirish } 59844961713Sgirish 599a3c5bd6dSspeer /* invalidate TCAM entries */ 60044961713Sgirish status = nxge_fflp_tcam_invalidate_all(nxgep); 60144961713Sgirish if (status != NXGE_OK) { 60244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 60352ccf843Smisaki "failed TCAM Entry Invalidate. ")); 60444961713Sgirish return (status); 60544961713Sgirish } 60644961713Sgirish 607a3c5bd6dSspeer /* invalidate FCRAM entries */ 6082e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 60944961713Sgirish status = nxge_fflp_fcram_invalidate_all(nxgep); 61044961713Sgirish if (status != NXGE_OK) { 61144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 61252ccf843Smisaki "failed FCRAM Entry Invalidate.")); 61344961713Sgirish return (status); 61444961713Sgirish } 61544961713Sgirish } 61644961713Sgirish 617a3c5bd6dSspeer /* invalidate VLAN RDC tables */ 61844961713Sgirish status = nxge_fflp_vlan_tbl_clear_all(nxgep); 61944961713Sgirish if (status != NXGE_OK) { 62044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 62152ccf843Smisaki "failed VLAN Table Invalidate. ")); 62244961713Sgirish return (status); 62344961713Sgirish } 62444961713Sgirish nxgep->classifier.state |= NXGE_FFLP_HW_RESET; 62544961713Sgirish 62644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset")); 62744961713Sgirish return (NXGE_OK); 62844961713Sgirish } 62944961713Sgirish 63044961713Sgirish nxge_status_t 63144961713Sgirish nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class, 632a3c5bd6dSspeer uint32_t class_config) 63344961713Sgirish { 63444961713Sgirish flow_key_cfg_t fcfg; 63544961713Sgirish npi_handle_t handle; 63644961713Sgirish npi_status_t rs = NPI_SUCCESS; 63744961713Sgirish 63844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key")); 63944961713Sgirish handle = nxgep->npi_reg_handle; 64044961713Sgirish bzero(&fcfg, sizeof (flow_key_cfg_t)); 64144961713Sgirish 642a3c5bd6dSspeer if (class_config & NXGE_CLASS_FLOW_USE_PROTO) 64344961713Sgirish fcfg.use_proto = 1; 64444961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT) 64544961713Sgirish fcfg.use_dport = 1; 64644961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT) 64744961713Sgirish fcfg.use_sport = 1; 64844961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_IPDST) 64944961713Sgirish fcfg.use_daddr = 1; 65044961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_IPSRC) 65144961713Sgirish fcfg.use_saddr = 1; 65244961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_VLAN) 65344961713Sgirish fcfg.use_vlan = 1; 65444961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_L2DA) 65544961713Sgirish fcfg.use_l2da = 1; 65644961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM) 65744961713Sgirish fcfg.use_portnum = 1; 65844961713Sgirish fcfg.ip_opts_exist = 0; 65944961713Sgirish 66044961713Sgirish rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg); 66144961713Sgirish if (rs & NPI_FFLP_ERROR) { 66244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 66352ccf843Smisaki " opt %x for class %d failed ", class_config, l3_class)); 66444961713Sgirish return (NXGE_ERROR | rs); 66544961713Sgirish } 66644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key")); 66744961713Sgirish return (NXGE_OK); 66844961713Sgirish } 66944961713Sgirish 67044961713Sgirish nxge_status_t 67144961713Sgirish nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class, 672a3c5bd6dSspeer uint32_t *class_config) 67344961713Sgirish { 67444961713Sgirish flow_key_cfg_t fcfg; 67544961713Sgirish npi_handle_t handle; 67644961713Sgirish npi_status_t rs = NPI_SUCCESS; 67744961713Sgirish uint32_t ccfg = 0; 678a3c5bd6dSspeer 67944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get")); 68044961713Sgirish handle = nxgep->npi_reg_handle; 68144961713Sgirish bzero(&fcfg, sizeof (flow_key_cfg_t)); 68244961713Sgirish 68344961713Sgirish rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg); 68444961713Sgirish if (rs & NPI_FFLP_ERROR) { 68544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 68652ccf843Smisaki " opt %x for class %d failed ", class_config, l3_class)); 68744961713Sgirish return (NXGE_ERROR | rs); 68844961713Sgirish } 68944961713Sgirish 69044961713Sgirish if (fcfg.use_proto) 69144961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_PROTO; 69244961713Sgirish if (fcfg.use_dport) 69344961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT; 69444961713Sgirish if (fcfg.use_sport) 69544961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT; 69644961713Sgirish if (fcfg.use_daddr) 69744961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_IPDST; 69844961713Sgirish if (fcfg.use_saddr) 69944961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_IPSRC; 70044961713Sgirish if (fcfg.use_vlan) 70144961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_VLAN; 70244961713Sgirish if (fcfg.use_l2da) 70344961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_L2DA; 70444961713Sgirish if (fcfg.use_portnum) 705a3c5bd6dSspeer ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM; 70644961713Sgirish 70744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 70852ccf843Smisaki " nxge_cfg_ip_cls_flow_key_get %x", ccfg)); 70944961713Sgirish *class_config = ccfg; 71044961713Sgirish 71144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 71252ccf843Smisaki " <== nxge_cfg_ip_cls_flow_key_get")); 71344961713Sgirish return (NXGE_OK); 71444961713Sgirish } 71544961713Sgirish 71644961713Sgirish static nxge_status_t 71744961713Sgirish nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class, 718a3c5bd6dSspeer uint32_t *class_config) 71944961713Sgirish { 72044961713Sgirish npi_status_t rs = NPI_SUCCESS; 72144961713Sgirish tcam_key_cfg_t cfg; 72244961713Sgirish npi_handle_t handle; 72344961713Sgirish uint32_t ccfg = 0; 72444961713Sgirish 72544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 72644961713Sgirish 72744961713Sgirish bzero(&cfg, sizeof (tcam_key_cfg_t)); 72844961713Sgirish handle = nxgep->npi_reg_handle; 72944961713Sgirish 73044961713Sgirish rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg); 73144961713Sgirish if (rs & NPI_FFLP_ERROR) { 73244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 73352ccf843Smisaki " opt %x for class %d failed ", class_config, class)); 73444961713Sgirish return (NXGE_ERROR | rs); 73544961713Sgirish } 73644961713Sgirish if (cfg.discard) 737a3c5bd6dSspeer ccfg |= NXGE_CLASS_DISCARD; 73844961713Sgirish if (cfg.lookup_enable) 73944961713Sgirish ccfg |= NXGE_CLASS_TCAM_LOOKUP; 74044961713Sgirish if (cfg.use_ip_daddr) 741a3c5bd6dSspeer ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR; 74244961713Sgirish *class_config = ccfg; 74344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 74452ccf843Smisaki " ==> nxge_cfg_tcam_ip_class %x", ccfg)); 74544961713Sgirish return (NXGE_OK); 74644961713Sgirish } 74744961713Sgirish 74844961713Sgirish static nxge_status_t 74944961713Sgirish nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class, 750a3c5bd6dSspeer uint32_t class_config) 75144961713Sgirish { 75244961713Sgirish npi_status_t rs = NPI_SUCCESS; 75344961713Sgirish tcam_key_cfg_t cfg; 75444961713Sgirish npi_handle_t handle; 755a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 75644961713Sgirish 75744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 758a3c5bd6dSspeer 75944961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 76044961713Sgirish p_class_cfgp->class_cfg[class] = class_config; 76144961713Sgirish 76244961713Sgirish bzero(&cfg, sizeof (tcam_key_cfg_t)); 76344961713Sgirish handle = nxgep->npi_reg_handle; 76444961713Sgirish cfg.discard = 0; 76544961713Sgirish cfg.lookup_enable = 0; 76644961713Sgirish cfg.use_ip_daddr = 0; 76744961713Sgirish if (class_config & NXGE_CLASS_DISCARD) 76844961713Sgirish cfg.discard = 1; 76944961713Sgirish if (class_config & NXGE_CLASS_TCAM_LOOKUP) 77044961713Sgirish cfg.lookup_enable = 1; 771a3c5bd6dSspeer if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR) 77244961713Sgirish cfg.use_ip_daddr = 1; 77344961713Sgirish 77444961713Sgirish rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg); 77544961713Sgirish if (rs & NPI_FFLP_ERROR) { 77644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 77752ccf843Smisaki " opt %x for class %d failed ", class_config, class)); 77844961713Sgirish return (NXGE_ERROR | rs); 77944961713Sgirish } 78044961713Sgirish return (NXGE_OK); 78144961713Sgirish } 78244961713Sgirish 78344961713Sgirish nxge_status_t 78444961713Sgirish nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1) 78544961713Sgirish { 78644961713Sgirish npi_status_t rs = NPI_SUCCESS; 78744961713Sgirish npi_handle_t handle; 788a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 78944961713Sgirish 79044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1")); 79144961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 79244961713Sgirish p_class_cfgp->init_h1 = h1; 79344961713Sgirish handle = nxgep->npi_reg_handle; 79444961713Sgirish rs = npi_fflp_cfg_hash_h1poly(handle, h1); 79544961713Sgirish if (rs & NPI_FFLP_ERROR) { 796a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 79752ccf843Smisaki " nxge_fflp_init_h1 %x failed ", h1)); 79844961713Sgirish return (NXGE_ERROR | rs); 79944961713Sgirish } 80044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1")); 80144961713Sgirish return (NXGE_OK); 80244961713Sgirish } 80344961713Sgirish 80444961713Sgirish nxge_status_t 80544961713Sgirish nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2) 80644961713Sgirish { 80744961713Sgirish npi_status_t rs = NPI_SUCCESS; 80844961713Sgirish npi_handle_t handle; 809a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 81044961713Sgirish 81144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2")); 81244961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 81344961713Sgirish p_class_cfgp->init_h2 = h2; 81444961713Sgirish 81544961713Sgirish handle = nxgep->npi_reg_handle; 81644961713Sgirish rs = npi_fflp_cfg_hash_h2poly(handle, h2); 81744961713Sgirish if (rs & NPI_FFLP_ERROR) { 818a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 81952ccf843Smisaki " nxge_fflp_init_h2 %x failed ", h2)); 82044961713Sgirish return (NXGE_ERROR | rs); 82144961713Sgirish } 82244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2")); 82344961713Sgirish return (NXGE_OK); 82444961713Sgirish } 82544961713Sgirish 82644961713Sgirish nxge_status_t 82744961713Sgirish nxge_classify_init_sw(p_nxge_t nxgep) 82844961713Sgirish { 82944961713Sgirish nxge_classify_t *classify_ptr; 83044961713Sgirish 83144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw")); 83244961713Sgirish classify_ptr = &nxgep->classifier; 83344961713Sgirish 83444961713Sgirish if (classify_ptr->state & NXGE_FFLP_SW_INIT) { 83544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 83652ccf843Smisaki "nxge_classify_init_sw already init")); 83744961713Sgirish return (NXGE_OK); 83844961713Sgirish } 839a3c5bd6dSspeer 840*4df55fdeSJanie Lu classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports; 841*4df55fdeSJanie Lu classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam; 842*4df55fdeSJanie Lu classify_ptr->tcam_top = nxgep->function_num; 84344961713Sgirish 844a3c5bd6dSspeer /* Init defaults */ 845a3c5bd6dSspeer /* 846a3c5bd6dSspeer * add hacks required for HW shortcomings for example, code to handle 847a3c5bd6dSspeer * fragmented packets 848a3c5bd6dSspeer */ 84944961713Sgirish nxge_init_h1_table(); 85044961713Sgirish nxge_crc_ccitt_init(); 85144961713Sgirish nxgep->classifier.tcam_location = nxgep->function_num; 85244961713Sgirish nxgep->classifier.fragment_bug = 1; 85344961713Sgirish classify_ptr->state |= NXGE_FFLP_SW_INIT; 85444961713Sgirish 85544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw")); 85644961713Sgirish return (NXGE_OK); 85744961713Sgirish } 85844961713Sgirish 85944961713Sgirish nxge_status_t 86044961713Sgirish nxge_classify_exit_sw(p_nxge_t nxgep) 86144961713Sgirish { 86244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw")); 86344961713Sgirish nxgep->classifier.state = NULL; 86444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw")); 86544961713Sgirish return (NXGE_OK); 86644961713Sgirish } 86744961713Sgirish 86844961713Sgirish /* 86944961713Sgirish * Figures out the RDC Group for the entry 87044961713Sgirish * 87144961713Sgirish * The current implementation is just a place holder and it 87244961713Sgirish * returns 0. 87344961713Sgirish * The real location determining algorithm would consider 87444961713Sgirish * the partition etc ... before deciding w 87544961713Sgirish * 87644961713Sgirish */ 877a3c5bd6dSspeer 8780a8e077aSspeer /* ARGSUSED */ 87944961713Sgirish static uint8_t 880*4df55fdeSJanie Lu nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie) 88144961713Sgirish { 88244961713Sgirish int use_port_rdc_grp = 0; 88344961713Sgirish uint8_t rdc_grp = 0; 884a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 885a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 886a3c5bd6dSspeer p_nxge_rdc_grp_t rdc_grp_p; 887a3c5bd6dSspeer 88844961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 88944961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 89044961713Sgirish rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp]; 891678453a8Sspeer rdc_grp = p_cfgp->def_mac_rxdma_grpid; 892a3c5bd6dSspeer 89344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 89452ccf843Smisaki "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n", 89552ccf843Smisaki cookie, rdc_grp, rdc_grp_p)); 89644961713Sgirish return (rdc_grp); 89744961713Sgirish } 89844961713Sgirish 89944961713Sgirish /* ARGSUSED */ 90044961713Sgirish static uint8_t 901*4df55fdeSJanie Lu nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie) 90244961713Sgirish { 90344961713Sgirish return ((uint8_t)cookie); 90444961713Sgirish } 90544961713Sgirish 9060a8e077aSspeer /* ARGSUSED */ 90744961713Sgirish static void 90844961713Sgirish nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec, 909a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 91044961713Sgirish { 91144961713Sgirish udpip4_spec_t *fspec_key; 91244961713Sgirish udpip4_spec_t *fspec_mask; 91344961713Sgirish 91444961713Sgirish fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec; 91544961713Sgirish fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec; 91644961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 91744961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 91844961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 91944961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 92044961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 92152ccf843Smisaki fspec_key->pdst, fspec_key->psrc); 92244961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 92352ccf843Smisaki fspec_mask->pdst, fspec_mask->psrc); 92444961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 92552ccf843Smisaki tcam_ptr->ip4_class_mask, 92652ccf843Smisaki TCAM_CLASS_UDP_IPV4); 92744961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 92852ccf843Smisaki tcam_ptr->ip4_proto_mask, 92952ccf843Smisaki IPPROTO_UDP); 930*4df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 931*4df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 93244961713Sgirish } 93344961713Sgirish 93444961713Sgirish static void 93544961713Sgirish nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 936a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 93744961713Sgirish { 93844961713Sgirish udpip6_spec_t *fspec_key; 93944961713Sgirish udpip6_spec_t *fspec_mask; 940a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 94144961713Sgirish 94244961713Sgirish fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec; 94344961713Sgirish fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec; 94444961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 94544961713Sgirish if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 94652ccf843Smisaki NXGE_CLASS_TCAM_USE_SRC_ADDR) { 94744961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 94844961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 94944961713Sgirish } else { 95044961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 95144961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 95244961713Sgirish } 95344961713Sgirish 95444961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 95552ccf843Smisaki tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6); 95644961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 95752ccf843Smisaki tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP); 95844961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 95952ccf843Smisaki fspec_key->pdst, fspec_key->psrc); 96044961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 96152ccf843Smisaki fspec_mask->pdst, fspec_mask->psrc); 962*4df55fdeSJanie Lu tcam_ptr->ip6_tos_key = fspec_key->tos; 963*4df55fdeSJanie Lu tcam_ptr->ip6_tos_mask = fspec_mask->tos; 96444961713Sgirish } 96544961713Sgirish 9660a8e077aSspeer /* ARGSUSED */ 96744961713Sgirish static void 96844961713Sgirish nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec, 969a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 97044961713Sgirish { 97144961713Sgirish tcpip4_spec_t *fspec_key; 97244961713Sgirish tcpip4_spec_t *fspec_mask; 97344961713Sgirish 97444961713Sgirish fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 97544961713Sgirish fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 97644961713Sgirish 97744961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 97844961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 97944961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 98044961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 98144961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 98252ccf843Smisaki fspec_key->pdst, fspec_key->psrc); 98344961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 98452ccf843Smisaki fspec_mask->pdst, fspec_mask->psrc); 98544961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 98652ccf843Smisaki tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4); 98744961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 98852ccf843Smisaki tcam_ptr->ip4_proto_mask, IPPROTO_TCP); 989*4df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 990*4df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 99144961713Sgirish } 99244961713Sgirish 9930a8e077aSspeer /* ARGSUSED */ 99444961713Sgirish static void 99544961713Sgirish nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec, 996a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 99744961713Sgirish { 99844961713Sgirish tcpip4_spec_t *fspec_key; 99944961713Sgirish tcpip4_spec_t *fspec_mask; 100044961713Sgirish 100144961713Sgirish fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 100244961713Sgirish fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 100344961713Sgirish 100444961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 100544961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 100644961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 100744961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 100844961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 100952ccf843Smisaki tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4); 101044961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 101152ccf843Smisaki tcam_ptr->ip4_proto_mask, IPPROTO_SCTP); 101244961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 101352ccf843Smisaki fspec_key->pdst, fspec_key->psrc); 101444961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 101552ccf843Smisaki fspec_mask->pdst, fspec_mask->psrc); 1016*4df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 1017*4df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 101844961713Sgirish } 101944961713Sgirish 102044961713Sgirish static void 102144961713Sgirish nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1022a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 102344961713Sgirish { 102444961713Sgirish tcpip6_spec_t *fspec_key; 102544961713Sgirish tcpip6_spec_t *fspec_mask; 1026a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 1027a3c5bd6dSspeer 102844961713Sgirish fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 102944961713Sgirish fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 103044961713Sgirish 103144961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 103244961713Sgirish if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 103352ccf843Smisaki NXGE_CLASS_TCAM_USE_SRC_ADDR) { 103444961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 103544961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 103644961713Sgirish } else { 103744961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 103844961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 103944961713Sgirish } 104044961713Sgirish 104144961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 104252ccf843Smisaki tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6); 104344961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 104452ccf843Smisaki tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP); 104544961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 104652ccf843Smisaki fspec_key->pdst, fspec_key->psrc); 104744961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 104852ccf843Smisaki fspec_mask->pdst, fspec_mask->psrc); 1049*4df55fdeSJanie Lu tcam_ptr->ip6_tos_key = fspec_key->tos; 1050*4df55fdeSJanie Lu tcam_ptr->ip6_tos_mask = fspec_mask->tos; 105144961713Sgirish } 105244961713Sgirish 105344961713Sgirish static void 105444961713Sgirish nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1055a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 105644961713Sgirish { 105744961713Sgirish tcpip6_spec_t *fspec_key; 105844961713Sgirish tcpip6_spec_t *fspec_mask; 1059a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 106044961713Sgirish 106144961713Sgirish fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 106244961713Sgirish fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 106344961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 106444961713Sgirish 106544961713Sgirish if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 106652ccf843Smisaki NXGE_CLASS_TCAM_USE_SRC_ADDR) { 106744961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 106844961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 106944961713Sgirish } else { 107044961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 107144961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 107244961713Sgirish } 107344961713Sgirish 107444961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 107552ccf843Smisaki tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6); 107644961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 107752ccf843Smisaki tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP); 107844961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 107952ccf843Smisaki fspec_key->pdst, fspec_key->psrc); 108044961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 108152ccf843Smisaki fspec_mask->pdst, fspec_mask->psrc); 1082*4df55fdeSJanie Lu tcam_ptr->ip6_tos_key = fspec_key->tos; 1083*4df55fdeSJanie Lu tcam_ptr->ip6_tos_mask = fspec_mask->tos; 1084*4df55fdeSJanie Lu } 1085*4df55fdeSJanie Lu 1086*4df55fdeSJanie Lu /* ARGSUSED */ 1087*4df55fdeSJanie Lu static void 1088*4df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec, 1089*4df55fdeSJanie Lu tcam_entry_t *tcam_ptr) 1090*4df55fdeSJanie Lu { 1091*4df55fdeSJanie Lu ahip4_spec_t *fspec_key; 1092*4df55fdeSJanie Lu ahip4_spec_t *fspec_mask; 1093*4df55fdeSJanie Lu 1094*4df55fdeSJanie Lu fspec_key = (ahip4_spec_t *)&flow_spec->uh.ahip4spec; 1095*4df55fdeSJanie Lu fspec_mask = (ahip4_spec_t *)&flow_spec->um.ahip4spec; 1096*4df55fdeSJanie Lu 1097*4df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1098*4df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1099*4df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1100*4df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1101*4df55fdeSJanie Lu 1102*4df55fdeSJanie Lu tcam_ptr->ip4_port_key = fspec_key->spi; 1103*4df55fdeSJanie Lu tcam_ptr->ip4_port_mask = fspec_mask->spi; 1104*4df55fdeSJanie Lu 1105*4df55fdeSJanie Lu TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1106*4df55fdeSJanie Lu tcam_ptr->ip4_class_mask, 1107*4df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV4); 1108*4df55fdeSJanie Lu 1109*4df55fdeSJanie Lu if (flow_spec->flow_type == FSPEC_AHIP4) { 1110*4df55fdeSJanie Lu TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1111*4df55fdeSJanie Lu tcam_ptr->ip4_proto_mask, IPPROTO_AH); 1112*4df55fdeSJanie Lu } else { 1113*4df55fdeSJanie Lu TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1114*4df55fdeSJanie Lu tcam_ptr->ip4_proto_mask, IPPROTO_ESP); 1115*4df55fdeSJanie Lu } 1116*4df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 1117*4df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 111844961713Sgirish } 111944961713Sgirish 1120*4df55fdeSJanie Lu static void 1121*4df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1122*4df55fdeSJanie Lu tcam_entry_t *tcam_ptr) 1123*4df55fdeSJanie Lu { 1124*4df55fdeSJanie Lu ahip6_spec_t *fspec_key; 1125*4df55fdeSJanie Lu ahip6_spec_t *fspec_mask; 1126*4df55fdeSJanie Lu p_nxge_class_pt_cfg_t p_class_cfgp; 1127*4df55fdeSJanie Lu 1128*4df55fdeSJanie Lu fspec_key = (ahip6_spec_t *)&flow_spec->uh.ahip6spec; 1129*4df55fdeSJanie Lu fspec_mask = (ahip6_spec_t *)&flow_spec->um.ahip6spec; 1130*4df55fdeSJanie Lu 1131*4df55fdeSJanie Lu p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1132*4df55fdeSJanie Lu if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] & 1133*4df55fdeSJanie Lu NXGE_CLASS_TCAM_USE_SRC_ADDR) { 1134*4df55fdeSJanie Lu TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 1135*4df55fdeSJanie Lu TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 1136*4df55fdeSJanie Lu } else { 1137*4df55fdeSJanie Lu TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 1138*4df55fdeSJanie Lu TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 1139*4df55fdeSJanie Lu } 1140*4df55fdeSJanie Lu 1141*4df55fdeSJanie Lu TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1142*4df55fdeSJanie Lu tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6); 1143*4df55fdeSJanie Lu 1144*4df55fdeSJanie Lu if (flow_spec->flow_type == FSPEC_AHIP6) { 1145*4df55fdeSJanie Lu TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1146*4df55fdeSJanie Lu tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH); 1147*4df55fdeSJanie Lu } else { 1148*4df55fdeSJanie Lu TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1149*4df55fdeSJanie Lu tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP); 1150*4df55fdeSJanie Lu } 1151*4df55fdeSJanie Lu tcam_ptr->ip6_port_key = fspec_key->spi; 1152*4df55fdeSJanie Lu tcam_ptr->ip6_port_mask = fspec_mask->spi; 1153*4df55fdeSJanie Lu tcam_ptr->ip6_tos_key = fspec_key->tos; 1154*4df55fdeSJanie Lu tcam_ptr->ip6_tos_mask = fspec_mask->tos; 1155*4df55fdeSJanie Lu } 1156*4df55fdeSJanie Lu 1157*4df55fdeSJanie Lu /* ARGSUSED */ 1158*4df55fdeSJanie Lu static void 1159*4df55fdeSJanie Lu nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec, 1160*4df55fdeSJanie Lu tcam_entry_t *tcam_ptr, tcam_class_t class) 1161*4df55fdeSJanie Lu { 1162*4df55fdeSJanie Lu ip_user_spec_t *fspec_key; 1163*4df55fdeSJanie Lu ip_user_spec_t *fspec_mask; 1164*4df55fdeSJanie Lu 1165*4df55fdeSJanie Lu fspec_key = (ip_user_spec_t *)&flow_spec->uh.ip_usr_spec; 1166*4df55fdeSJanie Lu fspec_mask = (ip_user_spec_t *)&flow_spec->um.ip_usr_spec; 1167*4df55fdeSJanie Lu 1168*4df55fdeSJanie Lu if (fspec_key->ip_ver == FSPEC_IP4) { 1169*4df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1170*4df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1171*4df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1172*4df55fdeSJanie Lu TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1173*4df55fdeSJanie Lu 1174*4df55fdeSJanie Lu tcam_ptr->ip4_port_key = fspec_key->l4_4_bytes; 1175*4df55fdeSJanie Lu tcam_ptr->ip4_port_mask = fspec_mask->l4_4_bytes; 1176*4df55fdeSJanie Lu 1177*4df55fdeSJanie Lu TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1178*4df55fdeSJanie Lu tcam_ptr->ip4_class_mask, class); 1179*4df55fdeSJanie Lu 1180*4df55fdeSJanie Lu tcam_ptr->ip4_proto_key = fspec_key->proto; 1181*4df55fdeSJanie Lu tcam_ptr->ip4_proto_mask = fspec_mask->proto; 1182*4df55fdeSJanie Lu 1183*4df55fdeSJanie Lu tcam_ptr->ip4_tos_key = fspec_key->tos; 1184*4df55fdeSJanie Lu tcam_ptr->ip4_tos_mask = fspec_mask->tos; 1185*4df55fdeSJanie Lu } 1186*4df55fdeSJanie Lu } 1187*4df55fdeSJanie Lu 1188*4df55fdeSJanie Lu 118944961713Sgirish nxge_status_t 119044961713Sgirish nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res, 1191a3c5bd6dSspeer uint32_t *H1, uint16_t *H2) 119244961713Sgirish { 119344961713Sgirish flow_spec_t *flow_spec; 119444961713Sgirish uint32_t class_cfg; 119544961713Sgirish flow_template_t ft; 1196a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 119744961713Sgirish 119844961713Sgirish int ft_size = sizeof (flow_template_t); 1199a3c5bd6dSspeer 120044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash")); 120144961713Sgirish 120244961713Sgirish flow_spec = (flow_spec_t *)&flow_res->flow_spec; 120344961713Sgirish bzero((char *)&ft, ft_size); 120444961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1205a3c5bd6dSspeer 120644961713Sgirish switch (flow_spec->flow_type) { 1207a3c5bd6dSspeer case FSPEC_TCPIP4: 1208a3c5bd6dSspeer class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4]; 1209a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 1210a3c5bd6dSspeer ft.ip_proto = IPPROTO_TCP; 1211a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 1212a3c5bd6dSspeer ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src; 1213a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 1214a3c5bd6dSspeer ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst; 1215a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 1216a3c5bd6dSspeer ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc; 1217a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 1218a3c5bd6dSspeer ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst; 1219a3c5bd6dSspeer break; 1220a3c5bd6dSspeer 1221a3c5bd6dSspeer case FSPEC_UDPIP4: 1222a3c5bd6dSspeer class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4]; 1223a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 1224a3c5bd6dSspeer ft.ip_proto = IPPROTO_UDP; 1225a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 1226a3c5bd6dSspeer ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src; 1227a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 1228a3c5bd6dSspeer ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst; 1229a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 1230a3c5bd6dSspeer ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc; 1231a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 1232a3c5bd6dSspeer ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst; 1233a3c5bd6dSspeer break; 1234a3c5bd6dSspeer 1235a3c5bd6dSspeer default: 1236a3c5bd6dSspeer return (NXGE_ERROR); 123744961713Sgirish } 123844961713Sgirish 123944961713Sgirish *H1 = nxge_compute_h1(p_class_cfgp->init_h1, 124052ccf843Smisaki (uint32_t *)&ft, ft_size) & 0xfffff; 124144961713Sgirish *H2 = nxge_compute_h2(p_class_cfgp->init_h2, 124252ccf843Smisaki (uint8_t *)&ft, ft_size); 124344961713Sgirish 124444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash")); 124544961713Sgirish return (NXGE_OK); 124644961713Sgirish } 124744961713Sgirish 124844961713Sgirish nxge_status_t 124944961713Sgirish nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 125044961713Sgirish { 125144961713Sgirish uint32_t H1; 125244961713Sgirish uint16_t H2; 125344961713Sgirish nxge_status_t status = NXGE_OK; 125444961713Sgirish 125544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry")); 125644961713Sgirish status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2); 125744961713Sgirish if (status != NXGE_OK) { 125844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 125952ccf843Smisaki " nxge_add_fcram_entry failed ")); 126044961713Sgirish return (status); 126144961713Sgirish } 126244961713Sgirish 126344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry")); 126444961713Sgirish return (NXGE_OK); 126544961713Sgirish } 126644961713Sgirish 126744961713Sgirish /* 126844961713Sgirish * Already decided this flow goes into the tcam 126944961713Sgirish */ 127044961713Sgirish 127144961713Sgirish nxge_status_t 127244961713Sgirish nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 127344961713Sgirish { 127444961713Sgirish npi_handle_t handle; 1275*4df55fdeSJanie Lu uint64_t channel_cookie; 1276*4df55fdeSJanie Lu uint64_t flow_cookie; 127744961713Sgirish flow_spec_t *flow_spec; 127844961713Sgirish npi_status_t rs = NPI_SUCCESS; 127944961713Sgirish tcam_entry_t tcam_ptr; 1280*4df55fdeSJanie Lu tcam_location_t location; 128144961713Sgirish uint8_t offset, rdc_grp; 1282a3c5bd6dSspeer p_nxge_hw_list_t hw_p; 1283*4df55fdeSJanie Lu uint64_t class; 128444961713Sgirish 128544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry")); 128644961713Sgirish handle = nxgep->npi_reg_handle; 128744961713Sgirish 1288a3c5bd6dSspeer bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 128944961713Sgirish flow_spec = (flow_spec_t *)&flow_res->flow_spec; 129044961713Sgirish flow_cookie = flow_res->flow_cookie; 129144961713Sgirish channel_cookie = flow_res->channel_cookie; 1292*4df55fdeSJanie Lu location = (tcam_location_t)nxge_tcam_get_index(nxgep, 1293*4df55fdeSJanie Lu (uint16_t)flow_res->location); 1294*4df55fdeSJanie Lu 1295*4df55fdeSJanie Lu if ((hw_p = nxgep->nxge_hw_p) == NULL) { 1296*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1297*4df55fdeSJanie Lu " nxge_add_tcam_entry: common hardware not set", 1298*4df55fdeSJanie Lu nxgep->niu_type)); 1299*4df55fdeSJanie Lu return (NXGE_ERROR); 1300*4df55fdeSJanie Lu } 1301*4df55fdeSJanie Lu 1302*4df55fdeSJanie Lu if (flow_spec->flow_type == FSPEC_IP_USR) { 1303*4df55fdeSJanie Lu int i; 1304*4df55fdeSJanie Lu int add_usr_cls = 0; 1305*4df55fdeSJanie Lu int ipv6 = 0; 1306*4df55fdeSJanie Lu ip_user_spec_t *uspec = &flow_spec->uh.ip_usr_spec; 1307*4df55fdeSJanie Lu ip_user_spec_t *umask = &flow_spec->um.ip_usr_spec; 1308*4df55fdeSJanie Lu nxge_usr_l3_cls_t *l3_ucls_p; 1309*4df55fdeSJanie Lu 1310*4df55fdeSJanie Lu MUTEX_ENTER(&hw_p->nxge_tcam_lock); 1311*4df55fdeSJanie Lu 1312*4df55fdeSJanie Lu for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 1313*4df55fdeSJanie Lu l3_ucls_p = &hw_p->tcam_l3_prog_cls[i]; 1314*4df55fdeSJanie Lu if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) { 1315*4df55fdeSJanie Lu if (uspec->proto == l3_ucls_p->pid) { 1316*4df55fdeSJanie Lu class = l3_ucls_p->cls; 1317*4df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt++; 1318*4df55fdeSJanie Lu add_usr_cls = 1; 1319*4df55fdeSJanie Lu break; 1320*4df55fdeSJanie Lu } 1321*4df55fdeSJanie Lu } else if (l3_ucls_p->valid == 0) { 1322*4df55fdeSJanie Lu /* Program new user IP class */ 1323*4df55fdeSJanie Lu switch (i) { 1324*4df55fdeSJanie Lu case 0: 1325*4df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_4; 1326*4df55fdeSJanie Lu break; 1327*4df55fdeSJanie Lu case 1: 1328*4df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_5; 1329*4df55fdeSJanie Lu break; 1330*4df55fdeSJanie Lu case 2: 1331*4df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_6; 1332*4df55fdeSJanie Lu break; 1333*4df55fdeSJanie Lu case 3: 1334*4df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_7; 1335*4df55fdeSJanie Lu break; 1336*4df55fdeSJanie Lu default: 1337*4df55fdeSJanie Lu break; 1338*4df55fdeSJanie Lu } 1339*4df55fdeSJanie Lu if (uspec->ip_ver == FSPEC_IP6) 1340*4df55fdeSJanie Lu ipv6 = 1; 1341*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set(handle, 1342*4df55fdeSJanie Lu (tcam_class_t)class, uspec->tos, 1343*4df55fdeSJanie Lu umask->tos, uspec->proto, ipv6); 1344*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 1345*4df55fdeSJanie Lu goto fail; 1346*4df55fdeSJanie Lu 1347*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 1348*4df55fdeSJanie Lu (tcam_class_t)class); 1349*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 1350*4df55fdeSJanie Lu goto fail; 1351*4df55fdeSJanie Lu 1352*4df55fdeSJanie Lu l3_ucls_p->cls = class; 1353*4df55fdeSJanie Lu l3_ucls_p->pid = uspec->proto; 1354*4df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt++; 1355*4df55fdeSJanie Lu l3_ucls_p->valid = 1; 1356*4df55fdeSJanie Lu add_usr_cls = 1; 1357*4df55fdeSJanie Lu break; 1358*4df55fdeSJanie Lu } else if (l3_ucls_p->tcam_ref_cnt == 0 && 1359*4df55fdeSJanie Lu uspec->proto == l3_ucls_p->pid) { 1360*4df55fdeSJanie Lu /* 1361*4df55fdeSJanie Lu * The class has already been programmed, 1362*4df55fdeSJanie Lu * probably for flow hash 1363*4df55fdeSJanie Lu */ 1364*4df55fdeSJanie Lu class = l3_ucls_p->cls; 1365*4df55fdeSJanie Lu if (uspec->ip_ver == FSPEC_IP6) 1366*4df55fdeSJanie Lu ipv6 = 1; 1367*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set(handle, 1368*4df55fdeSJanie Lu (tcam_class_t)class, uspec->tos, 1369*4df55fdeSJanie Lu umask->tos, uspec->proto, ipv6); 1370*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 1371*4df55fdeSJanie Lu goto fail; 1372*4df55fdeSJanie Lu 1373*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 1374*4df55fdeSJanie Lu (tcam_class_t)class); 1375*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 1376*4df55fdeSJanie Lu goto fail; 1377*4df55fdeSJanie Lu 1378*4df55fdeSJanie Lu l3_ucls_p->pid = uspec->proto; 1379*4df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt++; 1380*4df55fdeSJanie Lu add_usr_cls = 1; 1381*4df55fdeSJanie Lu break; 1382*4df55fdeSJanie Lu } 1383*4df55fdeSJanie Lu } 1384*4df55fdeSJanie Lu if (!add_usr_cls) { 1385*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1386*4df55fdeSJanie Lu "nxge_add_tcam_entry: Could not find/insert class" 1387*4df55fdeSJanie Lu "for pid %d", uspec->proto)); 1388*4df55fdeSJanie Lu goto fail; 1389*4df55fdeSJanie Lu } 1390*4df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1391*4df55fdeSJanie Lu } 139244961713Sgirish 139344961713Sgirish switch (flow_spec->flow_type) { 1394a3c5bd6dSspeer case FSPEC_TCPIP4: 1395a3c5bd6dSspeer nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr); 1396a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4, 139752ccf843Smisaki flow_cookie); 1398a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4, 139952ccf843Smisaki channel_cookie); 1400a3c5bd6dSspeer break; 1401a3c5bd6dSspeer 1402a3c5bd6dSspeer case FSPEC_UDPIP4: 1403a3c5bd6dSspeer nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr); 1404a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, 140552ccf843Smisaki TCAM_CLASS_UDP_IPV4, 140652ccf843Smisaki flow_cookie); 1407a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, 140852ccf843Smisaki TCAM_CLASS_UDP_IPV4, 140952ccf843Smisaki channel_cookie); 1410a3c5bd6dSspeer break; 1411a3c5bd6dSspeer 1412a3c5bd6dSspeer case FSPEC_TCPIP6: 1413a3c5bd6dSspeer nxge_fill_tcam_entry_tcp_ipv6(nxgep, 141452ccf843Smisaki flow_spec, &tcam_ptr); 1415a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6, 141652ccf843Smisaki flow_cookie); 1417a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6, 141852ccf843Smisaki channel_cookie); 1419a3c5bd6dSspeer break; 1420a3c5bd6dSspeer 1421a3c5bd6dSspeer case FSPEC_UDPIP6: 1422a3c5bd6dSspeer nxge_fill_tcam_entry_udp_ipv6(nxgep, 142352ccf843Smisaki flow_spec, &tcam_ptr); 1424a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, 142552ccf843Smisaki TCAM_CLASS_UDP_IPV6, 1426*4df55fdeSJanie Lu flow_cookie); 1427a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, 142852ccf843Smisaki TCAM_CLASS_UDP_IPV6, 1429*4df55fdeSJanie Lu channel_cookie); 1430a3c5bd6dSspeer break; 1431a3c5bd6dSspeer 1432a3c5bd6dSspeer case FSPEC_SCTPIP4: 1433a3c5bd6dSspeer nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr); 1434a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, 143552ccf843Smisaki TCAM_CLASS_SCTP_IPV4, 1436*4df55fdeSJanie Lu flow_cookie); 1437a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, 143852ccf843Smisaki TCAM_CLASS_SCTP_IPV4, 1439*4df55fdeSJanie Lu channel_cookie); 1440a3c5bd6dSspeer break; 1441a3c5bd6dSspeer 1442a3c5bd6dSspeer case FSPEC_SCTPIP6: 1443a3c5bd6dSspeer nxge_fill_tcam_entry_sctp_ipv6(nxgep, 144452ccf843Smisaki flow_spec, &tcam_ptr); 1445a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, 144652ccf843Smisaki TCAM_CLASS_SCTP_IPV6, 1447*4df55fdeSJanie Lu flow_cookie); 1448a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, 144952ccf843Smisaki TCAM_CLASS_SCTP_IPV6, 1450*4df55fdeSJanie Lu channel_cookie); 1451*4df55fdeSJanie Lu break; 1452*4df55fdeSJanie Lu 1453*4df55fdeSJanie Lu case FSPEC_AHIP4: 1454*4df55fdeSJanie Lu case FSPEC_ESPIP4: 1455*4df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp(nxgep, flow_spec, &tcam_ptr); 1456*4df55fdeSJanie Lu rdc_grp = nxge_get_rdc_group(nxgep, 1457*4df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV4, 145852ccf843Smisaki flow_cookie); 1459*4df55fdeSJanie Lu offset = nxge_get_rdc_offset(nxgep, 1460*4df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV4, 1461*4df55fdeSJanie Lu channel_cookie); 1462a3c5bd6dSspeer break; 1463a3c5bd6dSspeer 1464*4df55fdeSJanie Lu case FSPEC_AHIP6: 1465*4df55fdeSJanie Lu case FSPEC_ESPIP6: 1466*4df55fdeSJanie Lu nxge_fill_tcam_entry_ah_esp_ipv6(nxgep, 1467*4df55fdeSJanie Lu flow_spec, &tcam_ptr); 1468*4df55fdeSJanie Lu rdc_grp = nxge_get_rdc_group(nxgep, 1469*4df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV6, 1470*4df55fdeSJanie Lu flow_cookie); 1471*4df55fdeSJanie Lu offset = nxge_get_rdc_offset(nxgep, 1472*4df55fdeSJanie Lu TCAM_CLASS_AH_ESP_IPV6, 1473*4df55fdeSJanie Lu channel_cookie); 1474*4df55fdeSJanie Lu break; 1475*4df55fdeSJanie Lu 1476*4df55fdeSJanie Lu case FSPEC_IP_USR: 1477*4df55fdeSJanie Lu nxge_fill_tcam_entry_ip_usr(nxgep, flow_spec, &tcam_ptr, 1478*4df55fdeSJanie Lu (tcam_class_t)class); 1479*4df55fdeSJanie Lu rdc_grp = nxge_get_rdc_group(nxgep, 1480*4df55fdeSJanie Lu (tcam_class_t)class, flow_cookie); 1481*4df55fdeSJanie Lu offset = nxge_get_rdc_offset(nxgep, 1482*4df55fdeSJanie Lu (tcam_class_t)class, channel_cookie); 1483*4df55fdeSJanie Lu break; 1484a3c5bd6dSspeer default: 1485*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1486*4df55fdeSJanie Lu "nxge_add_tcam_entry: Unknown flow spec 0x%x", 1487*4df55fdeSJanie Lu flow_spec->flow_type)); 1488*4df55fdeSJanie Lu return (NXGE_ERROR); 148944961713Sgirish } 149044961713Sgirish 149144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 149252ccf843Smisaki " nxge_add_tcam_entry write" 149352ccf843Smisaki " for location %d offset %d", location, offset)); 149444961713Sgirish 149544961713Sgirish MUTEX_ENTER(&hw_p->nxge_tcam_lock); 1496a3c5bd6dSspeer rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr); 149744961713Sgirish 149844961713Sgirish if (rs & NPI_FFLP_ERROR) { 149944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 150052ccf843Smisaki " nxge_add_tcam_entry write" 150152ccf843Smisaki " failed for location %d", location)); 1502*4df55fdeSJanie Lu goto fail; 150344961713Sgirish } 1504a3c5bd6dSspeer 150544961713Sgirish tcam_ptr.match_action.value = 0; 150644961713Sgirish tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp; 150744961713Sgirish tcam_ptr.match_action.bits.ldw.offset = offset; 150844961713Sgirish tcam_ptr.match_action.bits.ldw.tres = 150952ccf843Smisaki TRES_TERM_OVRD_L2RDC; 1510*4df55fdeSJanie Lu if (channel_cookie == NXGE_PKT_DISCARD) 151144961713Sgirish tcam_ptr.match_action.bits.ldw.disc = 1; 151244961713Sgirish rs = npi_fflp_tcam_asc_ram_entry_write(handle, 151352ccf843Smisaki location, tcam_ptr.match_action.value); 151444961713Sgirish if (rs & NPI_FFLP_ERROR) { 151544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 151652ccf843Smisaki " nxge_add_tcam_entry write" 151752ccf843Smisaki " failed for ASC RAM location %d", location)); 1518*4df55fdeSJanie Lu goto fail; 151944961713Sgirish } 1520a3c5bd6dSspeer bcopy((void *) &tcam_ptr, 152152ccf843Smisaki (void *) &nxgep->classifier.tcam_entries[location].tce, 152252ccf843Smisaki sizeof (tcam_entry_t)); 1523*4df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt++; 1524*4df55fdeSJanie Lu nxgep->classifier.tcam_entries[location].valid = 1; 152544961713Sgirish 152644961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 152744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry")); 152844961713Sgirish return (NXGE_OK); 1529*4df55fdeSJanie Lu fail: 1530*4df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1531*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_tcam_entry FAILED")); 1532*4df55fdeSJanie Lu return (NXGE_ERROR); 153344961713Sgirish } 153444961713Sgirish 153514ea4bb7Ssd static nxge_status_t 153614ea4bb7Ssd nxge_tcam_handle_ip_fragment(p_nxge_t nxgep) 153744961713Sgirish { 153844961713Sgirish tcam_entry_t tcam_ptr; 153944961713Sgirish tcam_location_t location; 154044961713Sgirish uint8_t class; 154114ea4bb7Ssd uint32_t class_config; 154244961713Sgirish npi_handle_t handle; 154344961713Sgirish npi_status_t rs = NPI_SUCCESS; 1544a3c5bd6dSspeer p_nxge_hw_list_t hw_p; 154514ea4bb7Ssd nxge_status_t status = NXGE_OK; 154644961713Sgirish 154744961713Sgirish handle = nxgep->npi_reg_handle; 154844961713Sgirish class = 0; 1549a3c5bd6dSspeer bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 155044961713Sgirish tcam_ptr.ip4_noport_key = 1; 155144961713Sgirish tcam_ptr.ip4_noport_mask = 1; 155214ea4bb7Ssd location = nxgep->function_num; 155344961713Sgirish nxgep->classifier.fragment_bug_location = location; 155444961713Sgirish 155544961713Sgirish if ((hw_p = nxgep->nxge_hw_p) == NULL) { 155644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 155752ccf843Smisaki " nxge_tcam_handle_ip_fragment: common hardware not set", 155852ccf843Smisaki nxgep->niu_type)); 155914ea4bb7Ssd return (NXGE_ERROR); 156044961713Sgirish } 156144961713Sgirish MUTEX_ENTER(&hw_p->nxge_tcam_lock); 156244961713Sgirish rs = npi_fflp_tcam_entry_write(handle, 156352ccf843Smisaki location, &tcam_ptr); 156444961713Sgirish 156544961713Sgirish if (rs & NPI_FFLP_ERROR) { 156644961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 156744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 156852ccf843Smisaki " nxge_tcam_handle_ip_fragment " 156952ccf843Smisaki " tcam_entry write" 157052ccf843Smisaki " failed for location %d", location)); 157114ea4bb7Ssd return (NXGE_ERROR); 157244961713Sgirish } 157344961713Sgirish tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp; 1574a3c5bd6dSspeer tcam_ptr.match_action.bits.ldw.offset = 0; /* use the default */ 157544961713Sgirish tcam_ptr.match_action.bits.ldw.tres = 157652ccf843Smisaki TRES_TERM_USE_OFFSET; 157744961713Sgirish rs = npi_fflp_tcam_asc_ram_entry_write(handle, 157852ccf843Smisaki location, tcam_ptr.match_action.value); 157944961713Sgirish 158044961713Sgirish if (rs & NPI_FFLP_ERROR) { 158144961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 158244961713Sgirish NXGE_DEBUG_MSG((nxgep, 158352ccf843Smisaki FFLP_CTL, 158452ccf843Smisaki " nxge_tcam_handle_ip_fragment " 158552ccf843Smisaki " tcam_entry write" 158652ccf843Smisaki " failed for ASC RAM location %d", location)); 158714ea4bb7Ssd return (NXGE_ERROR); 158844961713Sgirish } 1589a3c5bd6dSspeer bcopy((void *) &tcam_ptr, 159052ccf843Smisaki (void *) &nxgep->classifier.tcam_entries[location].tce, 159152ccf843Smisaki sizeof (tcam_entry_t)); 1592*4df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt++; 1593*4df55fdeSJanie Lu nxgep->classifier.tcam_entries[location].valid = 1; 159414ea4bb7Ssd for (class = TCAM_CLASS_TCP_IPV4; 159552ccf843Smisaki class <= TCAM_CLASS_SCTP_IPV6; class++) { 159614ea4bb7Ssd class_config = nxgep->class_config.class_cfg[class]; 159714ea4bb7Ssd class_config |= NXGE_CLASS_TCAM_LOOKUP; 159814ea4bb7Ssd status = nxge_fflp_ip_class_config(nxgep, class, class_config); 159914ea4bb7Ssd 160014ea4bb7Ssd if (status & NPI_FFLP_ERROR) { 160114ea4bb7Ssd MUTEX_EXIT(&hw_p->nxge_tcam_lock); 160214ea4bb7Ssd NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 160352ccf843Smisaki "nxge_tcam_handle_ip_fragment " 160452ccf843Smisaki "nxge_fflp_ip_class_config failed " 160552ccf843Smisaki " class %d config %x ", class, class_config)); 160614ea4bb7Ssd return (NXGE_ERROR); 160714ea4bb7Ssd } 160814ea4bb7Ssd } 160914ea4bb7Ssd 161014ea4bb7Ssd rs = npi_fflp_cfg_tcam_enable(handle); 161114ea4bb7Ssd if (rs & NPI_FFLP_ERROR) { 161214ea4bb7Ssd MUTEX_EXIT(&hw_p->nxge_tcam_lock); 161314ea4bb7Ssd NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 161452ccf843Smisaki "nxge_tcam_handle_ip_fragment " 161552ccf843Smisaki " nxge_fflp_config_tcam_enable failed")); 161614ea4bb7Ssd return (NXGE_ERROR); 161714ea4bb7Ssd } 161844961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 161914ea4bb7Ssd return (NXGE_OK); 162044961713Sgirish } 162144961713Sgirish 162244961713Sgirish /* ARGSUSED */ 162344961713Sgirish static int 1624a3c5bd6dSspeer nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res) 162544961713Sgirish { 162644961713Sgirish return (0); 162744961713Sgirish } 162844961713Sgirish 162944961713Sgirish nxge_status_t 163044961713Sgirish nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res) 163144961713Sgirish { 163244961713Sgirish 163344961713Sgirish int insert_hash = 0; 163444961713Sgirish nxge_status_t status = NXGE_OK; 163544961713Sgirish 16362e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1637a3c5bd6dSspeer /* determine whether to do TCAM or Hash flow */ 163844961713Sgirish insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res); 163944961713Sgirish } 164044961713Sgirish if (insert_hash) { 164144961713Sgirish status = nxge_add_fcram_entry(nxgep, flow_res); 164244961713Sgirish } else { 164344961713Sgirish status = nxge_add_tcam_entry(nxgep, flow_res); 164444961713Sgirish } 164544961713Sgirish return (status); 164644961713Sgirish } 164744961713Sgirish 164844961713Sgirish void 164944961713Sgirish nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp) 165044961713Sgirish { 165144961713Sgirish flow_resource_t *fs; 165244961713Sgirish 1653a3c5bd6dSspeer fs = (flow_resource_t *)mp->b_rptr; 165444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 165552ccf843Smisaki "nxge_put_tcam addr fs $%p type %x offset %x", 165652ccf843Smisaki fs, fs->flow_spec.flow_type, fs->channel_cookie)); 165744961713Sgirish (void) nxge_add_tcam_entry(nxgep, fs); 165844961713Sgirish } 165944961713Sgirish 166044961713Sgirish nxge_status_t 166144961713Sgirish nxge_fflp_config_tcam_enable(p_nxge_t nxgep) 166244961713Sgirish { 166344961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 166444961713Sgirish npi_status_t rs = NPI_SUCCESS; 166544961713Sgirish 166644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable")); 166744961713Sgirish rs = npi_fflp_cfg_tcam_enable(handle); 166844961713Sgirish if (rs & NPI_FFLP_ERROR) { 166944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 167052ccf843Smisaki " nxge_fflp_config_tcam_enable failed")); 167144961713Sgirish return (NXGE_ERROR | rs); 167244961713Sgirish } 167344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable")); 167444961713Sgirish return (NXGE_OK); 167544961713Sgirish } 167644961713Sgirish 167744961713Sgirish nxge_status_t 167844961713Sgirish nxge_fflp_config_tcam_disable(p_nxge_t nxgep) 167944961713Sgirish { 168044961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 168144961713Sgirish npi_status_t rs = NPI_SUCCESS; 168244961713Sgirish 168344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 168452ccf843Smisaki " ==> nxge_fflp_config_tcam_disable")); 168544961713Sgirish rs = npi_fflp_cfg_tcam_disable(handle); 168644961713Sgirish if (rs & NPI_FFLP_ERROR) { 168744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 168852ccf843Smisaki " nxge_fflp_config_tcam_disable failed")); 168944961713Sgirish return (NXGE_ERROR | rs); 169044961713Sgirish } 169144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 169252ccf843Smisaki " <== nxge_fflp_config_tcam_disable")); 169344961713Sgirish return (NXGE_OK); 169444961713Sgirish } 169544961713Sgirish 169644961713Sgirish nxge_status_t 169744961713Sgirish nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep) 169844961713Sgirish { 169944961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 170044961713Sgirish npi_status_t rs = NPI_SUCCESS; 1701a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 1702a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 1703a3c5bd6dSspeer uint8_t partition; 170444961713Sgirish 170544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 170652ccf843Smisaki " ==> nxge_fflp_config_hash_lookup_enable")); 170744961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 170844961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 170944961713Sgirish 1710678453a8Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 1711678453a8Sspeer if (p_cfgp->grpids[partition]) { 1712678453a8Sspeer rs = npi_fflp_cfg_fcram_partition_enable( 171352ccf843Smisaki handle, partition); 1714678453a8Sspeer if (rs != NPI_SUCCESS) { 1715678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1716678453a8Sspeer " nxge_fflp_config_hash_lookup_enable" 1717678453a8Sspeer "failed FCRAM partition" 1718678453a8Sspeer " enable for partition %d ", partition)); 1719678453a8Sspeer return (NXGE_ERROR | rs); 1720678453a8Sspeer } 172144961713Sgirish } 172244961713Sgirish } 172344961713Sgirish 172444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 172552ccf843Smisaki " <== nxge_fflp_config_hash_lookup_enable")); 172644961713Sgirish return (NXGE_OK); 172744961713Sgirish } 172844961713Sgirish 172944961713Sgirish nxge_status_t 173044961713Sgirish nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep) 173144961713Sgirish { 173244961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 173344961713Sgirish npi_status_t rs = NPI_SUCCESS; 1734a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 1735a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 1736a3c5bd6dSspeer uint8_t partition; 173744961713Sgirish 173844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 173952ccf843Smisaki " ==> nxge_fflp_config_hash_lookup_disable")); 174044961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 174144961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 174244961713Sgirish 1743678453a8Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 1744678453a8Sspeer if (p_cfgp->grpids[partition]) { 1745678453a8Sspeer rs = npi_fflp_cfg_fcram_partition_disable(handle, 1746678453a8Sspeer partition); 1747678453a8Sspeer if (rs != NPI_SUCCESS) { 1748678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1749678453a8Sspeer " nxge_fflp_config_hash_lookup_disable" 1750678453a8Sspeer " failed FCRAM partition" 1751678453a8Sspeer " disable for partition %d ", partition)); 1752678453a8Sspeer return (NXGE_ERROR | rs); 1753678453a8Sspeer } 175444961713Sgirish } 175544961713Sgirish } 175644961713Sgirish 175744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 175852ccf843Smisaki " <== nxge_fflp_config_hash_lookup_disable")); 175944961713Sgirish return (NXGE_OK); 176044961713Sgirish } 176144961713Sgirish 176244961713Sgirish nxge_status_t 176344961713Sgirish nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep) 176444961713Sgirish { 176544961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 176644961713Sgirish npi_status_t rs = NPI_SUCCESS; 176744961713Sgirish 176844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 176952ccf843Smisaki " ==> nxge_fflp_config_llc_snap_enable")); 177044961713Sgirish rs = npi_fflp_cfg_llcsnap_enable(handle); 177144961713Sgirish if (rs & NPI_FFLP_ERROR) { 177244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 177352ccf843Smisaki " nxge_fflp_config_llc_snap_enable failed")); 177444961713Sgirish return (NXGE_ERROR | rs); 177544961713Sgirish } 177644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 177752ccf843Smisaki " <== nxge_fflp_config_llc_snap_enable")); 177844961713Sgirish return (NXGE_OK); 177944961713Sgirish } 178044961713Sgirish 178144961713Sgirish nxge_status_t 178244961713Sgirish nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep) 178344961713Sgirish { 178444961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 178544961713Sgirish npi_status_t rs = NPI_SUCCESS; 1786a3c5bd6dSspeer 178744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 178852ccf843Smisaki " ==> nxge_fflp_config_llc_snap_disable")); 178944961713Sgirish rs = npi_fflp_cfg_llcsnap_disable(handle); 179044961713Sgirish if (rs & NPI_FFLP_ERROR) { 179144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 179252ccf843Smisaki " nxge_fflp_config_llc_snap_disable failed")); 179344961713Sgirish return (NXGE_ERROR | rs); 179444961713Sgirish } 179544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 179652ccf843Smisaki " <== nxge_fflp_config_llc_snap_disable")); 179744961713Sgirish return (NXGE_OK); 179844961713Sgirish } 179944961713Sgirish 180044961713Sgirish nxge_status_t 180144961713Sgirish nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class, 1802a3c5bd6dSspeer uint32_t config) 180344961713Sgirish { 180444961713Sgirish npi_status_t rs = NPI_SUCCESS; 180544961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 180644961713Sgirish uint8_t tos, tos_mask, proto, ver = 0; 180744961713Sgirish uint8_t class_enable = 0; 180844961713Sgirish 180944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config")); 181044961713Sgirish 181144961713Sgirish tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >> 181252ccf843Smisaki NXGE_CLASS_CFG_IP_TOS_SHIFT; 181344961713Sgirish tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >> 181452ccf843Smisaki NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT; 181544961713Sgirish proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >> 181652ccf843Smisaki NXGE_CLASS_CFG_IP_PROTO_SHIFT; 181744961713Sgirish if (config & NXGE_CLASS_CFG_IP_IPV6_MASK) 181844961713Sgirish ver = 1; 181944961713Sgirish if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK) 182044961713Sgirish class_enable = 1; 182144961713Sgirish rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask, 182252ccf843Smisaki proto, ver); 182344961713Sgirish if (rs & NPI_FFLP_ERROR) { 182444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 182552ccf843Smisaki " nxge_fflp_ip_usr_class_config" 182652ccf843Smisaki " for class %d failed ", class)); 182744961713Sgirish return (NXGE_ERROR | rs); 182844961713Sgirish } 182944961713Sgirish if (class_enable) 183044961713Sgirish rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class); 183144961713Sgirish else 183244961713Sgirish rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 183344961713Sgirish 183444961713Sgirish if (rs & NPI_FFLP_ERROR) { 183544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 183652ccf843Smisaki " nxge_fflp_ip_usr_class_config" 183752ccf843Smisaki " TCAM enable/disable for class %d failed ", class)); 183844961713Sgirish return (NXGE_ERROR | rs); 183944961713Sgirish } 184044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config")); 184144961713Sgirish return (NXGE_OK); 184244961713Sgirish } 184344961713Sgirish 184444961713Sgirish nxge_status_t 1845a3c5bd6dSspeer nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config) 184644961713Sgirish { 184744961713Sgirish uint32_t class_config; 184844961713Sgirish nxge_status_t t_status = NXGE_OK; 184944961713Sgirish nxge_status_t f_status = NXGE_OK; 1850a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 185144961713Sgirish 185244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 1853a3c5bd6dSspeer 185444961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 185544961713Sgirish class_config = p_class_cfgp->class_cfg[class]; 185644961713Sgirish 185744961713Sgirish if (class_config != config) { 185844961713Sgirish p_class_cfgp->class_cfg[class] = config; 185944961713Sgirish class_config = config; 186044961713Sgirish } 186144961713Sgirish 186244961713Sgirish t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config); 186344961713Sgirish f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config); 186444961713Sgirish 186544961713Sgirish if (t_status & NPI_FFLP_ERROR) { 186644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 186752ccf843Smisaki " nxge_fflp_ip_class_config %x" 186852ccf843Smisaki " for class %d tcam failed", config, class)); 186944961713Sgirish return (t_status); 187044961713Sgirish } 187144961713Sgirish if (f_status & NPI_FFLP_ERROR) { 187244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 187352ccf843Smisaki " nxge_fflp_ip_class_config %x" 187452ccf843Smisaki " for class %d flow key failed", config, class)); 187544961713Sgirish return (f_status); 187644961713Sgirish } 187744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 187844961713Sgirish return (NXGE_OK); 187944961713Sgirish } 188044961713Sgirish 188144961713Sgirish nxge_status_t 188244961713Sgirish nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class, 1883a3c5bd6dSspeer uint32_t *config) 188444961713Sgirish { 188544961713Sgirish uint32_t t_class_config, f_class_config; 188644961713Sgirish int t_status = NXGE_OK; 188744961713Sgirish int f_status = NXGE_OK; 188844961713Sgirish 188944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 1890a3c5bd6dSspeer 189144961713Sgirish t_class_config = f_class_config = 0; 189244961713Sgirish t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config); 189344961713Sgirish f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config); 189444961713Sgirish 189544961713Sgirish if (t_status & NPI_FFLP_ERROR) { 189644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 189752ccf843Smisaki " nxge_fflp_ip_class_config_get " 189852ccf843Smisaki " for class %d tcam failed", class)); 189944961713Sgirish return (t_status); 190044961713Sgirish } 190144961713Sgirish 190244961713Sgirish if (f_status & NPI_FFLP_ERROR) { 190344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 190452ccf843Smisaki " nxge_fflp_ip_class_config_get " 190552ccf843Smisaki " for class %d flow key failed", class)); 190644961713Sgirish return (f_status); 190744961713Sgirish } 190844961713Sgirish 190944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 191052ccf843Smisaki " nxge_fflp_ip_class_config tcam %x flow %x", 191152ccf843Smisaki t_class_config, f_class_config)); 191244961713Sgirish 191344961713Sgirish *config = t_class_config | f_class_config; 191444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get")); 191544961713Sgirish return (NXGE_OK); 191644961713Sgirish } 191744961713Sgirish 191844961713Sgirish nxge_status_t 191944961713Sgirish nxge_fflp_ip_class_config_all(p_nxge_t nxgep) 192044961713Sgirish { 192144961713Sgirish uint32_t class_config; 192244961713Sgirish tcam_class_t class; 192344961713Sgirish 192444961713Sgirish #ifdef NXGE_DEBUG 192544961713Sgirish int status = NXGE_OK; 192644961713Sgirish #endif 192744961713Sgirish 192844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config")); 192944961713Sgirish for (class = TCAM_CLASS_TCP_IPV4; 193052ccf843Smisaki class <= TCAM_CLASS_SCTP_IPV6; class++) { 193144961713Sgirish class_config = nxgep->class_config.class_cfg[class]; 193244961713Sgirish #ifndef NXGE_DEBUG 193344961713Sgirish (void) nxge_fflp_ip_class_config(nxgep, class, class_config); 193444961713Sgirish #else 193544961713Sgirish status = nxge_fflp_ip_class_config(nxgep, class, class_config); 193644961713Sgirish if (status & NPI_FFLP_ERROR) { 193744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 193852ccf843Smisaki "nxge_fflp_ip_class_config failed " 193952ccf843Smisaki " class %d config %x ", 194052ccf843Smisaki class, class_config)); 194144961713Sgirish } 194244961713Sgirish #endif 194344961713Sgirish } 194444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 194544961713Sgirish return (NXGE_OK); 194644961713Sgirish } 194744961713Sgirish 194844961713Sgirish nxge_status_t 194944961713Sgirish nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id) 195044961713Sgirish { 195144961713Sgirish uint8_t port, rdc_grp; 195244961713Sgirish npi_handle_t handle; 195344961713Sgirish npi_status_t rs = NPI_SUCCESS; 195444961713Sgirish uint8_t priority = 1; 195544961713Sgirish p_nxge_mv_cfg_t vlan_table; 1956a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 1957a3c5bd6dSspeer p_nxge_hw_list_t hw_p; 195844961713Sgirish 195944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table")); 196044961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 196144961713Sgirish handle = nxgep->npi_reg_handle; 196244961713Sgirish vlan_table = p_class_cfgp->vlan_tbl; 196344961713Sgirish port = nxgep->function_num; 196444961713Sgirish 196544961713Sgirish if (vlan_table[vlan_id].flag == 0) { 196644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 196752ccf843Smisaki " nxge_fflp_config_vlan_table" 196852ccf843Smisaki " vlan id is not configured %d", vlan_id)); 196944961713Sgirish return (NXGE_ERROR); 197044961713Sgirish } 197144961713Sgirish 197244961713Sgirish if ((hw_p = nxgep->nxge_hw_p) == NULL) { 197344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 197452ccf843Smisaki " nxge_fflp_config_vlan_table:" 197552ccf843Smisaki " common hardware not set", nxgep->niu_type)); 197644961713Sgirish return (NXGE_ERROR); 197744961713Sgirish } 197844961713Sgirish MUTEX_ENTER(&hw_p->nxge_vlan_lock); 197944961713Sgirish rdc_grp = vlan_table[vlan_id].rdctbl; 198044961713Sgirish rs = npi_fflp_cfg_enet_vlan_table_assoc(handle, 198152ccf843Smisaki port, vlan_id, 198252ccf843Smisaki rdc_grp, priority); 198344961713Sgirish 198444961713Sgirish MUTEX_EXIT(&hw_p->nxge_vlan_lock); 198544961713Sgirish if (rs & NPI_FFLP_ERROR) { 198644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 198752ccf843Smisaki "nxge_fflp_config_vlan_table failed " 198852ccf843Smisaki " Port %d vlan_id %d rdc_grp %d", 198952ccf843Smisaki port, vlan_id, rdc_grp)); 199044961713Sgirish return (NXGE_ERROR | rs); 199144961713Sgirish } 1992a3c5bd6dSspeer 199344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table")); 199444961713Sgirish return (NXGE_OK); 199544961713Sgirish } 199644961713Sgirish 199744961713Sgirish nxge_status_t 199844961713Sgirish nxge_fflp_update_hw(p_nxge_t nxgep) 199944961713Sgirish { 200044961713Sgirish nxge_status_t status = NXGE_OK; 200144961713Sgirish p_nxge_param_t pa; 200244961713Sgirish uint64_t cfgd_vlans; 200344961713Sgirish uint64_t *val_ptr; 200444961713Sgirish int i; 200544961713Sgirish int num_macs; 200644961713Sgirish uint8_t alt_mac; 200744961713Sgirish nxge_param_map_t *p_map; 200844961713Sgirish p_nxge_mv_cfg_t vlan_table; 2009a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 2010a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_all_cfgp; 2011a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 201244961713Sgirish 201344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw")); 2014a3c5bd6dSspeer 201544961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 201644961713Sgirish p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 201744961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 201844961713Sgirish 201944961713Sgirish status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1); 202044961713Sgirish if (status != NXGE_OK) { 202144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 202252ccf843Smisaki "nxge_fflp_set_hash1 Failed")); 202344961713Sgirish return (NXGE_ERROR); 202444961713Sgirish } 202544961713Sgirish 202644961713Sgirish status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2); 202744961713Sgirish if (status != NXGE_OK) { 202844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 202952ccf843Smisaki "nxge_fflp_set_hash2 Failed")); 203044961713Sgirish return (NXGE_ERROR); 203144961713Sgirish } 203244961713Sgirish vlan_table = p_class_cfgp->vlan_tbl; 203344961713Sgirish 2034a3c5bd6dSspeer /* configure vlan tables */ 203544961713Sgirish pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp]; 2036adfcba55Sjoycey #if defined(__i386) 2037adfcba55Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value; 2038adfcba55Sjoycey #else 203944961713Sgirish val_ptr = (uint64_t *)pa->value; 2040adfcba55Sjoycey #endif 2041a3c5bd6dSspeer cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >> 204252ccf843Smisaki NXGE_PARAM_ARRAY_CNT_SHIFT); 204344961713Sgirish 204444961713Sgirish for (i = 0; i < cfgd_vlans; i++) { 204544961713Sgirish p_map = (nxge_param_map_t *)&val_ptr[i]; 204644961713Sgirish if (vlan_table[p_map->param_id].flag) { 204744961713Sgirish status = nxge_fflp_config_vlan_table(nxgep, 204852ccf843Smisaki p_map->param_id); 204944961713Sgirish if (status != NXGE_OK) { 205044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 205152ccf843Smisaki "nxge_fflp_config_vlan_table Failed")); 205244961713Sgirish return (NXGE_ERROR); 205344961713Sgirish } 205444961713Sgirish } 205544961713Sgirish } 2056a3c5bd6dSspeer 2057a3c5bd6dSspeer /* config MAC addresses */ 205844961713Sgirish num_macs = p_cfgp->max_macs; 205944961713Sgirish pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp]; 2060adfcba55Sjoycey #if defined(__i386) 2061adfcba55Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value; 2062adfcba55Sjoycey #else 206344961713Sgirish val_ptr = (uint64_t *)pa->value; 2064adfcba55Sjoycey #endif 206544961713Sgirish 206644961713Sgirish for (alt_mac = 0; alt_mac < num_macs; alt_mac++) { 206744961713Sgirish if (p_class_cfgp->mac_host_info[alt_mac].flag) { 206844961713Sgirish status = nxge_logical_mac_assign_rdc_table(nxgep, 206952ccf843Smisaki alt_mac); 207044961713Sgirish if (status != NXGE_OK) { 207144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 207252ccf843Smisaki "nxge_logical_mac_assign_rdc_table" 207352ccf843Smisaki " Failed")); 207444961713Sgirish return (NXGE_ERROR); 207544961713Sgirish } 207644961713Sgirish } 207744961713Sgirish } 2078a3c5bd6dSspeer 2079a3c5bd6dSspeer /* Config Hash values */ 2080f6485eecSyc /* config classes */ 208144961713Sgirish status = nxge_fflp_ip_class_config_all(nxgep); 208244961713Sgirish if (status != NXGE_OK) { 208344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 208452ccf843Smisaki "nxge_fflp_ip_class_config_all Failed")); 208544961713Sgirish return (NXGE_ERROR); 208644961713Sgirish } 208744961713Sgirish return (NXGE_OK); 208844961713Sgirish } 208944961713Sgirish 209044961713Sgirish nxge_status_t 209144961713Sgirish nxge_classify_init_hw(p_nxge_t nxgep) 209244961713Sgirish { 209344961713Sgirish nxge_status_t status = NXGE_OK; 209444961713Sgirish 209544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw")); 209644961713Sgirish 209744961713Sgirish if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) { 209844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 209952ccf843Smisaki "nxge_classify_init_hw already init")); 210044961713Sgirish return (NXGE_OK); 210144961713Sgirish } 210244961713Sgirish 2103a3c5bd6dSspeer /* Now do a real configuration */ 210444961713Sgirish status = nxge_fflp_update_hw(nxgep); 210544961713Sgirish if (status != NXGE_OK) { 210644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 210752ccf843Smisaki "nxge_fflp_update_hw failed")); 210844961713Sgirish return (NXGE_ERROR); 210944961713Sgirish } 2110a3c5bd6dSspeer 2111a3c5bd6dSspeer /* Init RDC tables? ? who should do that? rxdma or fflp ? */ 2112a3c5bd6dSspeer /* attach rdc table to the MAC port. */ 211344961713Sgirish status = nxge_main_mac_assign_rdc_table(nxgep); 211444961713Sgirish if (status != NXGE_OK) { 211544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 211652ccf843Smisaki "nxge_main_mac_assign_rdc_table failed")); 211744961713Sgirish return (NXGE_ERROR); 211844961713Sgirish } 2119a3c5bd6dSspeer 212058324dfcSspeer status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 212144961713Sgirish if (status != NXGE_OK) { 212244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 212352ccf843Smisaki "nxge_multicast_mac_assign_rdc_table failed")); 212444961713Sgirish return (NXGE_ERROR); 212544961713Sgirish } 212614ea4bb7Ssd 2127*4df55fdeSJanie Lu if (nxgep->classifier.fragment_bug == 1) { 2128*4df55fdeSJanie Lu status = nxge_tcam_handle_ip_fragment(nxgep); 2129*4df55fdeSJanie Lu if (status != NXGE_OK) { 2130*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2131*4df55fdeSJanie Lu "nxge_tcam_handle_ip_fragment failed")); 2132*4df55fdeSJanie Lu return (NXGE_ERROR); 2133*4df55fdeSJanie Lu } 213414ea4bb7Ssd } 213544961713Sgirish 213644961713Sgirish nxgep->classifier.state |= NXGE_FFLP_HW_INIT; 213744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw")); 213844961713Sgirish return (NXGE_OK); 213944961713Sgirish } 214044961713Sgirish 214144961713Sgirish nxge_status_t 214244961713Sgirish nxge_fflp_handle_sys_errors(p_nxge_t nxgep) 214344961713Sgirish { 2144a3c5bd6dSspeer npi_handle_t handle; 2145a3c5bd6dSspeer p_nxge_fflp_stats_t statsp; 2146a3c5bd6dSspeer uint8_t portn, rdc_grp; 2147a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 2148a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 2149a3c5bd6dSspeer vlan_par_err_t vlan_err; 2150a3c5bd6dSspeer tcam_err_t tcam_err; 2151a3c5bd6dSspeer hash_lookup_err_log1_t fcram1_err; 2152a3c5bd6dSspeer hash_lookup_err_log2_t fcram2_err; 2153a3c5bd6dSspeer hash_tbl_data_log_t fcram_err; 215444961713Sgirish 215544961713Sgirish handle = nxgep->npi_handle; 215644961713Sgirish statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats; 215744961713Sgirish portn = nxgep->mac.portnum; 215844961713Sgirish 215944961713Sgirish /* 2160a3c5bd6dSspeer * need to read the fflp error registers to figure out what the error 2161a3c5bd6dSspeer * is 216244961713Sgirish */ 216344961713Sgirish npi_fflp_vlan_error_get(handle, &vlan_err); 216444961713Sgirish npi_fflp_tcam_error_get(handle, &tcam_err); 216544961713Sgirish 216644961713Sgirish if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) { 216744961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 216852ccf843Smisaki " vlan table parity error on port %d" 216952ccf843Smisaki " addr: 0x%x data: 0x%x", 217052ccf843Smisaki portn, vlan_err.bits.ldw.addr, 217152ccf843Smisaki vlan_err.bits.ldw.data)); 217244961713Sgirish statsp->vlan_parity_err++; 217344961713Sgirish 217444961713Sgirish if (vlan_err.bits.ldw.m_err) { 217544961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 217652ccf843Smisaki " vlan table multiple errors on port %d", 217752ccf843Smisaki portn)); 217844961713Sgirish } 217944961713Sgirish statsp->errlog.vlan = (uint32_t)vlan_err.value; 218044961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 218152ccf843Smisaki NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR); 218244961713Sgirish npi_fflp_vlan_error_clear(handle); 218344961713Sgirish } 218444961713Sgirish 218544961713Sgirish if (tcam_err.bits.ldw.err) { 218644961713Sgirish if (tcam_err.bits.ldw.p_ecc != 0) { 218744961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 218852ccf843Smisaki " TCAM ECC error on port %d" 218952ccf843Smisaki " TCAM entry: 0x%x syndrome: 0x%x", 219052ccf843Smisaki portn, tcam_err.bits.ldw.addr, 219152ccf843Smisaki tcam_err.bits.ldw.syndrome)); 219244961713Sgirish statsp->tcam_ecc_err++; 219344961713Sgirish } else { 219444961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 219552ccf843Smisaki " TCAM Parity error on port %d" 219652ccf843Smisaki " addr: 0x%x parity value: 0x%x", 219752ccf843Smisaki portn, tcam_err.bits.ldw.addr, 219852ccf843Smisaki tcam_err.bits.ldw.syndrome)); 219944961713Sgirish statsp->tcam_parity_err++; 220044961713Sgirish } 220144961713Sgirish 220244961713Sgirish if (tcam_err.bits.ldw.mult) { 220344961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 220452ccf843Smisaki " TCAM Multiple errors on port %d", portn)); 220544961713Sgirish } else { 220644961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 220752ccf843Smisaki " TCAM PIO error on port %d", portn)); 220844961713Sgirish } 220944961713Sgirish 221044961713Sgirish statsp->errlog.tcam = (uint32_t)tcam_err.value; 221144961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 221252ccf843Smisaki NXGE_FM_EREPORT_FFLP_TCAM_ERR); 221344961713Sgirish npi_fflp_tcam_error_clear(handle); 221444961713Sgirish } 221544961713Sgirish 221644961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 221744961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 221844961713Sgirish 2219678453a8Sspeer for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) { 2220678453a8Sspeer if (p_cfgp->grpids[rdc_grp]) { 2221678453a8Sspeer npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp); 2222678453a8Sspeer if (fcram_err.bits.ldw.pio_err) { 2223678453a8Sspeer NXGE_ERROR_MSG((nxgep, FFLP_CTL, 222452ccf843Smisaki " FCRAM PIO ECC error on port %d" 222552ccf843Smisaki " rdc group: %d Hash Table addr: 0x%x" 222652ccf843Smisaki " syndrome: 0x%x", 222752ccf843Smisaki portn, rdc_grp, 222852ccf843Smisaki fcram_err.bits.ldw.fcram_addr, 222952ccf843Smisaki fcram_err.bits.ldw.syndrome)); 2230678453a8Sspeer statsp->hash_pio_err[rdc_grp]++; 2231678453a8Sspeer statsp->errlog.hash_pio[rdc_grp] = 2232678453a8Sspeer (uint32_t)fcram_err.value; 2233678453a8Sspeer NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 2234678453a8Sspeer NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR); 2235678453a8Sspeer npi_fflp_fcram_error_clear(handle, rdc_grp); 2236678453a8Sspeer } 223744961713Sgirish } 223844961713Sgirish } 223944961713Sgirish 224044961713Sgirish npi_fflp_fcram_error_log1_get(handle, &fcram1_err); 224144961713Sgirish if (fcram1_err.bits.ldw.ecc_err) { 224244961713Sgirish char *multi_str = ""; 224344961713Sgirish char *multi_bit_str = ""; 2244a3c5bd6dSspeer 224544961713Sgirish npi_fflp_fcram_error_log2_get(handle, &fcram2_err); 224644961713Sgirish if (fcram1_err.bits.ldw.mult_lk) { 224744961713Sgirish multi_str = "multiple"; 224844961713Sgirish } 224944961713Sgirish if (fcram1_err.bits.ldw.mult_bit) { 225044961713Sgirish multi_bit_str = "multiple bits"; 225144961713Sgirish } 2252f6485eecSyc statsp->hash_lookup_err++; 225344961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 225452ccf843Smisaki " FCRAM %s lookup %s ECC error on port %d" 225552ccf843Smisaki " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x", 225652ccf843Smisaki multi_str, multi_bit_str, portn, 225752ccf843Smisaki fcram2_err.bits.ldw.h1, 225852ccf843Smisaki fcram2_err.bits.ldw.subarea, 225952ccf843Smisaki fcram2_err.bits.ldw.syndrome)); 226044961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 226152ccf843Smisaki NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR); 226244961713Sgirish } 226344961713Sgirish statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value; 226444961713Sgirish statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value; 226544961713Sgirish return (NXGE_OK); 226644961713Sgirish } 2267*4df55fdeSJanie Lu 2268*4df55fdeSJanie Lu int 2269*4df55fdeSJanie Lu nxge_get_valid_tcam_cnt(p_nxge_t nxgep) { 2270*4df55fdeSJanie Lu return ((nxgep->classifier.fragment_bug == 1) ? 2271*4df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt - 1 : 2272*4df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt); 2273*4df55fdeSJanie Lu } 2274*4df55fdeSJanie Lu 2275*4df55fdeSJanie Lu int 2276*4df55fdeSJanie Lu nxge_rxdma_channel_cnt(p_nxge_t nxgep) 2277*4df55fdeSJanie Lu { 2278*4df55fdeSJanie Lu p_nxge_dma_pt_cfg_t p_dma_cfgp; 2279*4df55fdeSJanie Lu p_nxge_hw_pt_cfg_t p_cfgp; 2280*4df55fdeSJanie Lu 2281*4df55fdeSJanie Lu p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2282*4df55fdeSJanie Lu p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2283*4df55fdeSJanie Lu return (p_cfgp->max_rdcs); 2284*4df55fdeSJanie Lu } 2285*4df55fdeSJanie Lu 2286*4df55fdeSJanie Lu /* ARGSUSED */ 2287*4df55fdeSJanie Lu int 2288*4df55fdeSJanie Lu nxge_rxclass_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 2289*4df55fdeSJanie Lu { 2290*4df55fdeSJanie Lu uint32_t cmd; 2291*4df55fdeSJanie Lu rx_class_cfg_t *cfg_info = (rx_class_cfg_t *)mp->b_rptr; 2292*4df55fdeSJanie Lu 2293*4df55fdeSJanie Lu if (nxgep == NULL) { 2294*4df55fdeSJanie Lu return (-1); 2295*4df55fdeSJanie Lu } 2296*4df55fdeSJanie Lu cmd = cfg_info->cmd; 2297*4df55fdeSJanie Lu switch (cmd) { 2298*4df55fdeSJanie Lu default: 2299*4df55fdeSJanie Lu return (-1); 2300*4df55fdeSJanie Lu 2301*4df55fdeSJanie Lu case NXGE_RX_CLASS_GCHAN: 2302*4df55fdeSJanie Lu cfg_info->data = nxge_rxdma_channel_cnt(nxgep); 2303*4df55fdeSJanie Lu break; 2304*4df55fdeSJanie Lu case NXGE_RX_CLASS_GRULE_CNT: 2305*4df55fdeSJanie Lu MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2306*4df55fdeSJanie Lu cfg_info->rule_cnt = nxge_get_valid_tcam_cnt(nxgep); 2307*4df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2308*4df55fdeSJanie Lu break; 2309*4df55fdeSJanie Lu case NXGE_RX_CLASS_GRULE: 2310*4df55fdeSJanie Lu nxge_get_tcam_entry(nxgep, &cfg_info->fs); 2311*4df55fdeSJanie Lu break; 2312*4df55fdeSJanie Lu case NXGE_RX_CLASS_GRULE_ALL: 2313*4df55fdeSJanie Lu nxge_get_tcam_entry_all(nxgep, cfg_info); 2314*4df55fdeSJanie Lu break; 2315*4df55fdeSJanie Lu case NXGE_RX_CLASS_RULE_DEL: 2316*4df55fdeSJanie Lu nxge_del_tcam_entry(nxgep, cfg_info->fs.location); 2317*4df55fdeSJanie Lu break; 2318*4df55fdeSJanie Lu case NXGE_RX_CLASS_RULE_INS: 2319*4df55fdeSJanie Lu (void) nxge_add_tcam_entry(nxgep, &cfg_info->fs); 2320*4df55fdeSJanie Lu break; 2321*4df55fdeSJanie Lu } 2322*4df55fdeSJanie Lu return (0); 2323*4df55fdeSJanie Lu } 2324*4df55fdeSJanie Lu /* ARGSUSED */ 2325*4df55fdeSJanie Lu int 2326*4df55fdeSJanie Lu nxge_rxhash_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 2327*4df55fdeSJanie Lu { 2328*4df55fdeSJanie Lu uint32_t cmd; 2329*4df55fdeSJanie Lu cfg_cmd_t *cfg_info = (cfg_cmd_t *)mp->b_rptr; 2330*4df55fdeSJanie Lu 2331*4df55fdeSJanie Lu if (nxgep == NULL) { 2332*4df55fdeSJanie Lu return (-1); 2333*4df55fdeSJanie Lu } 2334*4df55fdeSJanie Lu cmd = cfg_info->cmd; 2335*4df55fdeSJanie Lu 2336*4df55fdeSJanie Lu switch (cmd) { 2337*4df55fdeSJanie Lu default: 2338*4df55fdeSJanie Lu return (-1); 2339*4df55fdeSJanie Lu case NXGE_IPTUN_CFG_ADD_CLS: 2340*4df55fdeSJanie Lu nxge_add_iptun_class(nxgep, &cfg_info->iptun_cfg, 2341*4df55fdeSJanie Lu &cfg_info->class_id); 2342*4df55fdeSJanie Lu break; 2343*4df55fdeSJanie Lu case NXGE_IPTUN_CFG_SET_HASH: 2344*4df55fdeSJanie Lu nxge_cfg_iptun_hash(nxgep, &cfg_info->iptun_cfg, 2345*4df55fdeSJanie Lu cfg_info->class_id); 2346*4df55fdeSJanie Lu break; 2347*4df55fdeSJanie Lu case NXGE_IPTUN_CFG_DEL_CLS: 2348*4df55fdeSJanie Lu nxge_del_iptun_class(nxgep, cfg_info->class_id); 2349*4df55fdeSJanie Lu break; 2350*4df55fdeSJanie Lu case NXGE_IPTUN_CFG_GET_CLS: 2351*4df55fdeSJanie Lu nxge_get_iptun_class(nxgep, &cfg_info->iptun_cfg, 2352*4df55fdeSJanie Lu cfg_info->class_id); 2353*4df55fdeSJanie Lu break; 2354*4df55fdeSJanie Lu case NXGE_CLS_CFG_SET_SYM: 2355*4df55fdeSJanie Lu nxge_set_ip_cls_sym(nxgep, cfg_info->class_id, cfg_info->sym); 2356*4df55fdeSJanie Lu break; 2357*4df55fdeSJanie Lu case NXGE_CLS_CFG_GET_SYM: 2358*4df55fdeSJanie Lu nxge_get_ip_cls_sym(nxgep, cfg_info->class_id, &cfg_info->sym); 2359*4df55fdeSJanie Lu break; 2360*4df55fdeSJanie Lu } 2361*4df55fdeSJanie Lu return (0); 2362*4df55fdeSJanie Lu } 2363*4df55fdeSJanie Lu 2364*4df55fdeSJanie Lu void 2365*4df55fdeSJanie Lu nxge_get_tcam_entry_all(p_nxge_t nxgep, rx_class_cfg_t *cfgp) 2366*4df55fdeSJanie Lu { 2367*4df55fdeSJanie Lu nxge_classify_t *clasp = &nxgep->classifier; 2368*4df55fdeSJanie Lu uint16_t n_entries; 2369*4df55fdeSJanie Lu int i, j, k; 2370*4df55fdeSJanie Lu tcam_flow_spec_t *tcam_entryp; 2371*4df55fdeSJanie Lu 2372*4df55fdeSJanie Lu cfgp->data = clasp->tcam_size; 2373*4df55fdeSJanie Lu MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2374*4df55fdeSJanie Lu n_entries = cfgp->rule_cnt; 2375*4df55fdeSJanie Lu 2376*4df55fdeSJanie Lu for (i = 0, j = 0; j < cfgp->data; j++) { 2377*4df55fdeSJanie Lu k = nxge_tcam_get_index(nxgep, j); 2378*4df55fdeSJanie Lu tcam_entryp = &clasp->tcam_entries[k]; 2379*4df55fdeSJanie Lu if (tcam_entryp->valid != 1) 2380*4df55fdeSJanie Lu continue; 2381*4df55fdeSJanie Lu cfgp->rule_locs[i] = j; 2382*4df55fdeSJanie Lu i++; 2383*4df55fdeSJanie Lu }; 2384*4df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2385*4df55fdeSJanie Lu 2386*4df55fdeSJanie Lu if (n_entries != i) { 2387*4df55fdeSJanie Lu /* print warning, this should not happen */ 2388*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry_all" 2389*4df55fdeSJanie Lu "n_entries[%d] != i[%d]!!!", n_entries, i)); 2390*4df55fdeSJanie Lu } 2391*4df55fdeSJanie Lu } 2392*4df55fdeSJanie Lu 2393*4df55fdeSJanie Lu 2394*4df55fdeSJanie Lu /* Entries for the ports are interleaved in the TCAM */ 2395*4df55fdeSJanie Lu static uint16_t 2396*4df55fdeSJanie Lu nxge_tcam_get_index(p_nxge_t nxgep, uint16_t index) 2397*4df55fdeSJanie Lu { 2398*4df55fdeSJanie Lu /* One entry reserved for IP fragment rule */ 2399*4df55fdeSJanie Lu if (index >= (nxgep->classifier.tcam_size - 1)) 2400*4df55fdeSJanie Lu index = 0; 2401*4df55fdeSJanie Lu if (nxgep->classifier.fragment_bug == 1) 2402*4df55fdeSJanie Lu index++; 2403*4df55fdeSJanie Lu return (nxgep->classifier.tcam_top + (index * nxgep->nports)); 2404*4df55fdeSJanie Lu } 2405*4df55fdeSJanie Lu 2406*4df55fdeSJanie Lu static uint32_t 2407*4df55fdeSJanie Lu nxge_tcam_cls_to_flow(uint32_t class_code) { 2408*4df55fdeSJanie Lu switch (class_code) { 2409*4df55fdeSJanie Lu case TCAM_CLASS_TCP_IPV4: 2410*4df55fdeSJanie Lu return (FSPEC_TCPIP4); 2411*4df55fdeSJanie Lu case TCAM_CLASS_UDP_IPV4: 2412*4df55fdeSJanie Lu return (FSPEC_UDPIP4); 2413*4df55fdeSJanie Lu case TCAM_CLASS_AH_ESP_IPV4: 2414*4df55fdeSJanie Lu return (FSPEC_AHIP4); 2415*4df55fdeSJanie Lu case TCAM_CLASS_SCTP_IPV4: 2416*4df55fdeSJanie Lu return (FSPEC_SCTPIP4); 2417*4df55fdeSJanie Lu case TCAM_CLASS_TCP_IPV6: 2418*4df55fdeSJanie Lu return (FSPEC_TCPIP6); 2419*4df55fdeSJanie Lu case TCAM_CLASS_UDP_IPV6: 2420*4df55fdeSJanie Lu return (FSPEC_UDPIP6); 2421*4df55fdeSJanie Lu case TCAM_CLASS_AH_ESP_IPV6: 2422*4df55fdeSJanie Lu return (FSPEC_AHIP6); 2423*4df55fdeSJanie Lu case TCAM_CLASS_SCTP_IPV6: 2424*4df55fdeSJanie Lu return (FSPEC_SCTPIP6); 2425*4df55fdeSJanie Lu case TCAM_CLASS_IP_USER_4: 2426*4df55fdeSJanie Lu case TCAM_CLASS_IP_USER_5: 2427*4df55fdeSJanie Lu case TCAM_CLASS_IP_USER_6: 2428*4df55fdeSJanie Lu case TCAM_CLASS_IP_USER_7: 2429*4df55fdeSJanie Lu return (FSPEC_IP_USR); 2430*4df55fdeSJanie Lu default: 2431*4df55fdeSJanie Lu NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "nxge_tcam_cls_to_flow" 2432*4df55fdeSJanie Lu ": Unknown class code [0x%x]", class_code)); 2433*4df55fdeSJanie Lu break; 2434*4df55fdeSJanie Lu } 2435*4df55fdeSJanie Lu return (0); 2436*4df55fdeSJanie Lu } 2437*4df55fdeSJanie Lu 2438*4df55fdeSJanie Lu void 2439*4df55fdeSJanie Lu nxge_get_tcam_entry(p_nxge_t nxgep, flow_resource_t *fs) 2440*4df55fdeSJanie Lu { 2441*4df55fdeSJanie Lu uint16_t index; 2442*4df55fdeSJanie Lu tcam_flow_spec_t *tcam_ep; 2443*4df55fdeSJanie Lu tcam_entry_t *tp; 2444*4df55fdeSJanie Lu flow_spec_t *fspec; 2445*4df55fdeSJanie Lu tcpip4_spec_t *fspec_key; 2446*4df55fdeSJanie Lu tcpip4_spec_t *fspec_mask; 2447*4df55fdeSJanie Lu 2448*4df55fdeSJanie Lu index = nxge_tcam_get_index(nxgep, (uint16_t)fs->location); 2449*4df55fdeSJanie Lu tcam_ep = &nxgep->classifier.tcam_entries[index]; 2450*4df55fdeSJanie Lu if (tcam_ep->valid != 1) { 2451*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry: :" 2452*4df55fdeSJanie Lu "Entry [%d] invalid for index [%d]", fs->location, index)); 2453*4df55fdeSJanie Lu return; 2454*4df55fdeSJanie Lu } 2455*4df55fdeSJanie Lu 2456*4df55fdeSJanie Lu /* Fill the flow spec entry */ 2457*4df55fdeSJanie Lu tp = &tcam_ep->tce; 2458*4df55fdeSJanie Lu fspec = &fs->flow_spec; 2459*4df55fdeSJanie Lu fspec->flow_type = nxge_tcam_cls_to_flow(tp->ip4_class_key); 2460*4df55fdeSJanie Lu 2461*4df55fdeSJanie Lu /* TODO - look at proto field to differentiate between AH and ESP */ 2462*4df55fdeSJanie Lu if (fspec->flow_type == FSPEC_AHIP4) { 2463*4df55fdeSJanie Lu if (tp->ip4_proto_key == IPPROTO_ESP) 2464*4df55fdeSJanie Lu fspec->flow_type = FSPEC_ESPIP4; 2465*4df55fdeSJanie Lu } 2466*4df55fdeSJanie Lu 2467*4df55fdeSJanie Lu switch (tp->ip4_class_key) { 2468*4df55fdeSJanie Lu case TCAM_CLASS_TCP_IPV4: 2469*4df55fdeSJanie Lu case TCAM_CLASS_UDP_IPV4: 2470*4df55fdeSJanie Lu case TCAM_CLASS_AH_ESP_IPV4: 2471*4df55fdeSJanie Lu case TCAM_CLASS_SCTP_IPV4: 2472*4df55fdeSJanie Lu fspec_key = (tcpip4_spec_t *)&fspec->uh.tcpip4spec; 2473*4df55fdeSJanie Lu fspec_mask = (tcpip4_spec_t *)&fspec->um.tcpip4spec; 2474*4df55fdeSJanie Lu FSPEC_IPV4_ADDR(fspec_key->ip4dst, tp->ip4_dest_key); 2475*4df55fdeSJanie Lu FSPEC_IPV4_ADDR(fspec_mask->ip4dst, tp->ip4_dest_mask); 2476*4df55fdeSJanie Lu FSPEC_IPV4_ADDR(fspec_key->ip4src, tp->ip4_src_key); 2477*4df55fdeSJanie Lu FSPEC_IPV4_ADDR(fspec_mask->ip4src, tp->ip4_src_mask); 2478*4df55fdeSJanie Lu fspec_key->tos = tp->ip4_tos_key; 2479*4df55fdeSJanie Lu fspec_mask->tos = tp->ip4_tos_mask; 2480*4df55fdeSJanie Lu break; 2481*4df55fdeSJanie Lu default: 2482*4df55fdeSJanie Lu break; 2483*4df55fdeSJanie Lu } 2484*4df55fdeSJanie Lu 2485*4df55fdeSJanie Lu switch (tp->ip4_class_key) { 2486*4df55fdeSJanie Lu case TCAM_CLASS_TCP_IPV4: 2487*4df55fdeSJanie Lu case TCAM_CLASS_UDP_IPV4: 2488*4df55fdeSJanie Lu case TCAM_CLASS_SCTP_IPV4: 2489*4df55fdeSJanie Lu FSPEC_IP_PORTS(fspec_key->pdst, fspec_key->psrc, 2490*4df55fdeSJanie Lu tp->ip4_port_key); 2491*4df55fdeSJanie Lu FSPEC_IP_PORTS(fspec_mask->pdst, fspec_mask->psrc, 2492*4df55fdeSJanie Lu tp->ip4_port_mask); 2493*4df55fdeSJanie Lu break; 2494*4df55fdeSJanie Lu case TCAM_CLASS_AH_ESP_IPV4: 2495*4df55fdeSJanie Lu fspec->uh.ahip4spec.spi = tp->ip4_port_key; 2496*4df55fdeSJanie Lu fspec->um.ahip4spec.spi = tp->ip4_port_mask; 2497*4df55fdeSJanie Lu break; 2498*4df55fdeSJanie Lu case TCAM_CLASS_IP_USER_4: 2499*4df55fdeSJanie Lu case TCAM_CLASS_IP_USER_5: 2500*4df55fdeSJanie Lu case TCAM_CLASS_IP_USER_6: 2501*4df55fdeSJanie Lu case TCAM_CLASS_IP_USER_7: 2502*4df55fdeSJanie Lu fspec->uh.ip_usr_spec.l4_4_bytes = tp->ip4_port_key; 2503*4df55fdeSJanie Lu fspec->um.ip_usr_spec.l4_4_bytes = tp->ip4_port_mask; 2504*4df55fdeSJanie Lu fspec->uh.ip_usr_spec.ip_ver = FSPEC_IP4; 2505*4df55fdeSJanie Lu fspec->uh.ip_usr_spec.proto = tp->ip4_proto_key; 2506*4df55fdeSJanie Lu fspec->um.ip_usr_spec.proto = tp->ip4_proto_mask; 2507*4df55fdeSJanie Lu break; 2508*4df55fdeSJanie Lu default: 2509*4df55fdeSJanie Lu break; 2510*4df55fdeSJanie Lu } 2511*4df55fdeSJanie Lu 2512*4df55fdeSJanie Lu if (tp->match_action.bits.ldw.disc == 1) { 2513*4df55fdeSJanie Lu fs->channel_cookie = NXGE_PKT_DISCARD; 2514*4df55fdeSJanie Lu } else { 2515*4df55fdeSJanie Lu fs->channel_cookie = tp->match_action.bits.ldw.offset; 2516*4df55fdeSJanie Lu } 2517*4df55fdeSJanie Lu } 2518*4df55fdeSJanie Lu 2519*4df55fdeSJanie Lu void 2520*4df55fdeSJanie Lu nxge_del_tcam_entry(p_nxge_t nxgep, uint32_t location) 2521*4df55fdeSJanie Lu { 2522*4df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 2523*4df55fdeSJanie Lu uint16_t index; 2524*4df55fdeSJanie Lu tcam_flow_spec_t *tcam_ep; 2525*4df55fdeSJanie Lu tcam_entry_t *tp; 2526*4df55fdeSJanie Lu tcam_class_t class; 2527*4df55fdeSJanie Lu 2528*4df55fdeSJanie Lu MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2529*4df55fdeSJanie Lu index = nxge_tcam_get_index(nxgep, (uint16_t)location); 2530*4df55fdeSJanie Lu tcam_ep = &nxgep->classifier.tcam_entries[index]; 2531*4df55fdeSJanie Lu if (tcam_ep->valid != 1) { 2532*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_tcam_entry: :" 2533*4df55fdeSJanie Lu "Entry [%d] invalid for index [%d]", location, index)); 2534*4df55fdeSJanie Lu goto fail; 2535*4df55fdeSJanie Lu } 2536*4df55fdeSJanie Lu 2537*4df55fdeSJanie Lu /* Fill the flow spec entry */ 2538*4df55fdeSJanie Lu tp = &tcam_ep->tce; 2539*4df55fdeSJanie Lu class = tp->ip4_class_key; 2540*4df55fdeSJanie Lu if (class >= TCAM_CLASS_IP_USER_4 && class <= TCAM_CLASS_IP_USER_7) { 2541*4df55fdeSJanie Lu int i; 2542*4df55fdeSJanie Lu nxge_usr_l3_cls_t *l3_ucls_p; 2543*4df55fdeSJanie Lu p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 2544*4df55fdeSJanie Lu 2545*4df55fdeSJanie Lu for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 2546*4df55fdeSJanie Lu l3_ucls_p = &hw_p->tcam_l3_prog_cls[i]; 2547*4df55fdeSJanie Lu if (l3_ucls_p->valid) { 2548*4df55fdeSJanie Lu if (l3_ucls_p->cls == class && 2549*4df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt) { 2550*4df55fdeSJanie Lu l3_ucls_p->tcam_ref_cnt--; 2551*4df55fdeSJanie Lu if (l3_ucls_p->tcam_ref_cnt > 0) 2552*4df55fdeSJanie Lu continue; 2553*4df55fdeSJanie Lu /* disable class */ 2554*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_disable( 2555*4df55fdeSJanie Lu nxgep->npi_reg_handle, 2556*4df55fdeSJanie Lu (tcam_class_t)class); 2557*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2558*4df55fdeSJanie Lu goto fail; 2559*4df55fdeSJanie Lu l3_ucls_p->cls = 0; 2560*4df55fdeSJanie Lu l3_ucls_p->pid = 0; 2561*4df55fdeSJanie Lu l3_ucls_p->valid = 0; 2562*4df55fdeSJanie Lu break; 2563*4df55fdeSJanie Lu } 2564*4df55fdeSJanie Lu } 2565*4df55fdeSJanie Lu } 2566*4df55fdeSJanie Lu if (i == NXGE_L3_PROG_CLS) { 2567*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2568*4df55fdeSJanie Lu "nxge_del_tcam_entry: Usr class " 2569*4df55fdeSJanie Lu "0x%llx not found", (unsigned long long) class)); 2570*4df55fdeSJanie Lu goto fail; 2571*4df55fdeSJanie Lu } 2572*4df55fdeSJanie Lu } 2573*4df55fdeSJanie Lu 2574*4df55fdeSJanie Lu rs = npi_fflp_tcam_entry_invalidate(nxgep->npi_reg_handle, index); 2575*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) { 2576*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2577*4df55fdeSJanie Lu "nxge_del_tcam_entry: TCAM invalidate failed " 2578*4df55fdeSJanie Lu "at loc %d ", location)); 2579*4df55fdeSJanie Lu goto fail; 2580*4df55fdeSJanie Lu } 2581*4df55fdeSJanie Lu 2582*4df55fdeSJanie Lu nxgep->classifier.tcam_entries[index].valid = 0; 2583*4df55fdeSJanie Lu nxgep->classifier.tcam_entry_cnt--; 2584*4df55fdeSJanie Lu 2585*4df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2586*4df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_del_tcam_entry")); 2587*4df55fdeSJanie Lu return; 2588*4df55fdeSJanie Lu fail: 2589*4df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2590*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2591*4df55fdeSJanie Lu "<== nxge_del_tcam_entry FAILED")); 2592*4df55fdeSJanie Lu } 2593*4df55fdeSJanie Lu 2594*4df55fdeSJanie Lu static uint8_t 2595*4df55fdeSJanie Lu nxge_iptun_pkt_type_to_pid(uint8_t pkt_type) 2596*4df55fdeSJanie Lu { 2597*4df55fdeSJanie Lu uint8_t pid = 0; 2598*4df55fdeSJanie Lu 2599*4df55fdeSJanie Lu switch (pkt_type) { 2600*4df55fdeSJanie Lu case IPTUN_PKT_IPV4: 2601*4df55fdeSJanie Lu pid = 4; 2602*4df55fdeSJanie Lu break; 2603*4df55fdeSJanie Lu case IPTUN_PKT_IPV6: 2604*4df55fdeSJanie Lu pid = 41; 2605*4df55fdeSJanie Lu break; 2606*4df55fdeSJanie Lu case IPTUN_PKT_GRE: 2607*4df55fdeSJanie Lu pid = 47; 2608*4df55fdeSJanie Lu break; 2609*4df55fdeSJanie Lu case IPTUN_PKT_GTP: 2610*4df55fdeSJanie Lu pid = 17; 2611*4df55fdeSJanie Lu break; 2612*4df55fdeSJanie Lu default: 2613*4df55fdeSJanie Lu NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 2614*4df55fdeSJanie Lu "nxge_iptun_pkt_type_to_pid: Unknown pkt type 0x%x", 2615*4df55fdeSJanie Lu pkt_type)); 2616*4df55fdeSJanie Lu break; 2617*4df55fdeSJanie Lu } 2618*4df55fdeSJanie Lu 2619*4df55fdeSJanie Lu return (pid); 2620*4df55fdeSJanie Lu } 2621*4df55fdeSJanie Lu 2622*4df55fdeSJanie Lu static npi_status_t 2623*4df55fdeSJanie Lu nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep, uint64_t class, 2624*4df55fdeSJanie Lu iptun_cfg_t *iptunp) 2625*4df55fdeSJanie Lu { 2626*4df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 2627*4df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 2628*4df55fdeSJanie Lu 2629*4df55fdeSJanie Lu switch (iptunp->in_pkt_type) { 2630*4df55fdeSJanie Lu case IPTUN_PKT_IPV4: 2631*4df55fdeSJanie Lu case IPTUN_PKT_IPV6: 2632*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 2633*4df55fdeSJanie Lu (tcam_class_t)class, 0, 0, 0, 0); 2634*4df55fdeSJanie Lu break; 2635*4df55fdeSJanie Lu case IPTUN_PKT_GRE: 2636*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 2637*4df55fdeSJanie Lu (tcam_class_t)class, iptunp->l4b0_val, 2638*4df55fdeSJanie Lu iptunp->l4b0_mask, 0, 0); 2639*4df55fdeSJanie Lu break; 2640*4df55fdeSJanie Lu case IPTUN_PKT_GTP: 2641*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 2642*4df55fdeSJanie Lu (tcam_class_t)class, 0, 0, iptunp->l4b23_val, 2643*4df55fdeSJanie Lu (iptunp->l4b23_sel & 0x01)); 2644*4df55fdeSJanie Lu break; 2645*4df55fdeSJanie Lu default: 2646*4df55fdeSJanie Lu rs = NPI_FFLP_TCAM_CLASS_INVALID; 2647*4df55fdeSJanie Lu break; 2648*4df55fdeSJanie Lu } 2649*4df55fdeSJanie Lu return (rs); 2650*4df55fdeSJanie Lu } 2651*4df55fdeSJanie Lu 2652*4df55fdeSJanie Lu void 2653*4df55fdeSJanie Lu nxge_add_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, 2654*4df55fdeSJanie Lu uint8_t *cls_idp) 2655*4df55fdeSJanie Lu { 2656*4df55fdeSJanie Lu int i, add_cls; 2657*4df55fdeSJanie Lu uint8_t pid; 2658*4df55fdeSJanie Lu uint64_t class; 2659*4df55fdeSJanie Lu p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 2660*4df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 2661*4df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 2662*4df55fdeSJanie Lu 2663*4df55fdeSJanie Lu pid = nxge_iptun_pkt_type_to_pid(iptunp->in_pkt_type); 2664*4df55fdeSJanie Lu if (pid == 0) 2665*4df55fdeSJanie Lu return; 2666*4df55fdeSJanie Lu 2667*4df55fdeSJanie Lu add_cls = 0; 2668*4df55fdeSJanie Lu MUTEX_ENTER(&hw_p->nxge_tcam_lock); 2669*4df55fdeSJanie Lu 2670*4df55fdeSJanie Lu /* Get an user programmable class ID */ 2671*4df55fdeSJanie Lu for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 2672*4df55fdeSJanie Lu if (hw_p->tcam_l3_prog_cls[i].valid == 0) { 2673*4df55fdeSJanie Lu /* todo add new usr class reg */ 2674*4df55fdeSJanie Lu switch (i) { 2675*4df55fdeSJanie Lu case 0: 2676*4df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_4; 2677*4df55fdeSJanie Lu break; 2678*4df55fdeSJanie Lu case 1: 2679*4df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_5; 2680*4df55fdeSJanie Lu break; 2681*4df55fdeSJanie Lu case 2: 2682*4df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_6; 2683*4df55fdeSJanie Lu break; 2684*4df55fdeSJanie Lu case 3: 2685*4df55fdeSJanie Lu class = TCAM_CLASS_IP_USER_7; 2686*4df55fdeSJanie Lu break; 2687*4df55fdeSJanie Lu default: 2688*4df55fdeSJanie Lu break; 2689*4df55fdeSJanie Lu } 2690*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_set(handle, 2691*4df55fdeSJanie Lu (tcam_class_t)class, 0, 0, pid, 0); 2692*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2693*4df55fdeSJanie Lu goto fail; 2694*4df55fdeSJanie Lu 2695*4df55fdeSJanie Lu rs = nxge_set_iptun_usr_cls_reg(nxgep, class, iptunp); 2696*4df55fdeSJanie Lu 2697*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2698*4df55fdeSJanie Lu goto fail; 2699*4df55fdeSJanie Lu 2700*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 2701*4df55fdeSJanie Lu (tcam_class_t)class); 2702*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2703*4df55fdeSJanie Lu goto fail; 2704*4df55fdeSJanie Lu 2705*4df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].cls = class; 2706*4df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].pid = pid; 2707*4df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 2708*4df55fdeSJanie Lu iptunp->in_pkt_type; 2709*4df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].valid = 1; 2710*4df55fdeSJanie Lu *cls_idp = (uint8_t)class; 2711*4df55fdeSJanie Lu add_cls = 1; 2712*4df55fdeSJanie Lu break; 2713*4df55fdeSJanie Lu } else if (hw_p->tcam_l3_prog_cls[i].pid == pid) { 2714*4df55fdeSJanie Lu if (hw_p->tcam_l3_prog_cls[i].flow_pkt_type == 0) { 2715*4df55fdeSJanie Lu /* there is no flow key */ 2716*4df55fdeSJanie Lu /* todo program the existing usr class reg */ 2717*4df55fdeSJanie Lu 2718*4df55fdeSJanie Lu rs = nxge_set_iptun_usr_cls_reg(nxgep, class, 2719*4df55fdeSJanie Lu iptunp); 2720*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2721*4df55fdeSJanie Lu goto fail; 2722*4df55fdeSJanie Lu 2723*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 2724*4df55fdeSJanie Lu (tcam_class_t)class); 2725*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2726*4df55fdeSJanie Lu goto fail; 2727*4df55fdeSJanie Lu 2728*4df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 2729*4df55fdeSJanie Lu iptunp->in_pkt_type; 2730*4df55fdeSJanie Lu *cls_idp = (uint8_t)class; 2731*4df55fdeSJanie Lu add_cls = 1; 2732*4df55fdeSJanie Lu } else { 2733*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2734*4df55fdeSJanie Lu "nxge_add_iptun_class: L3 usr " 2735*4df55fdeSJanie Lu "programmable class with pid %d " 2736*4df55fdeSJanie Lu "already exists", pid)); 2737*4df55fdeSJanie Lu } 2738*4df55fdeSJanie Lu break; 2739*4df55fdeSJanie Lu } 2740*4df55fdeSJanie Lu } 2741*4df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2742*4df55fdeSJanie Lu 2743*4df55fdeSJanie Lu if (add_cls != 1) { 2744*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2745*4df55fdeSJanie Lu "nxge_add_iptun_class: Could not add IP tunneling class")); 2746*4df55fdeSJanie Lu } 2747*4df55fdeSJanie Lu return; 2748*4df55fdeSJanie Lu fail: 2749*4df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2750*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_iptun_class: FAILED")); 2751*4df55fdeSJanie Lu } 2752*4df55fdeSJanie Lu 2753*4df55fdeSJanie Lu static boolean_t 2754*4df55fdeSJanie Lu nxge_is_iptun_cls_present(p_nxge_t nxgep, uint8_t cls_id, int *idx) 2755*4df55fdeSJanie Lu { 2756*4df55fdeSJanie Lu int i; 2757*4df55fdeSJanie Lu p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 2758*4df55fdeSJanie Lu 2759*4df55fdeSJanie Lu MUTEX_ENTER(&hw_p->nxge_tcam_lock); 2760*4df55fdeSJanie Lu for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 2761*4df55fdeSJanie Lu if (hw_p->tcam_l3_prog_cls[i].valid && 2762*4df55fdeSJanie Lu hw_p->tcam_l3_prog_cls[i].flow_pkt_type != 0) { 2763*4df55fdeSJanie Lu if (hw_p->tcam_l3_prog_cls[i].cls == cls_id) 2764*4df55fdeSJanie Lu break; 2765*4df55fdeSJanie Lu } 2766*4df55fdeSJanie Lu } 2767*4df55fdeSJanie Lu MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2768*4df55fdeSJanie Lu 2769*4df55fdeSJanie Lu if (i == NXGE_L3_PROG_CLS) { 2770*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2771*4df55fdeSJanie Lu "nxge_is_iptun_cls_present: Invalid class %d", cls_id)); 2772*4df55fdeSJanie Lu return (B_FALSE); 2773*4df55fdeSJanie Lu } else { 2774*4df55fdeSJanie Lu *idx = i; 2775*4df55fdeSJanie Lu return (B_TRUE); 2776*4df55fdeSJanie Lu } 2777*4df55fdeSJanie Lu } 2778*4df55fdeSJanie Lu 2779*4df55fdeSJanie Lu void 2780*4df55fdeSJanie Lu nxge_cfg_iptun_hash(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id) 2781*4df55fdeSJanie Lu { 2782*4df55fdeSJanie Lu int idx; 2783*4df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 2784*4df55fdeSJanie Lu flow_key_cfg_t cfg; 2785*4df55fdeSJanie Lu 2786*4df55fdeSJanie Lu /* check to see that this is a valid class ID */ 2787*4df55fdeSJanie Lu if (!nxge_is_iptun_cls_present(nxgep, cls_id, &idx)) { 2788*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2789*4df55fdeSJanie Lu "nxge_cfg_iptun_hash: nxge_is_iptun_cls_present " 2790*4df55fdeSJanie Lu "failed for cls_id %d", cls_id)); 2791*4df55fdeSJanie Lu return; 2792*4df55fdeSJanie Lu } 2793*4df55fdeSJanie Lu 2794*4df55fdeSJanie Lu bzero((void *)&cfg, sizeof (flow_key_cfg_t)); 2795*4df55fdeSJanie Lu 2796*4df55fdeSJanie Lu /* 2797*4df55fdeSJanie Lu * This ensures that all 4 bytes of the XOR value are loaded to the 2798*4df55fdeSJanie Lu * hash key. 2799*4df55fdeSJanie Lu */ 2800*4df55fdeSJanie Lu cfg.use_dport = cfg.use_sport = cfg.ip_opts_exist = 1; 2801*4df55fdeSJanie Lu 2802*4df55fdeSJanie Lu cfg.l4_xor_sel = (iptunp->l4xor_sel & FL_KEY_USR_L4XOR_MSK); 2803*4df55fdeSJanie Lu cfg.use_l4_md = 1; 2804*4df55fdeSJanie Lu 2805*4df55fdeSJanie Lu if (iptunp->hash_flags & HASH_L3PROTO) 2806*4df55fdeSJanie Lu cfg.use_proto = 1; 2807*4df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_IPDA) 2808*4df55fdeSJanie Lu cfg.use_daddr = 1; 2809*4df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_IPSA) 2810*4df55fdeSJanie Lu cfg.use_saddr = 1; 2811*4df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_VLAN) 2812*4df55fdeSJanie Lu cfg.use_vlan = 1; 2813*4df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_L2DA) 2814*4df55fdeSJanie Lu cfg.use_l2da = 1; 2815*4df55fdeSJanie Lu else if (iptunp->hash_flags & HASH_IFPORT) 2816*4df55fdeSJanie Lu cfg.use_portnum = 1; 2817*4df55fdeSJanie Lu 2818*4df55fdeSJanie Lu (void) npi_fflp_cfg_ip_cls_flow_key_rfnl(handle, (tcam_class_t)cls_id, 2819*4df55fdeSJanie Lu &cfg); 2820*4df55fdeSJanie Lu } 2821*4df55fdeSJanie Lu 2822*4df55fdeSJanie Lu void 2823*4df55fdeSJanie Lu nxge_del_iptun_class(p_nxge_t nxgep, uint8_t cls_id) 2824*4df55fdeSJanie Lu { 2825*4df55fdeSJanie Lu int i; 2826*4df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 2827*4df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 2828*4df55fdeSJanie Lu 2829*4df55fdeSJanie Lu 2830*4df55fdeSJanie Lu /* check to see that this is a valid class ID */ 2831*4df55fdeSJanie Lu if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) { 2832*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2833*4df55fdeSJanie Lu "nxge_del_iptun_class: Invalid class ID 0x%x", cls_id)); 2834*4df55fdeSJanie Lu return; 2835*4df55fdeSJanie Lu } 2836*4df55fdeSJanie Lu 2837*4df55fdeSJanie Lu MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2838*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_disable(handle, (tcam_class_t)cls_id); 2839*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2840*4df55fdeSJanie Lu goto fail; 2841*4df55fdeSJanie Lu nxgep->nxge_hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 0; 2842*4df55fdeSJanie Lu if (nxgep->nxge_hw_p->tcam_l3_prog_cls[i].tcam_ref_cnt == 0) 2843*4df55fdeSJanie Lu nxgep->nxge_hw_p->tcam_l3_prog_cls[i].valid = 0; 2844*4df55fdeSJanie Lu 2845*4df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2846*4df55fdeSJanie Lu return; 2847*4df55fdeSJanie Lu fail: 2848*4df55fdeSJanie Lu MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2849*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_iptun_class: FAILED")); 2850*4df55fdeSJanie Lu } 2851*4df55fdeSJanie Lu 2852*4df55fdeSJanie Lu void 2853*4df55fdeSJanie Lu nxge_get_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id) 2854*4df55fdeSJanie Lu { 2855*4df55fdeSJanie Lu int i; 2856*4df55fdeSJanie Lu uint8_t pid; 2857*4df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 2858*4df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 2859*4df55fdeSJanie Lu flow_key_cfg_t cfg; 2860*4df55fdeSJanie Lu 2861*4df55fdeSJanie Lu 2862*4df55fdeSJanie Lu /* check to see that this is a valid class ID */ 2863*4df55fdeSJanie Lu if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) 2864*4df55fdeSJanie Lu return; 2865*4df55fdeSJanie Lu 2866*4df55fdeSJanie Lu bzero((void *)iptunp, sizeof (iptun_cfg_t)); 2867*4df55fdeSJanie Lu 2868*4df55fdeSJanie Lu pid = nxgep->nxge_hw_p->tcam_l3_prog_cls[i].pid; 2869*4df55fdeSJanie Lu 2870*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_usr_cls_get_iptun(handle, (tcam_class_t)cls_id, 2871*4df55fdeSJanie Lu &iptunp->l4b0_val, &iptunp->l4b0_mask, &iptunp->l4b23_val, 2872*4df55fdeSJanie Lu &iptunp->l4b23_sel); 2873*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2874*4df55fdeSJanie Lu goto fail; 2875*4df55fdeSJanie Lu 2876*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle, 2877*4df55fdeSJanie Lu (tcam_class_t)cls_id, &cfg); 2878*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2879*4df55fdeSJanie Lu goto fail; 2880*4df55fdeSJanie Lu 2881*4df55fdeSJanie Lu iptunp->l4xor_sel = cfg.l4_xor_sel; 2882*4df55fdeSJanie Lu if (cfg.use_proto) 2883*4df55fdeSJanie Lu iptunp->hash_flags |= HASH_L3PROTO; 2884*4df55fdeSJanie Lu else if (cfg.use_daddr) 2885*4df55fdeSJanie Lu iptunp->hash_flags |= HASH_IPDA; 2886*4df55fdeSJanie Lu else if (cfg.use_saddr) 2887*4df55fdeSJanie Lu iptunp->hash_flags |= HASH_IPSA; 2888*4df55fdeSJanie Lu else if (cfg.use_vlan) 2889*4df55fdeSJanie Lu iptunp->hash_flags |= HASH_VLAN; 2890*4df55fdeSJanie Lu else if (cfg.use_l2da) 2891*4df55fdeSJanie Lu iptunp->hash_flags |= HASH_L2DA; 2892*4df55fdeSJanie Lu else if (cfg.use_portnum) 2893*4df55fdeSJanie Lu iptunp->hash_flags |= HASH_IFPORT; 2894*4df55fdeSJanie Lu 2895*4df55fdeSJanie Lu switch (pid) { 2896*4df55fdeSJanie Lu case 4: 2897*4df55fdeSJanie Lu iptunp->in_pkt_type = IPTUN_PKT_IPV4; 2898*4df55fdeSJanie Lu break; 2899*4df55fdeSJanie Lu case 41: 2900*4df55fdeSJanie Lu iptunp->in_pkt_type = IPTUN_PKT_IPV6; 2901*4df55fdeSJanie Lu break; 2902*4df55fdeSJanie Lu case 47: 2903*4df55fdeSJanie Lu iptunp->in_pkt_type = IPTUN_PKT_GRE; 2904*4df55fdeSJanie Lu break; 2905*4df55fdeSJanie Lu case 17: 2906*4df55fdeSJanie Lu iptunp->in_pkt_type = IPTUN_PKT_GTP; 2907*4df55fdeSJanie Lu break; 2908*4df55fdeSJanie Lu default: 2909*4df55fdeSJanie Lu iptunp->in_pkt_type = 0; 2910*4df55fdeSJanie Lu break; 2911*4df55fdeSJanie Lu } 2912*4df55fdeSJanie Lu 2913*4df55fdeSJanie Lu return; 2914*4df55fdeSJanie Lu fail: 2915*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_iptun_class: FAILED")); 2916*4df55fdeSJanie Lu } 2917*4df55fdeSJanie Lu 2918*4df55fdeSJanie Lu void 2919*4df55fdeSJanie Lu nxge_set_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t sym) 2920*4df55fdeSJanie Lu { 2921*4df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 2922*4df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 2923*4df55fdeSJanie Lu boolean_t sym_en = (sym == 1) ? B_TRUE : B_FALSE; 2924*4df55fdeSJanie Lu 2925*4df55fdeSJanie Lu rs = npi_fflp_cfg_sym_ip_cls_flow_key(handle, (tcam_class_t)cls_id, 2926*4df55fdeSJanie Lu sym_en); 2927*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2928*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2929*4df55fdeSJanie Lu "nxge_set_ip_cls_sym: FAILED")); 2930*4df55fdeSJanie Lu } 2931*4df55fdeSJanie Lu 2932*4df55fdeSJanie Lu void 2933*4df55fdeSJanie Lu nxge_get_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t *sym) 2934*4df55fdeSJanie Lu { 2935*4df55fdeSJanie Lu npi_handle_t handle = nxgep->npi_reg_handle; 2936*4df55fdeSJanie Lu npi_status_t rs = NPI_SUCCESS; 2937*4df55fdeSJanie Lu flow_key_cfg_t cfg; 2938*4df55fdeSJanie Lu 2939*4df55fdeSJanie Lu rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle, 2940*4df55fdeSJanie Lu (tcam_class_t)cls_id, &cfg); 2941*4df55fdeSJanie Lu if (rs != NPI_SUCCESS) 2942*4df55fdeSJanie Lu goto fail; 2943*4df55fdeSJanie Lu 2944*4df55fdeSJanie Lu if (cfg.use_sym) 2945*4df55fdeSJanie Lu *sym = 1; 2946*4df55fdeSJanie Lu else 2947*4df55fdeSJanie Lu *sym = 0; 2948*4df55fdeSJanie Lu return; 2949*4df55fdeSJanie Lu fail: 2950*4df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_ip_cls_sym: FAILED")); 2951*4df55fdeSJanie Lu } 2952