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*678453a8Sspeer * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2344961713Sgirish * Use is subject to license terms. 2444961713Sgirish */ 2544961713Sgirish 2644961713Sgirish #pragma ident "%Z%%M% %I% %E% SMI" 2744961713Sgirish 2844961713Sgirish #include <npi_fflp.h> 2944961713Sgirish #include <npi_mac.h> 3044961713Sgirish #include <nxge_defs.h> 3144961713Sgirish #include <nxge_flow.h> 3244961713Sgirish #include <nxge_fflp.h> 3344961713Sgirish #include <nxge_impl.h> 3444961713Sgirish #include <nxge_fflp_hash.h> 3544961713Sgirish #include <nxge_common.h> 3644961713Sgirish 3744961713Sgirish 38a3c5bd6dSspeer /* 39a3c5bd6dSspeer * Function prototypes 40a3c5bd6dSspeer */ 4144961713Sgirish static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t); 4244961713Sgirish static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t); 4344961713Sgirish static nxge_status_t nxge_fflp_tcam_init(p_nxge_t); 4444961713Sgirish static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t); 4544961713Sgirish static nxge_status_t nxge_fflp_fcram_init(p_nxge_t); 4644961713Sgirish static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *); 47a3c5bd6dSspeer static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 48a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 49a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 5044961713Sgirish static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *, 51a3c5bd6dSspeer tcam_entry_t *); 52a3c5bd6dSspeer static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *, 53a3c5bd6dSspeer tcam_entry_t *); 54a3c5bd6dSspeer static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *, 55a3c5bd6dSspeer tcam_entry_t *); 5644961713Sgirish static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, intptr_t); 5744961713Sgirish static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, intptr_t); 5844961713Sgirish static tcam_location_t nxge_get_tcam_location(p_nxge_t, uint8_t); 5944961713Sgirish 60a3c5bd6dSspeer /* 61a3c5bd6dSspeer * functions used outside this file 62a3c5bd6dSspeer */ 6344961713Sgirish nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t); 6444961713Sgirish nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t); 6544961713Sgirish nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *); 6614ea4bb7Ssd static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t); 6744961713Sgirish nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *); 6844961713Sgirish nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *); 6944961713Sgirish nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *, 70a3c5bd6dSspeer uint32_t *, uint16_t *); 7144961713Sgirish 7244961713Sgirish nxge_status_t 7344961713Sgirish nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location) 7444961713Sgirish { 7544961713Sgirish tcam_entry_t tcam_rdptr; 7644961713Sgirish uint64_t asc_ram = 0; 7744961713Sgirish npi_handle_t handle; 7844961713Sgirish npi_status_t status; 7944961713Sgirish 8044961713Sgirish handle = nxgep->npi_reg_handle; 8144961713Sgirish 8244961713Sgirish bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry)); 8344961713Sgirish status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location, 84a3c5bd6dSspeer (struct tcam_entry *)&tcam_rdptr); 8544961713Sgirish if (status & NPI_FAILURE) { 8644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 87a3c5bd6dSspeer " nxge_tcam_dump_entry:" 88a3c5bd6dSspeer " tcam read failed at location %d ", location)); 8944961713Sgirish return (NXGE_ERROR); 9044961713Sgirish } 9144961713Sgirish status = npi_fflp_tcam_asc_ram_entry_read(handle, 92a3c5bd6dSspeer (tcam_location_t)location, &asc_ram); 9344961713Sgirish 9444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n" 95a3c5bd6dSspeer " key: %llx %llx %llx %llx \n" 96a3c5bd6dSspeer " mask: %llx %llx %llx %llx \n" 97a3c5bd6dSspeer " ASC RAM %llx \n", location, 98a3c5bd6dSspeer tcam_rdptr.key0, tcam_rdptr.key1, 99a3c5bd6dSspeer tcam_rdptr.key2, tcam_rdptr.key3, 100a3c5bd6dSspeer tcam_rdptr.mask0, tcam_rdptr.mask1, 101a3c5bd6dSspeer tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram)); 10244961713Sgirish return (NXGE_OK); 10344961713Sgirish } 10444961713Sgirish 10544961713Sgirish void 10644961713Sgirish nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp) 10744961713Sgirish { 10844961713Sgirish uint32_t tcam_loc; 10944961713Sgirish int *lptr; 11044961713Sgirish int location; 11144961713Sgirish 11244961713Sgirish uint32_t start_location = 0; 11344961713Sgirish uint32_t stop_location = nxgep->classifier.tcam_size; 11444961713Sgirish lptr = (int *)mp->b_rptr; 11544961713Sgirish location = *lptr; 11644961713Sgirish 11744961713Sgirish if ((location >= nxgep->classifier.tcam_size) || (location < -1)) { 11844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 119a3c5bd6dSspeer "nxge_tcam_dump: Invalid location %d \n", location)); 12044961713Sgirish return; 12144961713Sgirish } 12244961713Sgirish if (location == -1) { 12344961713Sgirish start_location = 0; 12444961713Sgirish stop_location = nxgep->classifier.tcam_size; 12544961713Sgirish } else { 12644961713Sgirish start_location = location; 127a3c5bd6dSspeer stop_location = location + 1; 12844961713Sgirish } 12944961713Sgirish for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++) 13044961713Sgirish (void) nxge_tcam_dump_entry(nxgep, tcam_loc); 13144961713Sgirish } 13244961713Sgirish 13344961713Sgirish /* 13444961713Sgirish * nxge_fflp_vlan_table_invalidate_all 13544961713Sgirish * invalidates the vlan RDC table entries. 13644961713Sgirish * INPUT 13744961713Sgirish * nxge soft state data structure 13844961713Sgirish * Return 13944961713Sgirish * NXGE_OK 14044961713Sgirish * NXGE_ERROR 14144961713Sgirish * 14244961713Sgirish */ 143a3c5bd6dSspeer 14444961713Sgirish static nxge_status_t 14544961713Sgirish nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep) 14644961713Sgirish { 14744961713Sgirish vlan_id_t vlan_id; 14844961713Sgirish npi_handle_t handle; 14944961713Sgirish npi_status_t rs = NPI_SUCCESS; 15044961713Sgirish vlan_id_t start = 0, stop = NXGE_MAX_VLANS; 15144961713Sgirish 15244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all ")); 15344961713Sgirish handle = nxgep->npi_reg_handle; 15444961713Sgirish for (vlan_id = start; vlan_id < stop; vlan_id++) { 15544961713Sgirish rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id); 15644961713Sgirish if (rs != NPI_SUCCESS) { 15744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 158a3c5bd6dSspeer "VLAN Table invalidate failed for vlan id %d ", 159a3c5bd6dSspeer vlan_id)); 16044961713Sgirish return (NXGE_ERROR | rs); 16144961713Sgirish } 16244961713Sgirish } 16344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all ")); 16444961713Sgirish return (NXGE_OK); 16544961713Sgirish } 16644961713Sgirish 16744961713Sgirish /* 16844961713Sgirish * The following functions are used by other modules to init 16944961713Sgirish * the fflp module. 17044961713Sgirish * these functions are the basic API used to init 17144961713Sgirish * the fflp modules (tcam, fcram etc ......) 17244961713Sgirish * 17344961713Sgirish * The TCAM search future would be disabled by default. 17444961713Sgirish */ 17544961713Sgirish 17644961713Sgirish static nxge_status_t 17744961713Sgirish nxge_fflp_tcam_init(p_nxge_t nxgep) 17844961713Sgirish { 17944961713Sgirish uint8_t access_ratio; 18044961713Sgirish tcam_class_t class; 18144961713Sgirish npi_status_t rs = NPI_SUCCESS; 18244961713Sgirish npi_handle_t handle; 18344961713Sgirish 18444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init")); 18544961713Sgirish handle = nxgep->npi_reg_handle; 18644961713Sgirish 18744961713Sgirish rs = npi_fflp_cfg_tcam_disable(handle); 18844961713Sgirish if (rs != NPI_SUCCESS) { 18944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n")); 19044961713Sgirish return (NXGE_ERROR | rs); 19144961713Sgirish } 19244961713Sgirish 19344961713Sgirish access_ratio = nxgep->param_arr[param_tcam_access_ratio].value; 19444961713Sgirish rs = npi_fflp_cfg_tcam_access(handle, access_ratio); 19544961713Sgirish if (rs != NPI_SUCCESS) { 19644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 197a3c5bd6dSspeer "failed TCAM Access cfg\n")); 19844961713Sgirish return (NXGE_ERROR | rs); 19944961713Sgirish } 20044961713Sgirish 201a3c5bd6dSspeer /* disable configurable classes */ 202a3c5bd6dSspeer /* disable the configurable ethernet classes; */ 20344961713Sgirish for (class = TCAM_CLASS_ETYPE_1; 20444961713Sgirish class <= TCAM_CLASS_ETYPE_2; class++) { 20544961713Sgirish rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class); 20644961713Sgirish if (rs != NPI_SUCCESS) { 20744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 208a3c5bd6dSspeer "TCAM USR Ether Class config failed.")); 20944961713Sgirish return (NXGE_ERROR | rs); 21044961713Sgirish } 21144961713Sgirish } 21244961713Sgirish 213a3c5bd6dSspeer /* disable the configurable ip classes; */ 21444961713Sgirish for (class = TCAM_CLASS_IP_USER_4; 21544961713Sgirish class <= TCAM_CLASS_IP_USER_7; class++) { 21644961713Sgirish rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 21744961713Sgirish if (rs != NPI_SUCCESS) { 21844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 219a3c5bd6dSspeer "TCAM USR IP Class cnfg failed.")); 22044961713Sgirish return (NXGE_ERROR | rs); 22144961713Sgirish } 22244961713Sgirish } 22344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init")); 22444961713Sgirish return (NXGE_OK); 22544961713Sgirish } 22644961713Sgirish 22744961713Sgirish /* 22844961713Sgirish * nxge_fflp_tcam_invalidate_all 22944961713Sgirish * invalidates all the tcam entries. 23044961713Sgirish * INPUT 23144961713Sgirish * nxge soft state data structure 23244961713Sgirish * Return 23344961713Sgirish * NXGE_OK 23444961713Sgirish * NXGE_ERROR 23544961713Sgirish * 23644961713Sgirish */ 237a3c5bd6dSspeer 238a3c5bd6dSspeer 23944961713Sgirish static nxge_status_t 24044961713Sgirish nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep) 24144961713Sgirish { 24244961713Sgirish uint16_t location; 24344961713Sgirish npi_status_t rs = NPI_SUCCESS; 24444961713Sgirish npi_handle_t handle; 24544961713Sgirish uint16_t start = 0, stop = nxgep->classifier.tcam_size; 246a3c5bd6dSspeer p_nxge_hw_list_t hw_p; 24744961713Sgirish 24844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 249a3c5bd6dSspeer "==> nxge_fflp_tcam_invalidate_all")); 25044961713Sgirish handle = nxgep->npi_reg_handle; 25144961713Sgirish if ((hw_p = nxgep->nxge_hw_p) == NULL) { 25244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 25344961713Sgirish " nxge_fflp_tcam_invalidate_all:" 254a3c5bd6dSspeer " common hardware not set", nxgep->niu_type)); 25544961713Sgirish return (NXGE_ERROR); 25644961713Sgirish } 25744961713Sgirish MUTEX_ENTER(&hw_p->nxge_tcam_lock); 25844961713Sgirish for (location = start; location < stop; location++) { 25944961713Sgirish rs = npi_fflp_tcam_entry_invalidate(handle, location); 26044961713Sgirish if (rs != NPI_SUCCESS) { 26144961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 26244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 263a3c5bd6dSspeer "TCAM invalidate failed at loc %d ", location)); 26444961713Sgirish return (NXGE_ERROR | rs); 26544961713Sgirish } 26644961713Sgirish } 26744961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 26844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 269a3c5bd6dSspeer "<== nxge_fflp_tcam_invalidate_all")); 27044961713Sgirish return (NXGE_OK); 27144961713Sgirish } 27244961713Sgirish 27344961713Sgirish /* 27444961713Sgirish * nxge_fflp_fcram_entry_invalidate_all 27544961713Sgirish * invalidates all the FCRAM entries. 27644961713Sgirish * INPUT 27744961713Sgirish * nxge soft state data structure 27844961713Sgirish * Return 27944961713Sgirish * NXGE_OK 28044961713Sgirish * NXGE_ERROR 28144961713Sgirish * 28244961713Sgirish */ 283a3c5bd6dSspeer 28444961713Sgirish static nxge_status_t 28544961713Sgirish nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep) 28644961713Sgirish { 287a3c5bd6dSspeer npi_handle_t handle; 288a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 289a3c5bd6dSspeer part_id_t pid = 0; 290a3c5bd6dSspeer uint8_t base_mask, base_reloc; 291a3c5bd6dSspeer fcram_entry_t fc; 292a3c5bd6dSspeer uint32_t location; 293a3c5bd6dSspeer uint32_t increment, last_location; 29444961713Sgirish 295a3c5bd6dSspeer /* 296a3c5bd6dSspeer * (1) configure and enable partition 0 with no relocation 297a3c5bd6dSspeer * (2) Assume the FCRAM is used as IPv4 exact match entry cells 298a3c5bd6dSspeer * (3) Invalidate these cells by clearing the valid bit in 299a3c5bd6dSspeer * the subareas 0 and 4 300a3c5bd6dSspeer * (4) disable the partition 301a3c5bd6dSspeer * 302a3c5bd6dSspeer */ 30344961713Sgirish 30444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all")); 30544961713Sgirish 30644961713Sgirish base_mask = base_reloc = 0x0; 30744961713Sgirish handle = nxgep->npi_reg_handle; 308a3c5bd6dSspeer rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc); 30944961713Sgirish 31044961713Sgirish if (rs != NPI_SUCCESS) { 311a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n")); 31244961713Sgirish return (NXGE_ERROR | rs); 31344961713Sgirish } 314a3c5bd6dSspeer rs = npi_fflp_cfg_fcram_partition_disable(handle, pid); 31544961713Sgirish 31644961713Sgirish if (rs != NPI_SUCCESS) { 31744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 318a3c5bd6dSspeer "failed partition enable\n")); 31944961713Sgirish return (NXGE_ERROR | rs); 32044961713Sgirish } 321a3c5bd6dSspeer fc.dreg[0].value = 0; 322a3c5bd6dSspeer fc.hash_hdr_valid = 0; 323a3c5bd6dSspeer fc.hash_hdr_ext = 1; /* specify as IPV4 exact match entry */ 324a3c5bd6dSspeer increment = sizeof (hash_ipv4_t); 325a3c5bd6dSspeer last_location = FCRAM_SIZE * 0x40; 32644961713Sgirish 327a3c5bd6dSspeer for (location = 0; location < last_location; location += increment) { 32844961713Sgirish rs = npi_fflp_fcram_subarea_write(handle, pid, 329a3c5bd6dSspeer location, 330a3c5bd6dSspeer fc.value[0]); 33144961713Sgirish if (rs != NPI_SUCCESS) { 33244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 333a3c5bd6dSspeer "failed write" 334a3c5bd6dSspeer "at location %x ", 335a3c5bd6dSspeer location)); 33644961713Sgirish return (NXGE_ERROR | rs); 33744961713Sgirish } 33844961713Sgirish } 33944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all")); 340a3c5bd6dSspeer return (NXGE_OK); 34144961713Sgirish } 34244961713Sgirish 34344961713Sgirish static nxge_status_t 34444961713Sgirish nxge_fflp_fcram_init(p_nxge_t nxgep) 34544961713Sgirish { 34644961713Sgirish fflp_fcram_output_drive_t strength; 34744961713Sgirish fflp_fcram_qs_t qs; 34844961713Sgirish npi_status_t rs = NPI_SUCCESS; 34944961713Sgirish uint8_t access_ratio; 350a3c5bd6dSspeer int partition; 35144961713Sgirish npi_handle_t handle; 352a3c5bd6dSspeer uint32_t min_time, max_time, sys_time; 35344961713Sgirish 35444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init")); 35544961713Sgirish 356a3c5bd6dSspeer /* 357a3c5bd6dSspeer * Recommended values are needed. 358a3c5bd6dSspeer */ 35944961713Sgirish min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME; 36044961713Sgirish max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME; 36144961713Sgirish sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME; 362a3c5bd6dSspeer 36344961713Sgirish handle = nxgep->npi_reg_handle; 36444961713Sgirish strength = FCRAM_OUTDR_NORMAL; 36544961713Sgirish qs = FCRAM_QS_MODE_QS; 36644961713Sgirish rs = npi_fflp_cfg_fcram_reset(handle, strength, qs); 36744961713Sgirish if (rs != NPI_SUCCESS) { 36844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. ")); 36944961713Sgirish return (NXGE_ERROR | rs); 37044961713Sgirish } 37144961713Sgirish 372a3c5bd6dSspeer access_ratio = nxgep->param_arr[param_fcram_access_ratio].value; 373a3c5bd6dSspeer rs = npi_fflp_cfg_fcram_access(handle, access_ratio); 374a3c5bd6dSspeer if (rs != NPI_SUCCESS) { 37544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio" 376a3c5bd6dSspeer "configuration \n")); 37744961713Sgirish return (NXGE_ERROR | rs); 37844961713Sgirish } 37944961713Sgirish rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time, 380a3c5bd6dSspeer max_time, sys_time); 38144961713Sgirish if (rs != NPI_SUCCESS) { 38244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 383a3c5bd6dSspeer "failed FCRAM refresh cfg")); 38444961713Sgirish return (NXGE_ERROR); 38544961713Sgirish } 38644961713Sgirish 38744961713Sgirish /* disable all the partitions until explicitly enabled */ 38844961713Sgirish for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) { 389a3c5bd6dSspeer rs = npi_fflp_cfg_fcram_partition_disable(handle, partition); 39044961713Sgirish if (rs != NPI_SUCCESS) { 39144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 392a3c5bd6dSspeer "failed FCRAM partition" 393a3c5bd6dSspeer " enable for partition %d ", partition)); 39444961713Sgirish return (NXGE_ERROR | rs); 39544961713Sgirish } 39644961713Sgirish } 39744961713Sgirish 39844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init")); 399a3c5bd6dSspeer return (NXGE_OK); 40044961713Sgirish } 40144961713Sgirish 40244961713Sgirish nxge_status_t 40344961713Sgirish nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac) 40444961713Sgirish { 40544961713Sgirish npi_status_t rs = NPI_SUCCESS; 40644961713Sgirish hostinfo_t mac_rdc; 40744961713Sgirish npi_handle_t handle; 408a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 40944961713Sgirish 410a3c5bd6dSspeer p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 41144961713Sgirish if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) { 412a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 413a3c5bd6dSspeer " nxge_logical_mac_assign_rdc_table" 414a3c5bd6dSspeer " unconfigured alt MAC addr %d ", alt_mac)); 41544961713Sgirish return (NXGE_ERROR); 41644961713Sgirish } 41744961713Sgirish handle = nxgep->npi_reg_handle; 41844961713Sgirish mac_rdc.value = 0; 41944961713Sgirish mac_rdc.bits.w0.rdc_tbl_num = 420a3c5bd6dSspeer p_class_cfgp->mac_host_info[alt_mac].rdctbl; 42144961713Sgirish mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr; 42244961713Sgirish 42344961713Sgirish rs = npi_mac_hostinfo_entry(handle, OP_SET, 424a3c5bd6dSspeer nxgep->function_num, alt_mac, &mac_rdc); 42544961713Sgirish 42644961713Sgirish if (rs != NPI_SUCCESS) { 42744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 428a3c5bd6dSspeer "failed Assign RDC table")); 42944961713Sgirish return (NXGE_ERROR | rs); 43044961713Sgirish } 43144961713Sgirish return (NXGE_OK); 43244961713Sgirish } 43344961713Sgirish 43444961713Sgirish nxge_status_t 43544961713Sgirish nxge_main_mac_assign_rdc_table(p_nxge_t nxgep) 43644961713Sgirish { 43744961713Sgirish npi_status_t rs = NPI_SUCCESS; 43844961713Sgirish hostinfo_t mac_rdc; 43944961713Sgirish npi_handle_t handle; 44044961713Sgirish 44144961713Sgirish handle = nxgep->npi_reg_handle; 44244961713Sgirish mac_rdc.value = 0; 44344961713Sgirish mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp; 44444961713Sgirish mac_rdc.bits.w0.mac_pref = 1; 44544961713Sgirish switch (nxgep->function_num) { 446a3c5bd6dSspeer case 0: 447a3c5bd6dSspeer case 1: 448a3c5bd6dSspeer rs = npi_mac_hostinfo_entry(handle, OP_SET, 449a3c5bd6dSspeer nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, 450a3c5bd6dSspeer &mac_rdc); 451a3c5bd6dSspeer break; 452a3c5bd6dSspeer case 2: 453a3c5bd6dSspeer case 3: 454a3c5bd6dSspeer rs = npi_mac_hostinfo_entry(handle, OP_SET, 455a3c5bd6dSspeer nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, 456a3c5bd6dSspeer &mac_rdc); 457a3c5bd6dSspeer break; 458a3c5bd6dSspeer default: 459a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 46058324dfcSspeer "failed Assign RDC table (invalid function #)")); 461a3c5bd6dSspeer return (NXGE_ERROR); 46244961713Sgirish } 46344961713Sgirish 46444961713Sgirish if (rs != NPI_SUCCESS) { 46544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 466a3c5bd6dSspeer "failed Assign RDC table")); 46744961713Sgirish return (NXGE_ERROR | rs); 46844961713Sgirish } 46944961713Sgirish return (NXGE_OK); 47044961713Sgirish } 47144961713Sgirish 47258324dfcSspeer /* 47358324dfcSspeer * Initialize hostinfo registers for alternate MAC addresses and 47458324dfcSspeer * multicast MAC address. 47558324dfcSspeer */ 47644961713Sgirish nxge_status_t 47758324dfcSspeer nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep) 47844961713Sgirish { 47944961713Sgirish npi_status_t rs = NPI_SUCCESS; 48044961713Sgirish hostinfo_t mac_rdc; 48144961713Sgirish npi_handle_t handle; 48258324dfcSspeer int i; 48344961713Sgirish 48444961713Sgirish handle = nxgep->npi_reg_handle; 48544961713Sgirish mac_rdc.value = 0; 48644961713Sgirish mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp; 48744961713Sgirish mac_rdc.bits.w0.mac_pref = 1; 48844961713Sgirish switch (nxgep->function_num) { 489a3c5bd6dSspeer case 0: 490a3c5bd6dSspeer case 1: 49158324dfcSspeer /* 49258324dfcSspeer * Tests indicate that it is OK not to re-initialize the 49358324dfcSspeer * hostinfo registers for the XMAC's alternate MAC 49458324dfcSspeer * addresses. But that is necessary for BMAC (case 2 49558324dfcSspeer * and case 3 below) 49658324dfcSspeer */ 497a3c5bd6dSspeer rs = npi_mac_hostinfo_entry(handle, OP_SET, 498a3c5bd6dSspeer nxgep->function_num, 499a3c5bd6dSspeer XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 500a3c5bd6dSspeer break; 501a3c5bd6dSspeer case 2: 502a3c5bd6dSspeer case 3: 50358324dfcSspeer for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++) 50458324dfcSspeer rs |= npi_mac_hostinfo_entry(handle, OP_SET, 50558324dfcSspeer nxgep->function_num, i, &mac_rdc); 50658324dfcSspeer 50758324dfcSspeer rs |= npi_mac_hostinfo_entry(handle, OP_SET, 508a3c5bd6dSspeer nxgep->function_num, 509a3c5bd6dSspeer BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 510a3c5bd6dSspeer break; 511a3c5bd6dSspeer default: 512a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 513f6485eecSyc "failed Assign RDC table (invalid function #)")); 514a3c5bd6dSspeer return (NXGE_ERROR); 51544961713Sgirish } 51644961713Sgirish 51744961713Sgirish if (rs != NPI_SUCCESS) { 51844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 519a3c5bd6dSspeer "failed Assign RDC table")); 52044961713Sgirish return (NXGE_ERROR | rs); 52144961713Sgirish } 52244961713Sgirish return (NXGE_OK); 52344961713Sgirish } 52444961713Sgirish 52544961713Sgirish nxge_status_t 52644961713Sgirish nxge_fflp_init_hostinfo(p_nxge_t nxgep) 52744961713Sgirish { 52844961713Sgirish nxge_status_t status = NXGE_OK; 529a3c5bd6dSspeer 53058324dfcSspeer status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 53158324dfcSspeer status |= nxge_main_mac_assign_rdc_table(nxgep); 53244961713Sgirish return (status); 53344961713Sgirish } 53444961713Sgirish 53544961713Sgirish nxge_status_t 53644961713Sgirish nxge_fflp_hw_reset(p_nxge_t nxgep) 53744961713Sgirish { 53844961713Sgirish npi_handle_t handle; 53944961713Sgirish npi_status_t rs = NPI_SUCCESS; 54044961713Sgirish nxge_status_t status = NXGE_OK; 54144961713Sgirish 54244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset")); 54344961713Sgirish 5442e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 54544961713Sgirish status = nxge_fflp_fcram_init(nxgep); 546a3c5bd6dSspeer if (status != NXGE_OK) { 54744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 548a3c5bd6dSspeer " failed FCRAM init. ")); 54944961713Sgirish return (status); 55044961713Sgirish } 55144961713Sgirish } 55244961713Sgirish 55344961713Sgirish status = nxge_fflp_tcam_init(nxgep); 55444961713Sgirish if (status != NXGE_OK) { 555a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 556a3c5bd6dSspeer "failed TCAM init.")); 557a3c5bd6dSspeer return (status); 55844961713Sgirish } 55944961713Sgirish 56044961713Sgirish handle = nxgep->npi_reg_handle; 56144961713Sgirish rs = npi_fflp_cfg_llcsnap_enable(handle); 56244961713Sgirish if (rs != NPI_SUCCESS) { 563a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 564a3c5bd6dSspeer "failed LLCSNAP enable. ")); 565a3c5bd6dSspeer return (NXGE_ERROR | rs); 56644961713Sgirish } 56744961713Sgirish 56844961713Sgirish rs = npi_fflp_cfg_cam_errorcheck_disable(handle); 56944961713Sgirish if (rs != NPI_SUCCESS) { 57044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 571a3c5bd6dSspeer "failed CAM Error Check enable. ")); 57244961713Sgirish return (NXGE_ERROR | rs); 57344961713Sgirish } 57444961713Sgirish 575a3c5bd6dSspeer /* init the hash generators */ 57644961713Sgirish rs = npi_fflp_cfg_hash_h1poly(handle, 0); 57744961713Sgirish if (rs != NPI_SUCCESS) { 578a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 579a3c5bd6dSspeer "failed H1 Poly Init. ")); 580a3c5bd6dSspeer return (NXGE_ERROR | rs); 58144961713Sgirish } 58244961713Sgirish 58344961713Sgirish rs = npi_fflp_cfg_hash_h2poly(handle, 0); 58444961713Sgirish if (rs != NPI_SUCCESS) { 585a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 586a3c5bd6dSspeer "failed H2 Poly Init. ")); 587a3c5bd6dSspeer return (NXGE_ERROR | rs); 58844961713Sgirish } 58944961713Sgirish 590a3c5bd6dSspeer /* invalidate TCAM entries */ 59144961713Sgirish status = nxge_fflp_tcam_invalidate_all(nxgep); 59244961713Sgirish if (status != NXGE_OK) { 59344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 594a3c5bd6dSspeer "failed TCAM Entry Invalidate. ")); 59544961713Sgirish return (status); 59644961713Sgirish } 59744961713Sgirish 598a3c5bd6dSspeer /* invalidate FCRAM entries */ 5992e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 60044961713Sgirish status = nxge_fflp_fcram_invalidate_all(nxgep); 60144961713Sgirish if (status != NXGE_OK) { 60244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 603a3c5bd6dSspeer "failed FCRAM Entry Invalidate.")); 60444961713Sgirish return (status); 60544961713Sgirish } 60644961713Sgirish } 60744961713Sgirish 608a3c5bd6dSspeer /* invalidate VLAN RDC tables */ 60944961713Sgirish status = nxge_fflp_vlan_tbl_clear_all(nxgep); 61044961713Sgirish if (status != NXGE_OK) { 61144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 612a3c5bd6dSspeer "failed VLAN Table Invalidate. ")); 61344961713Sgirish return (status); 61444961713Sgirish } 61544961713Sgirish nxgep->classifier.state |= NXGE_FFLP_HW_RESET; 61644961713Sgirish 61744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset")); 61844961713Sgirish return (NXGE_OK); 61944961713Sgirish } 62044961713Sgirish 62144961713Sgirish nxge_status_t 62244961713Sgirish nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class, 623a3c5bd6dSspeer uint32_t class_config) 62444961713Sgirish { 62544961713Sgirish flow_key_cfg_t fcfg; 62644961713Sgirish npi_handle_t handle; 62744961713Sgirish npi_status_t rs = NPI_SUCCESS; 62844961713Sgirish 62944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key")); 63044961713Sgirish handle = nxgep->npi_reg_handle; 63144961713Sgirish bzero(&fcfg, sizeof (flow_key_cfg_t)); 63244961713Sgirish 633a3c5bd6dSspeer if (class_config & NXGE_CLASS_FLOW_USE_PROTO) 63444961713Sgirish fcfg.use_proto = 1; 63544961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT) 63644961713Sgirish fcfg.use_dport = 1; 63744961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT) 63844961713Sgirish fcfg.use_sport = 1; 63944961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_IPDST) 64044961713Sgirish fcfg.use_daddr = 1; 64144961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_IPSRC) 64244961713Sgirish fcfg.use_saddr = 1; 64344961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_VLAN) 64444961713Sgirish fcfg.use_vlan = 1; 64544961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_L2DA) 64644961713Sgirish fcfg.use_l2da = 1; 64744961713Sgirish if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM) 64844961713Sgirish fcfg.use_portnum = 1; 64944961713Sgirish fcfg.ip_opts_exist = 0; 65044961713Sgirish 65144961713Sgirish rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg); 65244961713Sgirish if (rs & NPI_FFLP_ERROR) { 65344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 654a3c5bd6dSspeer " opt %x for class %d failed ", 655a3c5bd6dSspeer class_config, l3_class)); 65644961713Sgirish return (NXGE_ERROR | rs); 65744961713Sgirish } 65844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key")); 65944961713Sgirish return (NXGE_OK); 66044961713Sgirish } 66144961713Sgirish 66244961713Sgirish nxge_status_t 66344961713Sgirish nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class, 664a3c5bd6dSspeer uint32_t *class_config) 66544961713Sgirish { 66644961713Sgirish flow_key_cfg_t fcfg; 66744961713Sgirish npi_handle_t handle; 66844961713Sgirish npi_status_t rs = NPI_SUCCESS; 66944961713Sgirish uint32_t ccfg = 0; 670a3c5bd6dSspeer 67144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get")); 67244961713Sgirish handle = nxgep->npi_reg_handle; 67344961713Sgirish bzero(&fcfg, sizeof (flow_key_cfg_t)); 67444961713Sgirish 67544961713Sgirish rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg); 67644961713Sgirish if (rs & NPI_FFLP_ERROR) { 67744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 678a3c5bd6dSspeer " opt %x for class %d failed ", 679a3c5bd6dSspeer class_config, l3_class)); 68044961713Sgirish return (NXGE_ERROR | rs); 68144961713Sgirish } 68244961713Sgirish 68344961713Sgirish if (fcfg.use_proto) 68444961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_PROTO; 68544961713Sgirish if (fcfg.use_dport) 68644961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT; 68744961713Sgirish if (fcfg.use_sport) 68844961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT; 68944961713Sgirish if (fcfg.use_daddr) 69044961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_IPDST; 69144961713Sgirish if (fcfg.use_saddr) 69244961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_IPSRC; 69344961713Sgirish if (fcfg.use_vlan) 69444961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_VLAN; 69544961713Sgirish if (fcfg.use_l2da) 69644961713Sgirish ccfg |= NXGE_CLASS_FLOW_USE_L2DA; 69744961713Sgirish if (fcfg.use_portnum) 698a3c5bd6dSspeer ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM; 69944961713Sgirish 70044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 701a3c5bd6dSspeer " nxge_cfg_ip_cls_flow_key_get %x", ccfg)); 70244961713Sgirish *class_config = ccfg; 70344961713Sgirish 70444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 705a3c5bd6dSspeer " <== nxge_cfg_ip_cls_flow_key_get")); 70644961713Sgirish return (NXGE_OK); 70744961713Sgirish } 70844961713Sgirish 70944961713Sgirish static nxge_status_t 71044961713Sgirish nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class, 711a3c5bd6dSspeer uint32_t *class_config) 71244961713Sgirish { 71344961713Sgirish npi_status_t rs = NPI_SUCCESS; 71444961713Sgirish tcam_key_cfg_t cfg; 71544961713Sgirish npi_handle_t handle; 71644961713Sgirish uint32_t ccfg = 0; 71744961713Sgirish 71844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 71944961713Sgirish 72044961713Sgirish bzero(&cfg, sizeof (tcam_key_cfg_t)); 72144961713Sgirish handle = nxgep->npi_reg_handle; 72244961713Sgirish 72344961713Sgirish rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg); 72444961713Sgirish if (rs & NPI_FFLP_ERROR) { 72544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 726a3c5bd6dSspeer " opt %x for class %d failed ", 727a3c5bd6dSspeer class_config, class)); 72844961713Sgirish return (NXGE_ERROR | rs); 72944961713Sgirish } 73044961713Sgirish if (cfg.discard) 731a3c5bd6dSspeer ccfg |= NXGE_CLASS_DISCARD; 73244961713Sgirish if (cfg.lookup_enable) 73344961713Sgirish ccfg |= NXGE_CLASS_TCAM_LOOKUP; 73444961713Sgirish if (cfg.use_ip_daddr) 735a3c5bd6dSspeer ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR; 73644961713Sgirish *class_config = ccfg; 73744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 738a3c5bd6dSspeer " ==> nxge_cfg_tcam_ip_class %x", ccfg)); 73944961713Sgirish return (NXGE_OK); 74044961713Sgirish } 74144961713Sgirish 74244961713Sgirish static nxge_status_t 74344961713Sgirish nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class, 744a3c5bd6dSspeer uint32_t class_config) 74544961713Sgirish { 74644961713Sgirish npi_status_t rs = NPI_SUCCESS; 74744961713Sgirish tcam_key_cfg_t cfg; 74844961713Sgirish npi_handle_t handle; 749a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 75044961713Sgirish 75144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 752a3c5bd6dSspeer 75344961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 75444961713Sgirish p_class_cfgp->class_cfg[class] = class_config; 75544961713Sgirish 75644961713Sgirish bzero(&cfg, sizeof (tcam_key_cfg_t)); 75744961713Sgirish handle = nxgep->npi_reg_handle; 75844961713Sgirish cfg.discard = 0; 75944961713Sgirish cfg.lookup_enable = 0; 76044961713Sgirish cfg.use_ip_daddr = 0; 76144961713Sgirish if (class_config & NXGE_CLASS_DISCARD) 76244961713Sgirish cfg.discard = 1; 76344961713Sgirish if (class_config & NXGE_CLASS_TCAM_LOOKUP) 76444961713Sgirish cfg.lookup_enable = 1; 765a3c5bd6dSspeer if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR) 76644961713Sgirish cfg.use_ip_daddr = 1; 76744961713Sgirish 76844961713Sgirish rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg); 76944961713Sgirish if (rs & NPI_FFLP_ERROR) { 77044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 771a3c5bd6dSspeer " opt %x for class %d failed ", 772a3c5bd6dSspeer class_config, class)); 77344961713Sgirish return (NXGE_ERROR | rs); 77444961713Sgirish } 77544961713Sgirish return (NXGE_OK); 77644961713Sgirish } 77744961713Sgirish 77844961713Sgirish nxge_status_t 77944961713Sgirish nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1) 78044961713Sgirish { 78144961713Sgirish npi_status_t rs = NPI_SUCCESS; 78244961713Sgirish npi_handle_t handle; 783a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 78444961713Sgirish 78544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1")); 78644961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 78744961713Sgirish p_class_cfgp->init_h1 = h1; 78844961713Sgirish handle = nxgep->npi_reg_handle; 78944961713Sgirish rs = npi_fflp_cfg_hash_h1poly(handle, h1); 79044961713Sgirish if (rs & NPI_FFLP_ERROR) { 791a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 792a3c5bd6dSspeer " nxge_fflp_init_h1 %x failed ", h1)); 79344961713Sgirish return (NXGE_ERROR | rs); 79444961713Sgirish } 79544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1")); 79644961713Sgirish return (NXGE_OK); 79744961713Sgirish } 79844961713Sgirish 79944961713Sgirish nxge_status_t 80044961713Sgirish nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2) 80144961713Sgirish { 80244961713Sgirish npi_status_t rs = NPI_SUCCESS; 80344961713Sgirish npi_handle_t handle; 804a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 80544961713Sgirish 80644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2")); 80744961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 80844961713Sgirish p_class_cfgp->init_h2 = h2; 80944961713Sgirish 81044961713Sgirish handle = nxgep->npi_reg_handle; 81144961713Sgirish rs = npi_fflp_cfg_hash_h2poly(handle, h2); 81244961713Sgirish if (rs & NPI_FFLP_ERROR) { 813a3c5bd6dSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 814a3c5bd6dSspeer " nxge_fflp_init_h2 %x failed ", h2)); 81544961713Sgirish return (NXGE_ERROR | rs); 81644961713Sgirish } 81744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2")); 81844961713Sgirish return (NXGE_OK); 81944961713Sgirish } 82044961713Sgirish 82144961713Sgirish nxge_status_t 82244961713Sgirish nxge_classify_init_sw(p_nxge_t nxgep) 82344961713Sgirish { 82444961713Sgirish int alloc_size; 82544961713Sgirish nxge_classify_t *classify_ptr; 82644961713Sgirish 82744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw")); 82844961713Sgirish classify_ptr = &nxgep->classifier; 82944961713Sgirish 83044961713Sgirish if (classify_ptr->state & NXGE_FFLP_SW_INIT) { 83144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 832a3c5bd6dSspeer "nxge_classify_init_sw already init")); 83344961713Sgirish return (NXGE_OK); 83444961713Sgirish } 835a3c5bd6dSspeer /* Init SW structures */ 83644961713Sgirish classify_ptr->tcam_size = TCAM_NIU_TCAM_MAX_ENTRY; 837a3c5bd6dSspeer 838a3c5bd6dSspeer /* init data structures, based on HW type */ 8392e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 84044961713Sgirish classify_ptr->tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY; 841a3c5bd6dSspeer /* 842a3c5bd6dSspeer * check if fcram based classification is required and init the 843a3c5bd6dSspeer * flow storage 844a3c5bd6dSspeer */ 84544961713Sgirish } 84644961713Sgirish alloc_size = sizeof (tcam_flow_spec_t) * classify_ptr->tcam_size; 84744961713Sgirish classify_ptr->tcam_entries = KMEM_ZALLOC(alloc_size, NULL); 84844961713Sgirish 849a3c5bd6dSspeer /* Init defaults */ 850a3c5bd6dSspeer /* 851a3c5bd6dSspeer * add hacks required for HW shortcomings for example, code to handle 852a3c5bd6dSspeer * fragmented packets 853a3c5bd6dSspeer */ 85444961713Sgirish nxge_init_h1_table(); 85544961713Sgirish nxge_crc_ccitt_init(); 85644961713Sgirish nxgep->classifier.tcam_location = nxgep->function_num; 85744961713Sgirish nxgep->classifier.fragment_bug = 1; 85844961713Sgirish classify_ptr->state |= NXGE_FFLP_SW_INIT; 85944961713Sgirish 86044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw")); 86144961713Sgirish return (NXGE_OK); 86244961713Sgirish } 86344961713Sgirish 86444961713Sgirish nxge_status_t 86544961713Sgirish nxge_classify_exit_sw(p_nxge_t nxgep) 86644961713Sgirish { 86744961713Sgirish int alloc_size; 86844961713Sgirish nxge_classify_t *classify_ptr; 86944961713Sgirish int fsize; 870a3c5bd6dSspeer 87144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw")); 87244961713Sgirish classify_ptr = &nxgep->classifier; 87344961713Sgirish 87444961713Sgirish fsize = sizeof (tcam_flow_spec_t); 87544961713Sgirish if (classify_ptr->tcam_entries) { 876a3c5bd6dSspeer alloc_size = fsize * classify_ptr->tcam_size; 877a3c5bd6dSspeer KMEM_FREE((void *) classify_ptr->tcam_entries, alloc_size); 87844961713Sgirish } 87944961713Sgirish nxgep->classifier.state = NULL; 88044961713Sgirish 88144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw")); 88244961713Sgirish return (NXGE_OK); 88344961713Sgirish } 88444961713Sgirish 88544961713Sgirish /* 88644961713Sgirish * Figures out the location where the TCAM entry is 88744961713Sgirish * to be inserted. 88844961713Sgirish * 88944961713Sgirish * The current implementation is just a place holder and it 89044961713Sgirish * returns the next tcam location. 89144961713Sgirish * The real location determining algorithm would consider 89244961713Sgirish * the priority, partition etc ... before deciding which 89344961713Sgirish * location to insert. 89444961713Sgirish * 89544961713Sgirish */ 89644961713Sgirish 8970a8e077aSspeer /* ARGSUSED */ 89844961713Sgirish static tcam_location_t 89944961713Sgirish nxge_get_tcam_location(p_nxge_t nxgep, uint8_t class) 90044961713Sgirish { 90144961713Sgirish tcam_location_t location; 902a3c5bd6dSspeer 90344961713Sgirish location = nxgep->classifier.tcam_location; 90444961713Sgirish nxgep->classifier.tcam_location = (location + nxgep->nports) % 905a3c5bd6dSspeer nxgep->classifier.tcam_size; 90644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 907a3c5bd6dSspeer "nxge_get_tcam_location: location %d next %d \n", 908a3c5bd6dSspeer location, nxgep->classifier.tcam_location)); 90944961713Sgirish return (location); 91044961713Sgirish } 91144961713Sgirish 91244961713Sgirish /* 91344961713Sgirish * Figures out the RDC Group for the entry 91444961713Sgirish * 91544961713Sgirish * The current implementation is just a place holder and it 91644961713Sgirish * returns 0. 91744961713Sgirish * The real location determining algorithm would consider 91844961713Sgirish * the partition etc ... before deciding w 91944961713Sgirish * 92044961713Sgirish */ 921a3c5bd6dSspeer 9220a8e077aSspeer /* ARGSUSED */ 92344961713Sgirish static uint8_t 92444961713Sgirish nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, intptr_t cookie) 92544961713Sgirish { 92644961713Sgirish int use_port_rdc_grp = 0; 92744961713Sgirish uint8_t rdc_grp = 0; 928a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 929a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 930a3c5bd6dSspeer p_nxge_rdc_grp_t rdc_grp_p; 931a3c5bd6dSspeer 93244961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 93344961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 93444961713Sgirish rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp]; 935*678453a8Sspeer rdc_grp = p_cfgp->def_mac_rxdma_grpid; 936a3c5bd6dSspeer 93744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 938a3c5bd6dSspeer "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n", 939a3c5bd6dSspeer cookie, rdc_grp, rdc_grp_p)); 94044961713Sgirish return (rdc_grp); 94144961713Sgirish } 94244961713Sgirish 94344961713Sgirish /* ARGSUSED */ 94444961713Sgirish static uint8_t 94544961713Sgirish nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, intptr_t cookie) 94644961713Sgirish { 94744961713Sgirish return ((uint8_t)cookie); 94844961713Sgirish } 94944961713Sgirish 9500a8e077aSspeer /* ARGSUSED */ 95144961713Sgirish static void 95244961713Sgirish nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec, 953a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 95444961713Sgirish { 95544961713Sgirish udpip4_spec_t *fspec_key; 95644961713Sgirish udpip4_spec_t *fspec_mask; 95744961713Sgirish 95844961713Sgirish fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec; 95944961713Sgirish fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec; 96044961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 96144961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 96244961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 96344961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 96444961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 965a3c5bd6dSspeer fspec_key->pdst, fspec_key->psrc); 96644961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 967a3c5bd6dSspeer fspec_mask->pdst, fspec_mask->psrc); 96844961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 969a3c5bd6dSspeer tcam_ptr->ip4_class_mask, 970a3c5bd6dSspeer TCAM_CLASS_UDP_IPV4); 97144961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 972a3c5bd6dSspeer tcam_ptr->ip4_proto_mask, 973a3c5bd6dSspeer IPPROTO_UDP); 97444961713Sgirish } 97544961713Sgirish 97644961713Sgirish static void 97744961713Sgirish nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 978a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 97944961713Sgirish { 98044961713Sgirish udpip6_spec_t *fspec_key; 98144961713Sgirish udpip6_spec_t *fspec_mask; 982a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 98344961713Sgirish 98444961713Sgirish fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec; 98544961713Sgirish fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec; 98644961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 98744961713Sgirish if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 988a3c5bd6dSspeer NXGE_CLASS_TCAM_USE_SRC_ADDR) { 98944961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 99044961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 99144961713Sgirish } else { 99244961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 99344961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 99444961713Sgirish } 99544961713Sgirish 99644961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 997a3c5bd6dSspeer tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6); 99844961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 999a3c5bd6dSspeer tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP); 100044961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 1001a3c5bd6dSspeer fspec_key->pdst, fspec_key->psrc); 100244961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 1003a3c5bd6dSspeer fspec_mask->pdst, fspec_mask->psrc); 100444961713Sgirish } 100544961713Sgirish 10060a8e077aSspeer /* ARGSUSED */ 100744961713Sgirish static void 100844961713Sgirish nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec, 1009a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 101044961713Sgirish { 101144961713Sgirish tcpip4_spec_t *fspec_key; 101244961713Sgirish tcpip4_spec_t *fspec_mask; 101344961713Sgirish 101444961713Sgirish fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 101544961713Sgirish fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 101644961713Sgirish 101744961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 101844961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 101944961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 102044961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 102144961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 1022a3c5bd6dSspeer fspec_key->pdst, fspec_key->psrc); 102344961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 1024a3c5bd6dSspeer fspec_mask->pdst, fspec_mask->psrc); 102544961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1026a3c5bd6dSspeer tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4); 102744961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1028a3c5bd6dSspeer tcam_ptr->ip4_proto_mask, IPPROTO_TCP); 102944961713Sgirish } 103044961713Sgirish 10310a8e077aSspeer /* ARGSUSED */ 103244961713Sgirish static void 103344961713Sgirish nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec, 1034a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 103544961713Sgirish { 103644961713Sgirish tcpip4_spec_t *fspec_key; 103744961713Sgirish tcpip4_spec_t *fspec_mask; 103844961713Sgirish 103944961713Sgirish fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 104044961713Sgirish fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 104144961713Sgirish 104244961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 104344961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 104444961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 104544961713Sgirish TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 104644961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1047a3c5bd6dSspeer tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4); 104844961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1049a3c5bd6dSspeer tcam_ptr->ip4_proto_mask, IPPROTO_SCTP); 105044961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 1051a3c5bd6dSspeer fspec_key->pdst, fspec_key->psrc); 105244961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 1053a3c5bd6dSspeer fspec_mask->pdst, fspec_mask->psrc); 105444961713Sgirish } 105544961713Sgirish 105644961713Sgirish static void 105744961713Sgirish nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1058a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 105944961713Sgirish { 106044961713Sgirish tcpip6_spec_t *fspec_key; 106144961713Sgirish tcpip6_spec_t *fspec_mask; 1062a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 1063a3c5bd6dSspeer 106444961713Sgirish fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 106544961713Sgirish fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 106644961713Sgirish 106744961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 106844961713Sgirish if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 1069a3c5bd6dSspeer NXGE_CLASS_TCAM_USE_SRC_ADDR) { 107044961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 107144961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 107244961713Sgirish } else { 107344961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 107444961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 107544961713Sgirish } 107644961713Sgirish 107744961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1078a3c5bd6dSspeer tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6); 107944961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1080a3c5bd6dSspeer tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP); 108144961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 1082a3c5bd6dSspeer fspec_key->pdst, fspec_key->psrc); 108344961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 1084a3c5bd6dSspeer fspec_mask->pdst, fspec_mask->psrc); 108544961713Sgirish } 108644961713Sgirish 108744961713Sgirish static void 108844961713Sgirish nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1089a3c5bd6dSspeer tcam_entry_t *tcam_ptr) 109044961713Sgirish { 109144961713Sgirish tcpip6_spec_t *fspec_key; 109244961713Sgirish tcpip6_spec_t *fspec_mask; 1093a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 109444961713Sgirish 109544961713Sgirish fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 109644961713Sgirish fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 109744961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 109844961713Sgirish 109944961713Sgirish if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 1100a3c5bd6dSspeer NXGE_CLASS_TCAM_USE_SRC_ADDR) { 110144961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 110244961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 110344961713Sgirish } else { 110444961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 110544961713Sgirish TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 110644961713Sgirish } 110744961713Sgirish 110844961713Sgirish TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1109a3c5bd6dSspeer tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6); 111044961713Sgirish TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1111a3c5bd6dSspeer tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP); 111244961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 1113a3c5bd6dSspeer fspec_key->pdst, fspec_key->psrc); 111444961713Sgirish TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 1115a3c5bd6dSspeer fspec_mask->pdst, fspec_mask->psrc); 111644961713Sgirish } 111744961713Sgirish 111844961713Sgirish nxge_status_t 111944961713Sgirish nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res, 1120a3c5bd6dSspeer uint32_t *H1, uint16_t *H2) 112144961713Sgirish { 112244961713Sgirish flow_spec_t *flow_spec; 112344961713Sgirish uint32_t class_cfg; 112444961713Sgirish flow_template_t ft; 1125a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 112644961713Sgirish 112744961713Sgirish int ft_size = sizeof (flow_template_t); 1128a3c5bd6dSspeer 112944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash")); 113044961713Sgirish 113144961713Sgirish flow_spec = (flow_spec_t *)&flow_res->flow_spec; 113244961713Sgirish bzero((char *)&ft, ft_size); 113344961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1134a3c5bd6dSspeer 113544961713Sgirish switch (flow_spec->flow_type) { 1136a3c5bd6dSspeer case FSPEC_TCPIP4: 1137a3c5bd6dSspeer class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4]; 1138a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 1139a3c5bd6dSspeer ft.ip_proto = IPPROTO_TCP; 1140a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 1141a3c5bd6dSspeer ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src; 1142a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 1143a3c5bd6dSspeer ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst; 1144a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 1145a3c5bd6dSspeer ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc; 1146a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 1147a3c5bd6dSspeer ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst; 1148a3c5bd6dSspeer break; 1149a3c5bd6dSspeer 1150a3c5bd6dSspeer case FSPEC_UDPIP4: 1151a3c5bd6dSspeer class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4]; 1152a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 1153a3c5bd6dSspeer ft.ip_proto = IPPROTO_UDP; 1154a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 1155a3c5bd6dSspeer ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src; 1156a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 1157a3c5bd6dSspeer ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst; 1158a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 1159a3c5bd6dSspeer ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc; 1160a3c5bd6dSspeer if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 1161a3c5bd6dSspeer ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst; 1162a3c5bd6dSspeer break; 1163a3c5bd6dSspeer 1164a3c5bd6dSspeer default: 1165a3c5bd6dSspeer return (NXGE_ERROR); 116644961713Sgirish } 116744961713Sgirish 116844961713Sgirish *H1 = nxge_compute_h1(p_class_cfgp->init_h1, 1169a3c5bd6dSspeer (uint32_t *)&ft, ft_size) & 0xfffff; 117044961713Sgirish *H2 = nxge_compute_h2(p_class_cfgp->init_h2, 1171a3c5bd6dSspeer (uint8_t *)&ft, ft_size); 117244961713Sgirish 117344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash")); 117444961713Sgirish return (NXGE_OK); 117544961713Sgirish } 117644961713Sgirish 117744961713Sgirish nxge_status_t 117844961713Sgirish nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 117944961713Sgirish { 118044961713Sgirish uint32_t H1; 118144961713Sgirish uint16_t H2; 118244961713Sgirish nxge_status_t status = NXGE_OK; 118344961713Sgirish 118444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry")); 118544961713Sgirish status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2); 118644961713Sgirish if (status != NXGE_OK) { 118744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1188a3c5bd6dSspeer " nxge_add_fcram_entry failed ")); 118944961713Sgirish return (status); 119044961713Sgirish } 119144961713Sgirish 119244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry")); 119344961713Sgirish return (NXGE_OK); 119444961713Sgirish } 119544961713Sgirish 119644961713Sgirish /* 119744961713Sgirish * Already decided this flow goes into the tcam 119844961713Sgirish */ 119944961713Sgirish 120044961713Sgirish nxge_status_t 120144961713Sgirish nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 120244961713Sgirish { 120344961713Sgirish npi_handle_t handle; 120444961713Sgirish intptr_t channel_cookie; 120544961713Sgirish intptr_t flow_cookie; 120644961713Sgirish flow_spec_t *flow_spec; 120744961713Sgirish npi_status_t rs = NPI_SUCCESS; 120844961713Sgirish tcam_entry_t tcam_ptr; 120944961713Sgirish tcam_location_t location = 0; 121044961713Sgirish uint8_t offset, rdc_grp; 1211a3c5bd6dSspeer p_nxge_hw_list_t hw_p; 121244961713Sgirish 121344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry")); 121444961713Sgirish handle = nxgep->npi_reg_handle; 121544961713Sgirish 1216a3c5bd6dSspeer bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 121744961713Sgirish flow_spec = (flow_spec_t *)&flow_res->flow_spec; 121844961713Sgirish flow_cookie = flow_res->flow_cookie; 121944961713Sgirish channel_cookie = flow_res->channel_cookie; 122044961713Sgirish 122144961713Sgirish switch (flow_spec->flow_type) { 1222a3c5bd6dSspeer case FSPEC_TCPIP4: 1223a3c5bd6dSspeer nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr); 1224a3c5bd6dSspeer location = nxge_get_tcam_location(nxgep, 1225a3c5bd6dSspeer TCAM_CLASS_TCP_IPV4); 1226a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4, 1227a3c5bd6dSspeer flow_cookie); 1228a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4, 1229a3c5bd6dSspeer channel_cookie); 1230a3c5bd6dSspeer break; 1231a3c5bd6dSspeer 1232a3c5bd6dSspeer case FSPEC_UDPIP4: 1233a3c5bd6dSspeer nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr); 1234a3c5bd6dSspeer location = nxge_get_tcam_location(nxgep, 1235a3c5bd6dSspeer TCAM_CLASS_UDP_IPV4); 1236a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, 1237a3c5bd6dSspeer TCAM_CLASS_UDP_IPV4, 1238a3c5bd6dSspeer flow_cookie); 1239a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, 1240a3c5bd6dSspeer TCAM_CLASS_UDP_IPV4, 1241a3c5bd6dSspeer channel_cookie); 1242a3c5bd6dSspeer break; 1243a3c5bd6dSspeer 1244a3c5bd6dSspeer case FSPEC_TCPIP6: 1245a3c5bd6dSspeer nxge_fill_tcam_entry_tcp_ipv6(nxgep, 1246a3c5bd6dSspeer flow_spec, &tcam_ptr); 1247a3c5bd6dSspeer location = nxge_get_tcam_location(nxgep, 1248a3c5bd6dSspeer TCAM_CLASS_TCP_IPV6); 1249a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6, 1250a3c5bd6dSspeer flow_cookie); 1251a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6, 1252a3c5bd6dSspeer channel_cookie); 1253a3c5bd6dSspeer break; 1254a3c5bd6dSspeer 1255a3c5bd6dSspeer case FSPEC_UDPIP6: 1256a3c5bd6dSspeer nxge_fill_tcam_entry_udp_ipv6(nxgep, 1257a3c5bd6dSspeer flow_spec, &tcam_ptr); 1258a3c5bd6dSspeer location = nxge_get_tcam_location(nxgep, 1259a3c5bd6dSspeer TCAM_CLASS_UDP_IPV6); 1260a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, 1261a3c5bd6dSspeer TCAM_CLASS_UDP_IPV6, 1262a3c5bd6dSspeer channel_cookie); 1263a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, 1264a3c5bd6dSspeer TCAM_CLASS_UDP_IPV6, 1265a3c5bd6dSspeer flow_cookie); 1266a3c5bd6dSspeer break; 1267a3c5bd6dSspeer 1268a3c5bd6dSspeer case FSPEC_SCTPIP4: 1269a3c5bd6dSspeer nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr); 1270a3c5bd6dSspeer location = nxge_get_tcam_location(nxgep, 1271a3c5bd6dSspeer TCAM_CLASS_SCTP_IPV4); 1272a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, 1273a3c5bd6dSspeer TCAM_CLASS_SCTP_IPV4, 1274a3c5bd6dSspeer channel_cookie); 1275a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, 1276a3c5bd6dSspeer TCAM_CLASS_SCTP_IPV4, 1277a3c5bd6dSspeer flow_cookie); 1278a3c5bd6dSspeer break; 1279a3c5bd6dSspeer 1280a3c5bd6dSspeer case FSPEC_SCTPIP6: 1281a3c5bd6dSspeer nxge_fill_tcam_entry_sctp_ipv6(nxgep, 1282a3c5bd6dSspeer flow_spec, &tcam_ptr); 1283a3c5bd6dSspeer location = nxge_get_tcam_location(nxgep, 1284a3c5bd6dSspeer TCAM_CLASS_SCTP_IPV4); 1285a3c5bd6dSspeer rdc_grp = nxge_get_rdc_group(nxgep, 1286a3c5bd6dSspeer TCAM_CLASS_SCTP_IPV6, 1287a3c5bd6dSspeer channel_cookie); 1288a3c5bd6dSspeer offset = nxge_get_rdc_offset(nxgep, 1289a3c5bd6dSspeer TCAM_CLASS_SCTP_IPV6, 1290a3c5bd6dSspeer flow_cookie); 1291a3c5bd6dSspeer break; 1292a3c5bd6dSspeer 1293a3c5bd6dSspeer default: 1294a3c5bd6dSspeer return (NXGE_OK); 129544961713Sgirish } 129644961713Sgirish 129744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1298a3c5bd6dSspeer " nxge_add_tcam_entry write" 1299a3c5bd6dSspeer " for location %d offset %d", location, offset)); 130044961713Sgirish 130144961713Sgirish if ((hw_p = nxgep->nxge_hw_p) == NULL) { 130244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1303a3c5bd6dSspeer " nxge_add_tcam_entry: common hardware not set", 130444961713Sgirish nxgep->niu_type)); 130544961713Sgirish return (NXGE_ERROR); 130644961713Sgirish } 1307a3c5bd6dSspeer 130844961713Sgirish MUTEX_ENTER(&hw_p->nxge_tcam_lock); 1309a3c5bd6dSspeer rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr); 131044961713Sgirish 131144961713Sgirish if (rs & NPI_FFLP_ERROR) { 131244961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 131344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1314a3c5bd6dSspeer " nxge_add_tcam_entry write" 1315a3c5bd6dSspeer " failed for location %d", location)); 131644961713Sgirish return (NXGE_ERROR | rs); 131744961713Sgirish } 1318a3c5bd6dSspeer 131944961713Sgirish tcam_ptr.match_action.value = 0; 132044961713Sgirish tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp; 132144961713Sgirish tcam_ptr.match_action.bits.ldw.offset = offset; 132244961713Sgirish tcam_ptr.match_action.bits.ldw.tres = 132344961713Sgirish TRES_TERM_OVRD_L2RDC; 132444961713Sgirish if (channel_cookie == -1) 132544961713Sgirish tcam_ptr.match_action.bits.ldw.disc = 1; 132644961713Sgirish rs = npi_fflp_tcam_asc_ram_entry_write(handle, 1327a3c5bd6dSspeer location, tcam_ptr.match_action.value); 132844961713Sgirish if (rs & NPI_FFLP_ERROR) { 132944961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 133044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1331a3c5bd6dSspeer " nxge_add_tcam_entry write" 1332a3c5bd6dSspeer " failed for ASC RAM location %d", location)); 133344961713Sgirish return (NXGE_ERROR | rs); 133444961713Sgirish } 1335a3c5bd6dSspeer bcopy((void *) &tcam_ptr, 1336a3c5bd6dSspeer (void *) &nxgep->classifier.tcam_entries[location].tce, 1337a3c5bd6dSspeer sizeof (tcam_entry_t)); 133844961713Sgirish 133944961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 134044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry")); 134144961713Sgirish return (NXGE_OK); 134244961713Sgirish } 134344961713Sgirish 134414ea4bb7Ssd static nxge_status_t 134514ea4bb7Ssd nxge_tcam_handle_ip_fragment(p_nxge_t nxgep) 134644961713Sgirish { 134744961713Sgirish tcam_entry_t tcam_ptr; 134844961713Sgirish tcam_location_t location; 134944961713Sgirish uint8_t class; 135014ea4bb7Ssd uint32_t class_config; 135144961713Sgirish npi_handle_t handle; 135244961713Sgirish npi_status_t rs = NPI_SUCCESS; 1353a3c5bd6dSspeer p_nxge_hw_list_t hw_p; 135414ea4bb7Ssd nxge_status_t status = NXGE_OK; 135544961713Sgirish 135644961713Sgirish handle = nxgep->npi_reg_handle; 135744961713Sgirish class = 0; 1358a3c5bd6dSspeer bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 135944961713Sgirish tcam_ptr.ip4_noport_key = 1; 136044961713Sgirish tcam_ptr.ip4_noport_mask = 1; 136114ea4bb7Ssd location = nxgep->function_num; 136244961713Sgirish nxgep->classifier.fragment_bug_location = location; 136344961713Sgirish 136444961713Sgirish if ((hw_p = nxgep->nxge_hw_p) == NULL) { 136544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 136614ea4bb7Ssd " nxge_tcam_handle_ip_fragment:" 136744961713Sgirish " common hardware not set", 136844961713Sgirish nxgep->niu_type)); 136914ea4bb7Ssd return (NXGE_ERROR); 137044961713Sgirish } 137144961713Sgirish MUTEX_ENTER(&hw_p->nxge_tcam_lock); 137244961713Sgirish rs = npi_fflp_tcam_entry_write(handle, 1373a3c5bd6dSspeer location, &tcam_ptr); 137444961713Sgirish 137544961713Sgirish if (rs & NPI_FFLP_ERROR) { 137644961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 137744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1378a3c5bd6dSspeer " nxge_tcam_handle_ip_fragment " 1379a3c5bd6dSspeer " tcam_entry write" 1380a3c5bd6dSspeer " failed for location %d", location)); 138114ea4bb7Ssd return (NXGE_ERROR); 138244961713Sgirish } 138344961713Sgirish tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp; 1384a3c5bd6dSspeer tcam_ptr.match_action.bits.ldw.offset = 0; /* use the default */ 138544961713Sgirish tcam_ptr.match_action.bits.ldw.tres = 138644961713Sgirish TRES_TERM_USE_OFFSET; 138744961713Sgirish rs = npi_fflp_tcam_asc_ram_entry_write(handle, 1388a3c5bd6dSspeer location, tcam_ptr.match_action.value); 138944961713Sgirish 139044961713Sgirish if (rs & NPI_FFLP_ERROR) { 139144961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 139244961713Sgirish NXGE_DEBUG_MSG((nxgep, 1393a3c5bd6dSspeer FFLP_CTL, 1394a3c5bd6dSspeer " nxge_tcam_handle_ip_fragment " 1395a3c5bd6dSspeer " tcam_entry write" 1396a3c5bd6dSspeer " failed for ASC RAM location %d", location)); 139714ea4bb7Ssd return (NXGE_ERROR); 139844961713Sgirish } 1399a3c5bd6dSspeer bcopy((void *) &tcam_ptr, 1400a3c5bd6dSspeer (void *) &nxgep->classifier.tcam_entries[location].tce, 1401a3c5bd6dSspeer sizeof (tcam_entry_t)); 140214ea4bb7Ssd for (class = TCAM_CLASS_TCP_IPV4; 1403a3c5bd6dSspeer class <= TCAM_CLASS_SCTP_IPV6; class++) { 140414ea4bb7Ssd class_config = nxgep->class_config.class_cfg[class]; 140514ea4bb7Ssd class_config |= NXGE_CLASS_TCAM_LOOKUP; 140614ea4bb7Ssd status = nxge_fflp_ip_class_config(nxgep, class, class_config); 140714ea4bb7Ssd 140814ea4bb7Ssd if (status & NPI_FFLP_ERROR) { 140914ea4bb7Ssd MUTEX_EXIT(&hw_p->nxge_tcam_lock); 141014ea4bb7Ssd NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1411a3c5bd6dSspeer "nxge_tcam_handle_ip_fragment " 1412a3c5bd6dSspeer "nxge_fflp_ip_class_config failed " 1413a3c5bd6dSspeer " class %d config %x ", class, class_config)); 141414ea4bb7Ssd return (NXGE_ERROR); 141514ea4bb7Ssd } 141614ea4bb7Ssd } 141714ea4bb7Ssd 141814ea4bb7Ssd rs = npi_fflp_cfg_tcam_enable(handle); 141914ea4bb7Ssd if (rs & NPI_FFLP_ERROR) { 142014ea4bb7Ssd MUTEX_EXIT(&hw_p->nxge_tcam_lock); 142114ea4bb7Ssd NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1422a3c5bd6dSspeer "nxge_tcam_handle_ip_fragment " 1423a3c5bd6dSspeer " nxge_fflp_config_tcam_enable failed")); 142414ea4bb7Ssd return (NXGE_ERROR); 142514ea4bb7Ssd } 142644961713Sgirish MUTEX_EXIT(&hw_p->nxge_tcam_lock); 142714ea4bb7Ssd return (NXGE_OK); 142844961713Sgirish } 142944961713Sgirish 143044961713Sgirish /* ARGSUSED */ 143144961713Sgirish static int 1432a3c5bd6dSspeer nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res) 143344961713Sgirish { 143444961713Sgirish return (0); 143544961713Sgirish } 143644961713Sgirish 143744961713Sgirish nxge_status_t 143844961713Sgirish nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res) 143944961713Sgirish { 144044961713Sgirish 144144961713Sgirish int insert_hash = 0; 144244961713Sgirish nxge_status_t status = NXGE_OK; 144344961713Sgirish 14442e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1445a3c5bd6dSspeer /* determine whether to do TCAM or Hash flow */ 144644961713Sgirish insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res); 144744961713Sgirish } 144844961713Sgirish if (insert_hash) { 144944961713Sgirish status = nxge_add_fcram_entry(nxgep, flow_res); 145044961713Sgirish } else { 145144961713Sgirish status = nxge_add_tcam_entry(nxgep, flow_res); 145244961713Sgirish } 145344961713Sgirish return (status); 145444961713Sgirish } 145544961713Sgirish 145644961713Sgirish void 145744961713Sgirish nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp) 145844961713Sgirish { 145944961713Sgirish flow_resource_t *fs; 146044961713Sgirish 1461a3c5bd6dSspeer fs = (flow_resource_t *)mp->b_rptr; 146244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1463a3c5bd6dSspeer "nxge_put_tcam addr fs $%p type %x offset %x", 1464a3c5bd6dSspeer fs, fs->flow_spec.flow_type, fs->channel_cookie)); 146544961713Sgirish (void) nxge_add_tcam_entry(nxgep, fs); 146644961713Sgirish } 146744961713Sgirish 146844961713Sgirish nxge_status_t 146944961713Sgirish nxge_fflp_config_tcam_enable(p_nxge_t nxgep) 147044961713Sgirish { 147144961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 147244961713Sgirish npi_status_t rs = NPI_SUCCESS; 147344961713Sgirish 147444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable")); 147544961713Sgirish rs = npi_fflp_cfg_tcam_enable(handle); 147644961713Sgirish if (rs & NPI_FFLP_ERROR) { 147744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1478a3c5bd6dSspeer " nxge_fflp_config_tcam_enable failed")); 147944961713Sgirish return (NXGE_ERROR | rs); 148044961713Sgirish } 148144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable")); 148244961713Sgirish return (NXGE_OK); 148344961713Sgirish } 148444961713Sgirish 148544961713Sgirish nxge_status_t 148644961713Sgirish nxge_fflp_config_tcam_disable(p_nxge_t nxgep) 148744961713Sgirish { 148844961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 148944961713Sgirish npi_status_t rs = NPI_SUCCESS; 149044961713Sgirish 149144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1492a3c5bd6dSspeer " ==> nxge_fflp_config_tcam_disable")); 149344961713Sgirish rs = npi_fflp_cfg_tcam_disable(handle); 149444961713Sgirish if (rs & NPI_FFLP_ERROR) { 149544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1496a3c5bd6dSspeer " nxge_fflp_config_tcam_disable failed")); 149744961713Sgirish return (NXGE_ERROR | rs); 149844961713Sgirish } 149944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1500a3c5bd6dSspeer " <== nxge_fflp_config_tcam_disable")); 150144961713Sgirish return (NXGE_OK); 150244961713Sgirish } 150344961713Sgirish 150444961713Sgirish nxge_status_t 150544961713Sgirish nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep) 150644961713Sgirish { 150744961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 150844961713Sgirish npi_status_t rs = NPI_SUCCESS; 1509a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 1510a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 1511a3c5bd6dSspeer uint8_t partition; 151244961713Sgirish 151344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1514a3c5bd6dSspeer " ==> nxge_fflp_config_hash_lookup_enable")); 151544961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 151644961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 151744961713Sgirish 1518*678453a8Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 1519*678453a8Sspeer if (p_cfgp->grpids[partition]) { 1520*678453a8Sspeer rs = npi_fflp_cfg_fcram_partition_enable( 1521*678453a8Sspeer handle, partition); 1522*678453a8Sspeer if (rs != NPI_SUCCESS) { 1523*678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1524*678453a8Sspeer " nxge_fflp_config_hash_lookup_enable" 1525*678453a8Sspeer "failed FCRAM partition" 1526*678453a8Sspeer " enable for partition %d ", partition)); 1527*678453a8Sspeer return (NXGE_ERROR | rs); 1528*678453a8Sspeer } 152944961713Sgirish } 153044961713Sgirish } 153144961713Sgirish 153244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1533a3c5bd6dSspeer " <== nxge_fflp_config_hash_lookup_enable")); 153444961713Sgirish return (NXGE_OK); 153544961713Sgirish } 153644961713Sgirish 153744961713Sgirish nxge_status_t 153844961713Sgirish nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep) 153944961713Sgirish { 154044961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 154144961713Sgirish npi_status_t rs = NPI_SUCCESS; 1542a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 1543a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 1544a3c5bd6dSspeer uint8_t partition; 154544961713Sgirish 154644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1547a3c5bd6dSspeer " ==> nxge_fflp_config_hash_lookup_disable")); 154844961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 154944961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 155044961713Sgirish 1551*678453a8Sspeer for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 1552*678453a8Sspeer if (p_cfgp->grpids[partition]) { 1553*678453a8Sspeer rs = npi_fflp_cfg_fcram_partition_disable(handle, 1554*678453a8Sspeer partition); 1555*678453a8Sspeer if (rs != NPI_SUCCESS) { 1556*678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1557*678453a8Sspeer " nxge_fflp_config_hash_lookup_disable" 1558*678453a8Sspeer " failed FCRAM partition" 1559*678453a8Sspeer " disable for partition %d ", partition)); 1560*678453a8Sspeer return (NXGE_ERROR | rs); 1561*678453a8Sspeer } 156244961713Sgirish } 156344961713Sgirish } 156444961713Sgirish 156544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1566a3c5bd6dSspeer " <== nxge_fflp_config_hash_lookup_disable")); 156744961713Sgirish return (NXGE_OK); 156844961713Sgirish } 156944961713Sgirish 157044961713Sgirish nxge_status_t 157144961713Sgirish nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep) 157244961713Sgirish { 157344961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 157444961713Sgirish npi_status_t rs = NPI_SUCCESS; 157544961713Sgirish 157644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1577a3c5bd6dSspeer " ==> nxge_fflp_config_llc_snap_enable")); 157844961713Sgirish rs = npi_fflp_cfg_llcsnap_enable(handle); 157944961713Sgirish if (rs & NPI_FFLP_ERROR) { 158044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1581a3c5bd6dSspeer " nxge_fflp_config_llc_snap_enable failed")); 158244961713Sgirish return (NXGE_ERROR | rs); 158344961713Sgirish } 158444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1585a3c5bd6dSspeer " <== nxge_fflp_config_llc_snap_enable")); 158644961713Sgirish return (NXGE_OK); 158744961713Sgirish } 158844961713Sgirish 158944961713Sgirish nxge_status_t 159044961713Sgirish nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep) 159144961713Sgirish { 159244961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 159344961713Sgirish npi_status_t rs = NPI_SUCCESS; 1594a3c5bd6dSspeer 159544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1596a3c5bd6dSspeer " ==> nxge_fflp_config_llc_snap_disable")); 159744961713Sgirish rs = npi_fflp_cfg_llcsnap_disable(handle); 159844961713Sgirish if (rs & NPI_FFLP_ERROR) { 159944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1600a3c5bd6dSspeer " nxge_fflp_config_llc_snap_disable failed")); 160144961713Sgirish return (NXGE_ERROR | rs); 160244961713Sgirish } 160344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1604a3c5bd6dSspeer " <== nxge_fflp_config_llc_snap_disable")); 160544961713Sgirish return (NXGE_OK); 160644961713Sgirish } 160744961713Sgirish 160844961713Sgirish nxge_status_t 160944961713Sgirish nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class, 1610a3c5bd6dSspeer uint32_t config) 161144961713Sgirish { 161244961713Sgirish npi_status_t rs = NPI_SUCCESS; 161344961713Sgirish npi_handle_t handle = nxgep->npi_reg_handle; 161444961713Sgirish uint8_t tos, tos_mask, proto, ver = 0; 161544961713Sgirish uint8_t class_enable = 0; 161644961713Sgirish 161744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config")); 161844961713Sgirish 161944961713Sgirish tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >> 1620a3c5bd6dSspeer NXGE_CLASS_CFG_IP_TOS_SHIFT; 162144961713Sgirish tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >> 162244961713Sgirish NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT; 162344961713Sgirish proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >> 162444961713Sgirish NXGE_CLASS_CFG_IP_PROTO_SHIFT; 162544961713Sgirish if (config & NXGE_CLASS_CFG_IP_IPV6_MASK) 162644961713Sgirish ver = 1; 162744961713Sgirish if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK) 162844961713Sgirish class_enable = 1; 162944961713Sgirish rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask, 1630a3c5bd6dSspeer proto, ver); 163144961713Sgirish if (rs & NPI_FFLP_ERROR) { 163244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 163344961713Sgirish " nxge_fflp_ip_usr_class_config" 163444961713Sgirish " for class %d failed ", class)); 163544961713Sgirish return (NXGE_ERROR | rs); 163644961713Sgirish } 163744961713Sgirish if (class_enable) 163844961713Sgirish rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class); 163944961713Sgirish else 164044961713Sgirish rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 164144961713Sgirish 164244961713Sgirish if (rs & NPI_FFLP_ERROR) { 164344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1644a3c5bd6dSspeer " nxge_fflp_ip_usr_class_config" 1645a3c5bd6dSspeer " TCAM enable/disable for class %d failed ", class)); 164644961713Sgirish return (NXGE_ERROR | rs); 164744961713Sgirish } 164844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config")); 164944961713Sgirish return (NXGE_OK); 165044961713Sgirish } 165144961713Sgirish 165244961713Sgirish nxge_status_t 1653a3c5bd6dSspeer nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config) 165444961713Sgirish { 165544961713Sgirish uint32_t class_config; 165644961713Sgirish nxge_status_t t_status = NXGE_OK; 165744961713Sgirish nxge_status_t f_status = NXGE_OK; 1658a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 165944961713Sgirish 166044961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 1661a3c5bd6dSspeer 166244961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 166344961713Sgirish class_config = p_class_cfgp->class_cfg[class]; 166444961713Sgirish 166544961713Sgirish if (class_config != config) { 166644961713Sgirish p_class_cfgp->class_cfg[class] = config; 166744961713Sgirish class_config = config; 166844961713Sgirish } 166944961713Sgirish 167044961713Sgirish t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config); 167144961713Sgirish f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config); 167244961713Sgirish 167344961713Sgirish if (t_status & NPI_FFLP_ERROR) { 167444961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1675a3c5bd6dSspeer " nxge_fflp_ip_class_config %x" 1676a3c5bd6dSspeer " for class %d tcam failed", config, class)); 167744961713Sgirish return (t_status); 167844961713Sgirish } 167944961713Sgirish if (f_status & NPI_FFLP_ERROR) { 168044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1681a3c5bd6dSspeer " nxge_fflp_ip_class_config %x" 1682a3c5bd6dSspeer " for class %d flow key failed", config, class)); 168344961713Sgirish return (f_status); 168444961713Sgirish } 168544961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 168644961713Sgirish return (NXGE_OK); 168744961713Sgirish } 168844961713Sgirish 168944961713Sgirish nxge_status_t 169044961713Sgirish nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class, 1691a3c5bd6dSspeer uint32_t *config) 169244961713Sgirish { 169344961713Sgirish uint32_t t_class_config, f_class_config; 169444961713Sgirish int t_status = NXGE_OK; 169544961713Sgirish int f_status = NXGE_OK; 169644961713Sgirish 169744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 1698a3c5bd6dSspeer 169944961713Sgirish t_class_config = f_class_config = 0; 170044961713Sgirish t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config); 170144961713Sgirish f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config); 170244961713Sgirish 170344961713Sgirish if (t_status & NPI_FFLP_ERROR) { 170444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1705a3c5bd6dSspeer " nxge_fflp_ip_class_config_get " 1706a3c5bd6dSspeer " for class %d tcam failed", class)); 170744961713Sgirish return (t_status); 170844961713Sgirish } 170944961713Sgirish 171044961713Sgirish if (f_status & NPI_FFLP_ERROR) { 171144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1712a3c5bd6dSspeer " nxge_fflp_ip_class_config_get " 1713a3c5bd6dSspeer " for class %d flow key failed", class)); 171444961713Sgirish return (f_status); 171544961713Sgirish } 171644961713Sgirish 171744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1718a3c5bd6dSspeer " nxge_fflp_ip_class_config tcam %x flow %x", 1719a3c5bd6dSspeer t_class_config, f_class_config)); 172044961713Sgirish 172144961713Sgirish *config = t_class_config | f_class_config; 172244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get")); 172344961713Sgirish return (NXGE_OK); 172444961713Sgirish } 172544961713Sgirish 172644961713Sgirish nxge_status_t 172744961713Sgirish nxge_fflp_ip_class_config_all(p_nxge_t nxgep) 172844961713Sgirish { 172944961713Sgirish uint32_t class_config; 173044961713Sgirish tcam_class_t class; 173144961713Sgirish 173244961713Sgirish #ifdef NXGE_DEBUG 173344961713Sgirish int status = NXGE_OK; 173444961713Sgirish #endif 173544961713Sgirish 173644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config")); 173744961713Sgirish for (class = TCAM_CLASS_TCP_IPV4; 1738a3c5bd6dSspeer class <= TCAM_CLASS_SCTP_IPV6; class++) { 173944961713Sgirish class_config = nxgep->class_config.class_cfg[class]; 174044961713Sgirish #ifndef NXGE_DEBUG 174144961713Sgirish (void) nxge_fflp_ip_class_config(nxgep, class, class_config); 174244961713Sgirish #else 174344961713Sgirish status = nxge_fflp_ip_class_config(nxgep, class, class_config); 174444961713Sgirish if (status & NPI_FFLP_ERROR) { 174544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1746a3c5bd6dSspeer "nxge_fflp_ip_class_config failed " 1747a3c5bd6dSspeer " class %d config %x ", 1748a3c5bd6dSspeer class, class_config)); 174944961713Sgirish } 175044961713Sgirish #endif 175144961713Sgirish } 175244961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 175344961713Sgirish return (NXGE_OK); 175444961713Sgirish } 175544961713Sgirish 175644961713Sgirish nxge_status_t 175744961713Sgirish nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id) 175844961713Sgirish { 175944961713Sgirish uint8_t port, rdc_grp; 176044961713Sgirish npi_handle_t handle; 176144961713Sgirish npi_status_t rs = NPI_SUCCESS; 176244961713Sgirish uint8_t priority = 1; 176344961713Sgirish p_nxge_mv_cfg_t vlan_table; 1764a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 1765a3c5bd6dSspeer p_nxge_hw_list_t hw_p; 176644961713Sgirish 176744961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table")); 176844961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 176944961713Sgirish handle = nxgep->npi_reg_handle; 177044961713Sgirish vlan_table = p_class_cfgp->vlan_tbl; 177144961713Sgirish port = nxgep->function_num; 177244961713Sgirish 177344961713Sgirish if (vlan_table[vlan_id].flag == 0) { 177444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1775a3c5bd6dSspeer " nxge_fflp_config_vlan_table" 1776a3c5bd6dSspeer " vlan id is not configured %d", vlan_id)); 177744961713Sgirish return (NXGE_ERROR); 177844961713Sgirish } 177944961713Sgirish 178044961713Sgirish if ((hw_p = nxgep->nxge_hw_p) == NULL) { 178144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 178244961713Sgirish " nxge_fflp_config_vlan_table:" 1783a3c5bd6dSspeer " common hardware not set", nxgep->niu_type)); 178444961713Sgirish return (NXGE_ERROR); 178544961713Sgirish } 178644961713Sgirish MUTEX_ENTER(&hw_p->nxge_vlan_lock); 178744961713Sgirish rdc_grp = vlan_table[vlan_id].rdctbl; 178844961713Sgirish rs = npi_fflp_cfg_enet_vlan_table_assoc(handle, 1789a3c5bd6dSspeer port, vlan_id, 1790a3c5bd6dSspeer rdc_grp, priority); 179144961713Sgirish 179244961713Sgirish MUTEX_EXIT(&hw_p->nxge_vlan_lock); 179344961713Sgirish if (rs & NPI_FFLP_ERROR) { 179444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1795a3c5bd6dSspeer "nxge_fflp_config_vlan_table failed " 1796a3c5bd6dSspeer " Port %d vlan_id %d rdc_grp %d", 1797a3c5bd6dSspeer port, vlan_id, rdc_grp)); 179844961713Sgirish return (NXGE_ERROR | rs); 179944961713Sgirish } 1800a3c5bd6dSspeer 180144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table")); 180244961713Sgirish return (NXGE_OK); 180344961713Sgirish } 180444961713Sgirish 180544961713Sgirish nxge_status_t 180644961713Sgirish nxge_fflp_update_hw(p_nxge_t nxgep) 180744961713Sgirish { 180844961713Sgirish nxge_status_t status = NXGE_OK; 180944961713Sgirish p_nxge_param_t pa; 181044961713Sgirish uint64_t cfgd_vlans; 181144961713Sgirish uint64_t *val_ptr; 181244961713Sgirish int i; 181344961713Sgirish int num_macs; 181444961713Sgirish uint8_t alt_mac; 181544961713Sgirish nxge_param_map_t *p_map; 181644961713Sgirish p_nxge_mv_cfg_t vlan_table; 1817a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 1818a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_all_cfgp; 1819a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 182044961713Sgirish 182144961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw")); 1822a3c5bd6dSspeer 182344961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 182444961713Sgirish p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 182544961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 182644961713Sgirish 182744961713Sgirish status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1); 182844961713Sgirish if (status != NXGE_OK) { 182944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1830a3c5bd6dSspeer "nxge_fflp_set_hash1 Failed")); 183144961713Sgirish return (NXGE_ERROR); 183244961713Sgirish } 183344961713Sgirish 183444961713Sgirish status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2); 183544961713Sgirish if (status != NXGE_OK) { 183644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1837a3c5bd6dSspeer "nxge_fflp_set_hash2 Failed")); 183844961713Sgirish return (NXGE_ERROR); 183944961713Sgirish } 184044961713Sgirish vlan_table = p_class_cfgp->vlan_tbl; 184144961713Sgirish 1842a3c5bd6dSspeer /* configure vlan tables */ 184344961713Sgirish pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp]; 1844adfcba55Sjoycey #if defined(__i386) 1845adfcba55Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value; 1846adfcba55Sjoycey #else 184744961713Sgirish val_ptr = (uint64_t *)pa->value; 1848adfcba55Sjoycey #endif 1849a3c5bd6dSspeer cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >> 1850a3c5bd6dSspeer NXGE_PARAM_ARRAY_CNT_SHIFT); 185144961713Sgirish 185244961713Sgirish for (i = 0; i < cfgd_vlans; i++) { 185344961713Sgirish p_map = (nxge_param_map_t *)&val_ptr[i]; 185444961713Sgirish if (vlan_table[p_map->param_id].flag) { 185544961713Sgirish status = nxge_fflp_config_vlan_table(nxgep, 1856a3c5bd6dSspeer p_map->param_id); 185744961713Sgirish if (status != NXGE_OK) { 185844961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1859a3c5bd6dSspeer "nxge_fflp_config_vlan_table Failed")); 186044961713Sgirish return (NXGE_ERROR); 186144961713Sgirish } 186244961713Sgirish } 186344961713Sgirish } 1864a3c5bd6dSspeer 1865a3c5bd6dSspeer /* config MAC addresses */ 186644961713Sgirish num_macs = p_cfgp->max_macs; 186744961713Sgirish pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp]; 1868adfcba55Sjoycey #if defined(__i386) 1869adfcba55Sjoycey val_ptr = (uint64_t *)(uint32_t)pa->value; 1870adfcba55Sjoycey #else 187144961713Sgirish val_ptr = (uint64_t *)pa->value; 1872adfcba55Sjoycey #endif 187344961713Sgirish 187444961713Sgirish for (alt_mac = 0; alt_mac < num_macs; alt_mac++) { 187544961713Sgirish if (p_class_cfgp->mac_host_info[alt_mac].flag) { 187644961713Sgirish status = nxge_logical_mac_assign_rdc_table(nxgep, 1877a3c5bd6dSspeer alt_mac); 187844961713Sgirish if (status != NXGE_OK) { 187944961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1880a3c5bd6dSspeer "nxge_logical_mac_assign_rdc_table" 1881a3c5bd6dSspeer " Failed")); 188244961713Sgirish return (NXGE_ERROR); 188344961713Sgirish } 188444961713Sgirish } 188544961713Sgirish } 1886a3c5bd6dSspeer 1887a3c5bd6dSspeer /* Config Hash values */ 1888f6485eecSyc /* config classes */ 188944961713Sgirish status = nxge_fflp_ip_class_config_all(nxgep); 189044961713Sgirish if (status != NXGE_OK) { 189144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1892a3c5bd6dSspeer "nxge_fflp_ip_class_config_all Failed")); 189344961713Sgirish return (NXGE_ERROR); 189444961713Sgirish } 189544961713Sgirish return (NXGE_OK); 189644961713Sgirish } 189744961713Sgirish 189844961713Sgirish nxge_status_t 189944961713Sgirish nxge_classify_init_hw(p_nxge_t nxgep) 190044961713Sgirish { 190144961713Sgirish nxge_status_t status = NXGE_OK; 190244961713Sgirish 190344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw")); 190444961713Sgirish 190544961713Sgirish if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) { 190644961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1907a3c5bd6dSspeer "nxge_classify_init_hw already init")); 190844961713Sgirish return (NXGE_OK); 190944961713Sgirish } 191044961713Sgirish 1911a3c5bd6dSspeer /* Now do a real configuration */ 191244961713Sgirish status = nxge_fflp_update_hw(nxgep); 191344961713Sgirish if (status != NXGE_OK) { 191444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1915a3c5bd6dSspeer "nxge_fflp_update_hw failed")); 191644961713Sgirish return (NXGE_ERROR); 191744961713Sgirish } 1918a3c5bd6dSspeer 1919a3c5bd6dSspeer /* Init RDC tables? ? who should do that? rxdma or fflp ? */ 1920a3c5bd6dSspeer /* attach rdc table to the MAC port. */ 192144961713Sgirish status = nxge_main_mac_assign_rdc_table(nxgep); 192244961713Sgirish if (status != NXGE_OK) { 192344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1924a3c5bd6dSspeer "nxge_main_mac_assign_rdc_table failed")); 192544961713Sgirish return (NXGE_ERROR); 192644961713Sgirish } 1927a3c5bd6dSspeer 192858324dfcSspeer status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 192944961713Sgirish if (status != NXGE_OK) { 193044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1931a3c5bd6dSspeer "nxge_multicast_mac_assign_rdc_table failed")); 193244961713Sgirish return (NXGE_ERROR); 193344961713Sgirish } 193414ea4bb7Ssd 193514ea4bb7Ssd status = nxge_tcam_handle_ip_fragment(nxgep); 193614ea4bb7Ssd if (status != NXGE_OK) { 193714ea4bb7Ssd NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1938a3c5bd6dSspeer "nxge_tcam_handle_ip_fragment failed")); 193914ea4bb7Ssd return (NXGE_ERROR); 194014ea4bb7Ssd } 194144961713Sgirish 194244961713Sgirish nxgep->classifier.state |= NXGE_FFLP_HW_INIT; 194344961713Sgirish NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw")); 194444961713Sgirish return (NXGE_OK); 194544961713Sgirish } 194644961713Sgirish 194744961713Sgirish nxge_status_t 194844961713Sgirish nxge_fflp_handle_sys_errors(p_nxge_t nxgep) 194944961713Sgirish { 1950a3c5bd6dSspeer npi_handle_t handle; 1951a3c5bd6dSspeer p_nxge_fflp_stats_t statsp; 1952a3c5bd6dSspeer uint8_t portn, rdc_grp; 1953a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 1954a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 1955a3c5bd6dSspeer vlan_par_err_t vlan_err; 1956a3c5bd6dSspeer tcam_err_t tcam_err; 1957a3c5bd6dSspeer hash_lookup_err_log1_t fcram1_err; 1958a3c5bd6dSspeer hash_lookup_err_log2_t fcram2_err; 1959a3c5bd6dSspeer hash_tbl_data_log_t fcram_err; 196044961713Sgirish 196144961713Sgirish handle = nxgep->npi_handle; 196244961713Sgirish statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats; 196344961713Sgirish portn = nxgep->mac.portnum; 196444961713Sgirish 196544961713Sgirish /* 1966a3c5bd6dSspeer * need to read the fflp error registers to figure out what the error 1967a3c5bd6dSspeer * is 196844961713Sgirish */ 196944961713Sgirish npi_fflp_vlan_error_get(handle, &vlan_err); 197044961713Sgirish npi_fflp_tcam_error_get(handle, &tcam_err); 197144961713Sgirish 197244961713Sgirish if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) { 197344961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 1974a3c5bd6dSspeer " vlan table parity error on port %d" 1975a3c5bd6dSspeer " addr: 0x%x data: 0x%x", 1976a3c5bd6dSspeer portn, vlan_err.bits.ldw.addr, 1977a3c5bd6dSspeer vlan_err.bits.ldw.data)); 197844961713Sgirish statsp->vlan_parity_err++; 197944961713Sgirish 198044961713Sgirish if (vlan_err.bits.ldw.m_err) { 198144961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 1982a3c5bd6dSspeer " vlan table multiple errors on port %d", 1983a3c5bd6dSspeer portn)); 198444961713Sgirish } 198544961713Sgirish statsp->errlog.vlan = (uint32_t)vlan_err.value; 198644961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 1987a3c5bd6dSspeer NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR); 198844961713Sgirish npi_fflp_vlan_error_clear(handle); 198944961713Sgirish } 199044961713Sgirish 199144961713Sgirish if (tcam_err.bits.ldw.err) { 199244961713Sgirish if (tcam_err.bits.ldw.p_ecc != 0) { 199344961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 1994a3c5bd6dSspeer " TCAM ECC error on port %d" 1995a3c5bd6dSspeer " TCAM entry: 0x%x syndrome: 0x%x", 1996a3c5bd6dSspeer portn, tcam_err.bits.ldw.addr, 1997a3c5bd6dSspeer tcam_err.bits.ldw.syndrome)); 199844961713Sgirish statsp->tcam_ecc_err++; 199944961713Sgirish } else { 200044961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2001a3c5bd6dSspeer " TCAM Parity error on port %d" 2002a3c5bd6dSspeer " addr: 0x%x parity value: 0x%x", 2003a3c5bd6dSspeer portn, tcam_err.bits.ldw.addr, 2004a3c5bd6dSspeer tcam_err.bits.ldw.syndrome)); 200544961713Sgirish statsp->tcam_parity_err++; 200644961713Sgirish } 200744961713Sgirish 200844961713Sgirish if (tcam_err.bits.ldw.mult) { 200944961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2010a3c5bd6dSspeer " TCAM Multiple errors on port %d", portn)); 201144961713Sgirish } else { 201244961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2013a3c5bd6dSspeer " TCAM PIO error on port %d", 2014a3c5bd6dSspeer portn)); 201544961713Sgirish } 201644961713Sgirish 201744961713Sgirish statsp->errlog.tcam = (uint32_t)tcam_err.value; 201844961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 2019a3c5bd6dSspeer NXGE_FM_EREPORT_FFLP_TCAM_ERR); 202044961713Sgirish npi_fflp_tcam_error_clear(handle); 202144961713Sgirish } 202244961713Sgirish 202344961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 202444961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 202544961713Sgirish 2026*678453a8Sspeer for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) { 2027*678453a8Sspeer if (p_cfgp->grpids[rdc_grp]) { 2028*678453a8Sspeer npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp); 2029*678453a8Sspeer if (fcram_err.bits.ldw.pio_err) { 2030*678453a8Sspeer NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2031*678453a8Sspeer " FCRAM PIO ECC error on port %d" 2032*678453a8Sspeer " rdc group: %d Hash Table addr: 0x%x" 2033*678453a8Sspeer " syndrome: 0x%x", 2034*678453a8Sspeer portn, rdc_grp, 2035*678453a8Sspeer fcram_err.bits.ldw.fcram_addr, 2036*678453a8Sspeer fcram_err.bits.ldw.syndrome)); 2037*678453a8Sspeer statsp->hash_pio_err[rdc_grp]++; 2038*678453a8Sspeer statsp->errlog.hash_pio[rdc_grp] = 2039*678453a8Sspeer (uint32_t)fcram_err.value; 2040*678453a8Sspeer NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 2041*678453a8Sspeer NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR); 2042*678453a8Sspeer npi_fflp_fcram_error_clear(handle, rdc_grp); 2043*678453a8Sspeer } 204444961713Sgirish } 204544961713Sgirish } 204644961713Sgirish 204744961713Sgirish npi_fflp_fcram_error_log1_get(handle, &fcram1_err); 204844961713Sgirish if (fcram1_err.bits.ldw.ecc_err) { 204944961713Sgirish char *multi_str = ""; 205044961713Sgirish char *multi_bit_str = ""; 2051a3c5bd6dSspeer 205244961713Sgirish npi_fflp_fcram_error_log2_get(handle, &fcram2_err); 205344961713Sgirish if (fcram1_err.bits.ldw.mult_lk) { 205444961713Sgirish multi_str = "multiple"; 205544961713Sgirish } 205644961713Sgirish if (fcram1_err.bits.ldw.mult_bit) { 205744961713Sgirish multi_bit_str = "multiple bits"; 205844961713Sgirish } 2059f6485eecSyc statsp->hash_lookup_err++; 206044961713Sgirish NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2061a3c5bd6dSspeer " FCRAM %s lookup %s ECC error on port %d" 2062a3c5bd6dSspeer " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x", 2063a3c5bd6dSspeer multi_str, multi_bit_str, portn, 2064a3c5bd6dSspeer fcram2_err.bits.ldw.h1, 2065a3c5bd6dSspeer fcram2_err.bits.ldw.subarea, 2066a3c5bd6dSspeer fcram2_err.bits.ldw.syndrome)); 206744961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 2068a3c5bd6dSspeer NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR); 206944961713Sgirish } 207044961713Sgirish statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value; 207144961713Sgirish statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value; 207244961713Sgirish return (NXGE_OK); 207344961713Sgirish } 2074