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 /* 223d16f8e7Sml * 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 28a3c5bd6dSspeer #include <sys/nxge/nxge_impl.h> 29a3c5bd6dSspeer #include <sys/nxge/nxge_mac.h> 30678453a8Sspeer #include <sys/nxge/nxge_hio.h> 3144961713Sgirish 3244961713Sgirish static void nxge_get_niu_property(dev_info_t *, niu_type_t *); 3314ea4bb7Ssd static nxge_status_t nxge_get_mac_addr_properties(p_nxge_t); 3444961713Sgirish static nxge_status_t nxge_use_cfg_n2niu_properties(p_nxge_t); 3544961713Sgirish static void nxge_use_cfg_neptune_properties(p_nxge_t); 3644961713Sgirish static void nxge_use_cfg_dma_config(p_nxge_t); 3744961713Sgirish static void nxge_use_cfg_vlan_class_config(p_nxge_t); 3844961713Sgirish static void nxge_use_cfg_mac_class_config(p_nxge_t); 3944961713Sgirish static void nxge_use_cfg_class_config(p_nxge_t); 4044961713Sgirish static void nxge_use_cfg_link_cfg(p_nxge_t); 4144961713Sgirish static void nxge_set_hw_dma_config(p_nxge_t); 4244961713Sgirish static void nxge_set_hw_vlan_class_config(p_nxge_t); 4344961713Sgirish static void nxge_set_hw_mac_class_config(p_nxge_t); 4444961713Sgirish static void nxge_set_hw_class_config(p_nxge_t); 4544961713Sgirish static nxge_status_t nxge_use_default_dma_config_n2(p_nxge_t); 46a3c5bd6dSspeer static void nxge_ldgv_setup(p_nxge_ldg_t *, p_nxge_ldv_t *, uint8_t, 4744961713Sgirish uint8_t, int *); 4859ac0c16Sdavemq static void nxge_init_mmac(p_nxge_t, boolean_t); 49678453a8Sspeer static void nxge_set_rdc_intr_property(p_nxge_t); 5044961713Sgirish 51a3c5bd6dSspeer uint32_t nxge_use_hw_property = 1; 52a3c5bd6dSspeer uint32_t nxge_groups_per_port = 2; 5344961713Sgirish 54a3c5bd6dSspeer extern uint32_t nxge_use_partition; 55a3c5bd6dSspeer extern uint32_t nxge_dma_obp_props_only; 5644961713Sgirish 57a3c5bd6dSspeer extern uint16_t nxge_rcr_timeout; 58a3c5bd6dSspeer extern uint16_t nxge_rcr_threshold; 5944961713Sgirish 60a3c5bd6dSspeer extern uint_t nxge_rx_intr(void *, void *); 61a3c5bd6dSspeer extern uint_t nxge_tx_intr(void *, void *); 62a3c5bd6dSspeer extern uint_t nxge_mif_intr(void *, void *); 63a3c5bd6dSspeer extern uint_t nxge_mac_intr(void *, void *); 64a3c5bd6dSspeer extern uint_t nxge_syserr_intr(void *, void *); 6544961713Sgirish extern void *nxge_list; 6644961713Sgirish 6744961713Sgirish #define NXGE_SHARED_REG_SW_SIM 6844961713Sgirish 6944961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM 7044961713Sgirish uint64_t global_dev_ctrl = 0; 7144961713Sgirish #endif 7244961713Sgirish 7344961713Sgirish #define MAX_SIBLINGS NXGE_MAX_PORTS 7444961713Sgirish 75a3c5bd6dSspeer extern uint32_t nxge_rbr_size; 76a3c5bd6dSspeer extern uint32_t nxge_rcr_size; 77a3c5bd6dSspeer extern uint32_t nxge_tx_ring_size; 78a3c5bd6dSspeer extern uint32_t nxge_rbr_spare_size; 7944961713Sgirish 80a3c5bd6dSspeer extern npi_status_t npi_mac_altaddr_disable(npi_handle_t, uint8_t, uint8_t); 8144961713Sgirish 8244961713Sgirish static uint8_t p2_tx_fair[2] = {12, 12}; 8344961713Sgirish static uint8_t p2_tx_equal[2] = {12, 12}; 8444961713Sgirish static uint8_t p4_tx_fair[4] = {6, 6, 6, 6}; 8544961713Sgirish static uint8_t p4_tx_equal[4] = {6, 6, 6, 6}; 8644961713Sgirish static uint8_t p2_rx_fair[2] = {8, 8}; 8744961713Sgirish static uint8_t p2_rx_equal[2] = {8, 8}; 8844961713Sgirish static uint8_t p4_rx_fair[4] = {4, 4, 4, 4}; 8944961713Sgirish static uint8_t p4_rx_equal[4] = {4, 4, 4, 4}; 9044961713Sgirish 9144961713Sgirish static uint8_t p2_rdcgrp_fair[2] = {4, 4}; 9244961713Sgirish static uint8_t p2_rdcgrp_equal[2] = {4, 4}; 9344961713Sgirish static uint8_t p4_rdcgrp_fair[4] = {2, 2, 1, 1}; 9444961713Sgirish static uint8_t p4_rdcgrp_equal[4] = {2, 2, 2, 2}; 9544961713Sgirish static uint8_t p2_rdcgrp_cls[2] = {1, 1}; 9644961713Sgirish static uint8_t p4_rdcgrp_cls[4] = {1, 1, 1, 1}; 9744961713Sgirish 9859ac0c16Sdavemq static uint8_t rx_4_1G[4] = {4, 4, 4, 4}; 9959ac0c16Sdavemq static uint8_t rx_2_10G[2] = {8, 8}; 10059ac0c16Sdavemq static uint8_t rx_2_10G_2_1G[4] = {6, 6, 2, 2}; 10159ac0c16Sdavemq static uint8_t rx_1_10G_3_1G[4] = {10, 2, 2, 2}; 10259ac0c16Sdavemq static uint8_t rx_1_1G_1_10G_2_1G[4] = {2, 10, 2, 2}; 10359ac0c16Sdavemq 10459ac0c16Sdavemq static uint8_t tx_4_1G[4] = {6, 6, 6, 6}; 10559ac0c16Sdavemq static uint8_t tx_2_10G[2] = {12, 12}; 10659ac0c16Sdavemq static uint8_t tx_2_10G_2_1G[4] = {10, 10, 2, 2}; 10759ac0c16Sdavemq static uint8_t tx_1_10G_3_1G[4] = {12, 4, 4, 4}; 10859ac0c16Sdavemq static uint8_t tx_1_1G_1_10G_2_1G[4] = {4, 12, 4, 4}; 10959ac0c16Sdavemq 11044961713Sgirish typedef enum { 11144961713Sgirish DEFAULT = 0, 11244961713Sgirish EQUAL, 11344961713Sgirish FAIR, 11444961713Sgirish CUSTOM, 11544961713Sgirish CLASSIFY, 11644961713Sgirish L2_CLASSIFY, 11744961713Sgirish L3_DISTRIBUTE, 11844961713Sgirish L3_CLASSIFY, 11944961713Sgirish L3_TCAM, 12044961713Sgirish CONFIG_TOKEN_NONE 12144961713Sgirish } config_token_t; 12244961713Sgirish 12344961713Sgirish static char *token_names[] = { 12444961713Sgirish "default", 12544961713Sgirish "equal", 12644961713Sgirish "fair", 12744961713Sgirish "custom", 12844961713Sgirish "classify", 12944961713Sgirish "l2_classify", 13044961713Sgirish "l3_distribute", 13144961713Sgirish "l3_classify", 13244961713Sgirish "l3_tcam", 13344961713Sgirish "none", 13444961713Sgirish }; 13544961713Sgirish 13644961713Sgirish void nxge_virint_regs_dump(p_nxge_t nxgep); 13744961713Sgirish 13844961713Sgirish void 13944961713Sgirish nxge_virint_regs_dump(p_nxge_t nxgep) 14044961713Sgirish { 141a3c5bd6dSspeer npi_handle_t handle; 14244961713Sgirish 14344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_virint_regs_dump")); 14444961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 14544961713Sgirish (void) npi_vir_dump_pio_fzc_regs_one(handle); 14644961713Sgirish (void) npi_vir_dump_ldgnum(handle); 14744961713Sgirish (void) npi_vir_dump_ldsv(handle); 14844961713Sgirish (void) npi_vir_dump_imask0(handle); 14944961713Sgirish (void) npi_vir_dump_sid(handle); 15044961713Sgirish (void) npi_mac_dump_regs(handle, nxgep->function_num); 15144961713Sgirish (void) npi_ipp_dump_regs(handle, nxgep->function_num); 15244961713Sgirish (void) npi_fflp_dump_regs(handle); 15344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_virint_regs_dump")); 15444961713Sgirish } 15544961713Sgirish 15644961713Sgirish /* 15744961713Sgirish * For now: we hard coded the DMA configurations. 15844961713Sgirish * and assume for one partition only. 15944961713Sgirish * 16044961713Sgirish * OBP. Then OBP will pass this partition's 16144961713Sgirish * Neptune configurations to fcode to create 16244961713Sgirish * properties for them. 16344961713Sgirish * 16444961713Sgirish * Since Neptune(PCI-E) and NIU (Niagara-2) has 16544961713Sgirish * different bus interfaces, the driver needs 16644961713Sgirish * to know which bus it is connected to. 16744961713Sgirish * Ravinder suggested: create a device property. 16844961713Sgirish * In partitioning environment, we cannot 16944961713Sgirish * use .conf file (need to check). If conf changes, 17044961713Sgirish * need to reboot the system. 17144961713Sgirish * The following function assumes that we will 17244961713Sgirish * retrieve its properties from a virtualized nexus driver. 17344961713Sgirish */ 17444961713Sgirish 17544961713Sgirish nxge_status_t 17644961713Sgirish nxge_cntlops(dev_info_t *dip, nxge_ctl_enum_t ctlop, void *arg, void *result) 17744961713Sgirish { 178a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 17944961713Sgirish int instance; 180a3c5bd6dSspeer p_nxge_t nxgep; 181a3c5bd6dSspeer 18244961713Sgirish #ifndef NXGE_SHARED_REG_SW_SIM 18344961713Sgirish npi_handle_t handle; 18444961713Sgirish uint16_t sr16, cr16; 18544961713Sgirish #endif 18644961713Sgirish instance = ddi_get_instance(dip); 187a3c5bd6dSspeer NXGE_DEBUG_MSG((NULL, VIR_CTL, "Instance %d ", instance)); 188a3c5bd6dSspeer 18944961713Sgirish if (nxge_list == NULL) { 19044961713Sgirish NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 191*52ccf843Smisaki "nxge_cntlops: nxge_list null")); 19244961713Sgirish return (NXGE_ERROR); 19344961713Sgirish } 19444961713Sgirish nxgep = (p_nxge_t)ddi_get_soft_state(nxge_list, instance); 19544961713Sgirish if (nxgep == NULL) { 19644961713Sgirish NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 197*52ccf843Smisaki "nxge_cntlops: nxgep null")); 19844961713Sgirish return (NXGE_ERROR); 19944961713Sgirish } 20044961713Sgirish #ifndef NXGE_SHARED_REG_SW_SIM 20144961713Sgirish handle = nxgep->npi_reg_handle; 20244961713Sgirish #endif 20344961713Sgirish switch (ctlop) { 20444961713Sgirish case NXGE_CTLOPS_NIUTYPE: 20544961713Sgirish nxge_get_niu_property(dip, (niu_type_t *)result); 20644961713Sgirish return (status); 207a3c5bd6dSspeer 20844961713Sgirish case NXGE_CTLOPS_GET_SHARED_REG: 20944961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM 21044961713Sgirish *(uint64_t *)result = global_dev_ctrl; 21144961713Sgirish return (0); 21244961713Sgirish #else 21344961713Sgirish status = npi_dev_func_sr_sr_get(handle, &sr16); 21444961713Sgirish *(uint16_t *)result = sr16; 21544961713Sgirish NXGE_DEBUG_MSG((NULL, VIR_CTL, 216*52ccf843Smisaki "nxge_cntlops: NXGE_CTLOPS_GET_SHARED_REG")); 21744961713Sgirish return (0); 21844961713Sgirish #endif 21944961713Sgirish 22044961713Sgirish case NXGE_CTLOPS_SET_SHARED_REG_LOCK: 22144961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM 222a3c5bd6dSspeer global_dev_ctrl = *(uint64_t *)arg; 22344961713Sgirish return (0); 22444961713Sgirish #else 22544961713Sgirish status = NPI_FAILURE; 22644961713Sgirish while (status != NPI_SUCCESS) 22744961713Sgirish status = npi_dev_func_sr_lock_enter(handle); 22844961713Sgirish 22944961713Sgirish sr16 = *(uint16_t *)arg; 23044961713Sgirish status = npi_dev_func_sr_sr_set_only(handle, &sr16); 23144961713Sgirish status = npi_dev_func_sr_lock_free(handle); 23244961713Sgirish NXGE_DEBUG_MSG((NULL, VIR_CTL, 233*52ccf843Smisaki "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG")); 23444961713Sgirish return (0); 23544961713Sgirish #endif 23644961713Sgirish 23744961713Sgirish case NXGE_CTLOPS_UPDATE_SHARED_REG: 23844961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM 23944961713Sgirish global_dev_ctrl |= *(uint64_t *)arg; 24044961713Sgirish return (0); 24144961713Sgirish #else 24244961713Sgirish status = NPI_FAILURE; 24344961713Sgirish while (status != NPI_SUCCESS) 24444961713Sgirish status = npi_dev_func_sr_lock_enter(handle); 24544961713Sgirish status = npi_dev_func_sr_sr_get(handle, &sr16); 24644961713Sgirish sr16 |= *(uint16_t *)arg; 24744961713Sgirish status = npi_dev_func_sr_sr_set_only(handle, &sr16); 24844961713Sgirish status = npi_dev_func_sr_lock_free(handle); 24944961713Sgirish NXGE_DEBUG_MSG((NULL, VIR_CTL, 250*52ccf843Smisaki "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG")); 25144961713Sgirish return (0); 25244961713Sgirish #endif 25344961713Sgirish 25444961713Sgirish case NXGE_CTLOPS_CLEAR_BIT_SHARED_REG_UL: 25544961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM 25644961713Sgirish global_dev_ctrl |= *(uint64_t *)arg; 25744961713Sgirish return (0); 25844961713Sgirish #else 25944961713Sgirish status = npi_dev_func_sr_sr_get(handle, &sr16); 26044961713Sgirish cr16 = *(uint16_t *)arg; 26144961713Sgirish sr16 &= ~cr16; 26244961713Sgirish status = npi_dev_func_sr_sr_set_only(handle, &sr16); 26344961713Sgirish NXGE_DEBUG_MSG((NULL, VIR_CTL, 264*52ccf843Smisaki "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG")); 26544961713Sgirish return (0); 26644961713Sgirish #endif 26744961713Sgirish 26844961713Sgirish case NXGE_CTLOPS_CLEAR_BIT_SHARED_REG: 26944961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM 27044961713Sgirish global_dev_ctrl |= *(uint64_t *)arg; 27144961713Sgirish return (0); 27244961713Sgirish #else 27344961713Sgirish status = NPI_FAILURE; 27444961713Sgirish while (status != NPI_SUCCESS) 27544961713Sgirish status = npi_dev_func_sr_lock_enter(handle); 27644961713Sgirish status = npi_dev_func_sr_sr_get(handle, &sr16); 27744961713Sgirish cr16 = *(uint16_t *)arg; 27844961713Sgirish sr16 &= ~cr16; 27944961713Sgirish status = npi_dev_func_sr_sr_set_only(handle, &sr16); 28044961713Sgirish status = npi_dev_func_sr_lock_free(handle); 28144961713Sgirish NXGE_DEBUG_MSG((NULL, VIR_CTL, 282*52ccf843Smisaki "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG")); 28344961713Sgirish return (0); 28444961713Sgirish #endif 28544961713Sgirish 28644961713Sgirish case NXGE_CTLOPS_GET_LOCK_BLOCK: 28744961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM 28844961713Sgirish global_dev_ctrl |= *(uint64_t *)arg; 28944961713Sgirish return (0); 29044961713Sgirish #else 29144961713Sgirish status = NPI_FAILURE; 29244961713Sgirish while (status != NPI_SUCCESS) 293a3c5bd6dSspeer status = npi_dev_func_sr_lock_enter(handle); 29444961713Sgirish NXGE_DEBUG_MSG((NULL, VIR_CTL, 295*52ccf843Smisaki "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_BLOCK")); 29644961713Sgirish return (0); 29744961713Sgirish #endif 29844961713Sgirish case NXGE_CTLOPS_GET_LOCK_TRY: 29944961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM 30044961713Sgirish global_dev_ctrl |= *(uint64_t *)arg; 30144961713Sgirish return (0); 30244961713Sgirish #else 30344961713Sgirish status = npi_dev_func_sr_lock_enter(handle); 30444961713Sgirish NXGE_DEBUG_MSG((NULL, VIR_CTL, 305*52ccf843Smisaki "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_TRY")); 30644961713Sgirish if (status == NPI_SUCCESS) 30744961713Sgirish return (NXGE_OK); 30844961713Sgirish else 30944961713Sgirish return (NXGE_ERROR); 31044961713Sgirish #endif 31144961713Sgirish case NXGE_CTLOPS_FREE_LOCK: 31244961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM 31344961713Sgirish global_dev_ctrl |= *(uint64_t *)arg; 31444961713Sgirish return (0); 31544961713Sgirish #else 31644961713Sgirish status = npi_dev_func_sr_lock_free(handle); 31744961713Sgirish NXGE_DEBUG_MSG((NULL, VIR_CTL, 318*52ccf843Smisaki "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_FREE")); 319a3c5bd6dSspeer if (status == NPI_SUCCESS) 32044961713Sgirish return (NXGE_OK); 32144961713Sgirish else 32244961713Sgirish return (NXGE_ERROR); 32344961713Sgirish #endif 32444961713Sgirish 32544961713Sgirish default: 32644961713Sgirish status = NXGE_ERROR; 32744961713Sgirish } 32844961713Sgirish 32944961713Sgirish return (status); 33044961713Sgirish } 33144961713Sgirish 33244961713Sgirish void 33344961713Sgirish nxge_common_lock_get(p_nxge_t nxgep) 33444961713Sgirish { 33544961713Sgirish uint32_t status = NPI_FAILURE; 33644961713Sgirish npi_handle_t handle; 33744961713Sgirish 33844961713Sgirish #if defined(NXGE_SHARE_REG_SW_SIM) 33944961713Sgirish return; 34044961713Sgirish #endif 34144961713Sgirish handle = nxgep->npi_reg_handle; 34244961713Sgirish while (status != NPI_SUCCESS) 34344961713Sgirish status = npi_dev_func_sr_lock_enter(handle); 34444961713Sgirish } 34544961713Sgirish 34644961713Sgirish void 34744961713Sgirish nxge_common_lock_free(p_nxge_t nxgep) 34844961713Sgirish { 34944961713Sgirish npi_handle_t handle; 350a3c5bd6dSspeer 35144961713Sgirish #if defined(NXGE_SHARE_REG_SW_SIM) 35244961713Sgirish return; 35344961713Sgirish #endif 35444961713Sgirish handle = nxgep->npi_reg_handle; 35544961713Sgirish (void) npi_dev_func_sr_lock_free(handle); 35644961713Sgirish } 35744961713Sgirish 35856d930aeSspeer 35944961713Sgirish static void 36044961713Sgirish nxge_get_niu_property(dev_info_t *dip, niu_type_t *niu_type) 36144961713Sgirish { 362a3c5bd6dSspeer uchar_t *prop_val; 363a3c5bd6dSspeer uint_t prop_len; 36444961713Sgirish 36559ac0c16Sdavemq *niu_type = NIU_TYPE_NONE; 36644961713Sgirish if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, 367*52ccf843Smisaki "niu-type", (uchar_t **)&prop_val, 368*52ccf843Smisaki &prop_len) == DDI_PROP_SUCCESS) { 36944961713Sgirish if (strncmp("niu", (caddr_t)prop_val, (size_t)prop_len) == 0) { 37044961713Sgirish *niu_type = N2_NIU; 37144961713Sgirish } 37244961713Sgirish ddi_prop_free(prop_val); 37344961713Sgirish } 37444961713Sgirish } 37544961713Sgirish 37644961713Sgirish static config_token_t 37744961713Sgirish nxge_get_config_token(char *prop) 37844961713Sgirish { 37944961713Sgirish config_token_t token = DEFAULT; 380a3c5bd6dSspeer 38144961713Sgirish while (token < CONFIG_TOKEN_NONE) { 38244961713Sgirish if (strncmp(prop, token_names[token], 4) == 0) 38344961713Sgirish break; 38444961713Sgirish token++; 38544961713Sgirish } 38644961713Sgirish return (token); 38744961713Sgirish } 38844961713Sgirish 38944961713Sgirish /* per port */ 39044961713Sgirish 39144961713Sgirish static nxge_status_t 39244961713Sgirish nxge_update_rxdma_grp_properties(p_nxge_t nxgep, config_token_t token, 393a3c5bd6dSspeer dev_info_t *s_dip[]) 39444961713Sgirish { 39544961713Sgirish nxge_status_t status = NXGE_OK; 39644961713Sgirish int ddi_status; 39744961713Sgirish int num_ports = nxgep->nports; 39844961713Sgirish int port, bits, j; 39944961713Sgirish uint8_t start_grp = 0, num_grps = 0; 40044961713Sgirish p_nxge_param_t param_arr; 40144961713Sgirish uint32_t grp_bitmap[MAX_SIBLINGS]; 40244961713Sgirish int custom_start_grp[MAX_SIBLINGS]; 40344961713Sgirish int custom_num_grp[MAX_SIBLINGS]; 40444961713Sgirish uint8_t bad_config = B_FALSE; 40544961713Sgirish char *start_prop, *num_prop, *cfg_prop; 40644961713Sgirish 40744961713Sgirish start_grp = 0; 40844961713Sgirish param_arr = nxgep->param_arr; 40944961713Sgirish start_prop = param_arr[param_rdc_grps_start].fcode_name; 41044961713Sgirish num_prop = param_arr[param_rx_rdc_grps].fcode_name; 41144961713Sgirish 41244961713Sgirish switch (token) { 413a3c5bd6dSspeer case FAIR: 414a3c5bd6dSspeer cfg_prop = "fair"; 415a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 416a3c5bd6dSspeer custom_num_grp[port] = 417*52ccf843Smisaki (num_ports == 4) ? 418*52ccf843Smisaki p4_rdcgrp_fair[port] : 419*52ccf843Smisaki p2_rdcgrp_fair[port]; 420a3c5bd6dSspeer custom_start_grp[port] = start_grp; 421a3c5bd6dSspeer start_grp += custom_num_grp[port]; 422a3c5bd6dSspeer } 42344961713Sgirish break; 42444961713Sgirish 425a3c5bd6dSspeer case EQUAL: 426a3c5bd6dSspeer cfg_prop = "equal"; 427a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 428a3c5bd6dSspeer custom_num_grp[port] = 429*52ccf843Smisaki (num_ports == 4) ? 430*52ccf843Smisaki p4_rdcgrp_equal[port] : 431*52ccf843Smisaki p2_rdcgrp_equal[port]; 432a3c5bd6dSspeer custom_start_grp[port] = start_grp; 433a3c5bd6dSspeer start_grp += custom_num_grp[port]; 434a3c5bd6dSspeer } 435a3c5bd6dSspeer break; 43644961713Sgirish 43744961713Sgirish 438a3c5bd6dSspeer case CLASSIFY: 439a3c5bd6dSspeer cfg_prop = "classify"; 440a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 441a3c5bd6dSspeer custom_num_grp[port] = (num_ports == 4) ? 442*52ccf843Smisaki p4_rdcgrp_cls[port] : p2_rdcgrp_cls[port]; 443a3c5bd6dSspeer custom_start_grp[port] = start_grp; 444a3c5bd6dSspeer start_grp += custom_num_grp[port]; 445a3c5bd6dSspeer } 446a3c5bd6dSspeer break; 44744961713Sgirish 448a3c5bd6dSspeer case CUSTOM: 449a3c5bd6dSspeer cfg_prop = "custom"; 450a3c5bd6dSspeer /* See if it is good config */ 451a3c5bd6dSspeer num_grps = 0; 452a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 453a3c5bd6dSspeer custom_start_grp[port] = 454*52ccf843Smisaki ddi_prop_get_int(DDI_DEV_T_NONE, s_dip[port], 455*52ccf843Smisaki DDI_PROP_DONTPASS, start_prop, -1); 456a3c5bd6dSspeer if ((custom_start_grp[port] == -1) || 457*52ccf843Smisaki (custom_start_grp[port] >= 458*52ccf843Smisaki NXGE_MAX_RDC_GRPS)) { 459a3c5bd6dSspeer bad_config = B_TRUE; 460a3c5bd6dSspeer break; 461a3c5bd6dSspeer } 462a3c5bd6dSspeer custom_num_grp[port] = ddi_prop_get_int( 463*52ccf843Smisaki DDI_DEV_T_NONE, 464*52ccf843Smisaki s_dip[port], 465*52ccf843Smisaki DDI_PROP_DONTPASS, 466*52ccf843Smisaki num_prop, -1); 467a3c5bd6dSspeer 468a3c5bd6dSspeer if ((custom_num_grp[port] == -1) || 469*52ccf843Smisaki (custom_num_grp[port] > 470*52ccf843Smisaki NXGE_MAX_RDC_GRPS) || 471*52ccf843Smisaki ((custom_num_grp[port] + 472*52ccf843Smisaki custom_start_grp[port]) >= 473*52ccf843Smisaki NXGE_MAX_RDC_GRPS)) { 474a3c5bd6dSspeer bad_config = B_TRUE; 475a3c5bd6dSspeer break; 476a3c5bd6dSspeer } 477a3c5bd6dSspeer num_grps += custom_num_grp[port]; 478a3c5bd6dSspeer if (num_grps > NXGE_MAX_RDC_GRPS) { 479a3c5bd6dSspeer bad_config = B_TRUE; 480a3c5bd6dSspeer break; 481a3c5bd6dSspeer } 482a3c5bd6dSspeer grp_bitmap[port] = 0; 483a3c5bd6dSspeer for (bits = 0; 484*52ccf843Smisaki bits < custom_num_grp[port]; 485*52ccf843Smisaki bits++) { 486a3c5bd6dSspeer grp_bitmap[port] |= 487*52ccf843Smisaki (1 << (bits + custom_start_grp[port])); 48844961713Sgirish } 48944961713Sgirish 490a3c5bd6dSspeer } 49144961713Sgirish 492a3c5bd6dSspeer if (bad_config == B_FALSE) { 493a3c5bd6dSspeer /* check for overlap */ 494a3c5bd6dSspeer for (port = 0; port < num_ports - 1; port++) { 495a3c5bd6dSspeer for (j = port + 1; j < num_ports; j++) { 496a3c5bd6dSspeer if (grp_bitmap[port] & 497*52ccf843Smisaki grp_bitmap[j]) { 498a3c5bd6dSspeer bad_config = B_TRUE; 499a3c5bd6dSspeer break; 500a3c5bd6dSspeer } 50144961713Sgirish } 502a3c5bd6dSspeer if (bad_config == B_TRUE) 503a3c5bd6dSspeer break; 50444961713Sgirish } 505a3c5bd6dSspeer } 506a3c5bd6dSspeer if (bad_config == B_TRUE) { 507a3c5bd6dSspeer /* use default config */ 50844961713Sgirish for (port = 0; port < num_ports; port++) { 509a3c5bd6dSspeer custom_num_grp[port] = 510*52ccf843Smisaki (num_ports == 4) ? 511*52ccf843Smisaki p4_rx_fair[port] : p2_rx_fair[port]; 51244961713Sgirish custom_start_grp[port] = start_grp; 51344961713Sgirish start_grp += custom_num_grp[port]; 51444961713Sgirish } 515a3c5bd6dSspeer } 516a3c5bd6dSspeer break; 517a3c5bd6dSspeer 518a3c5bd6dSspeer default: 519a3c5bd6dSspeer /* use default config */ 520a3c5bd6dSspeer cfg_prop = "fair"; 521a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 522a3c5bd6dSspeer custom_num_grp[port] = (num_ports == 4) ? 523*52ccf843Smisaki p4_rx_fair[port] : p2_rx_fair[port]; 524a3c5bd6dSspeer custom_start_grp[port] = start_grp; 525a3c5bd6dSspeer start_grp += custom_num_grp[port]; 526a3c5bd6dSspeer } 527a3c5bd6dSspeer break; 52844961713Sgirish } 52944961713Sgirish 530a3c5bd6dSspeer /* Now Update the rx properties */ 53144961713Sgirish for (port = 0; port < num_ports; port++) { 53244961713Sgirish ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port], 533*52ccf843Smisaki "rxdma-grp-cfg", cfg_prop); 53444961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) { 53544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 536*52ccf843Smisaki " property %s not updating", 537*52ccf843Smisaki cfg_prop)); 53844961713Sgirish status |= NXGE_DDI_FAILED; 53944961713Sgirish } 54044961713Sgirish ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 541*52ccf843Smisaki num_prop, custom_num_grp[port]); 54244961713Sgirish 54344961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) { 54444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 545*52ccf843Smisaki " property %s not updating", 546*52ccf843Smisaki num_prop)); 54744961713Sgirish status |= NXGE_DDI_FAILED; 54844961713Sgirish } 54944961713Sgirish ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 550*52ccf843Smisaki start_prop, custom_start_grp[port]); 55144961713Sgirish 55244961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) { 55344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 554*52ccf843Smisaki " property %s not updating", 555*52ccf843Smisaki start_prop)); 55644961713Sgirish status |= NXGE_DDI_FAILED; 55744961713Sgirish } 55844961713Sgirish } 55944961713Sgirish if (status & NXGE_DDI_FAILED) 56044961713Sgirish status |= NXGE_ERROR; 56144961713Sgirish 56244961713Sgirish return (status); 56344961713Sgirish } 56444961713Sgirish 56544961713Sgirish static nxge_status_t 56644961713Sgirish nxge_update_rxdma_properties(p_nxge_t nxgep, config_token_t token, 567a3c5bd6dSspeer dev_info_t *s_dip[]) 56844961713Sgirish { 56944961713Sgirish nxge_status_t status = NXGE_OK; 57044961713Sgirish int ddi_status; 57144961713Sgirish int num_ports = nxgep->nports; 57244961713Sgirish int port, bits, j; 57344961713Sgirish uint8_t start_rdc = 0, num_rdc = 0; 57444961713Sgirish p_nxge_param_t param_arr; 57544961713Sgirish uint32_t rdc_bitmap[MAX_SIBLINGS]; 57644961713Sgirish int custom_start_rdc[MAX_SIBLINGS]; 57744961713Sgirish int custom_num_rdc[MAX_SIBLINGS]; 57844961713Sgirish uint8_t bad_config = B_FALSE; 57944961713Sgirish int *prop_val; 58044961713Sgirish uint_t prop_len; 58144961713Sgirish char *start_rdc_prop, *num_rdc_prop, *cfg_prop; 58244961713Sgirish 58344961713Sgirish start_rdc = 0; 58444961713Sgirish param_arr = nxgep->param_arr; 58544961713Sgirish start_rdc_prop = param_arr[param_rxdma_channels_begin].fcode_name; 58644961713Sgirish num_rdc_prop = param_arr[param_rxdma_channels].fcode_name; 58744961713Sgirish 58844961713Sgirish switch (token) { 589a3c5bd6dSspeer case FAIR: 590a3c5bd6dSspeer cfg_prop = "fair"; 591a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 592a3c5bd6dSspeer custom_num_rdc[port] = (num_ports == 4) ? 593*52ccf843Smisaki p4_rx_fair[port] : p2_rx_fair[port]; 594a3c5bd6dSspeer custom_start_rdc[port] = start_rdc; 595a3c5bd6dSspeer start_rdc += custom_num_rdc[port]; 596a3c5bd6dSspeer } 597a3c5bd6dSspeer break; 59844961713Sgirish 599a3c5bd6dSspeer case EQUAL: 600a3c5bd6dSspeer cfg_prop = "equal"; 601a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 602a3c5bd6dSspeer custom_num_rdc[port] = (num_ports == 4) ? 603*52ccf843Smisaki p4_rx_equal[port] : 604*52ccf843Smisaki p2_rx_equal[port]; 605a3c5bd6dSspeer custom_start_rdc[port] = start_rdc; 606a3c5bd6dSspeer start_rdc += custom_num_rdc[port]; 607a3c5bd6dSspeer } 60844961713Sgirish break; 60944961713Sgirish 610a3c5bd6dSspeer case CUSTOM: 611a3c5bd6dSspeer cfg_prop = "custom"; 612a3c5bd6dSspeer /* See if it is good config */ 613a3c5bd6dSspeer num_rdc = 0; 614a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 615a3c5bd6dSspeer ddi_status = ddi_prop_lookup_int_array( 616*52ccf843Smisaki DDI_DEV_T_ANY, 617*52ccf843Smisaki s_dip[port], 0, 618*52ccf843Smisaki start_rdc_prop, 619*52ccf843Smisaki &prop_val, 620*52ccf843Smisaki &prop_len); 621a3c5bd6dSspeer if (ddi_status == DDI_SUCCESS) 622a3c5bd6dSspeer custom_start_rdc[port] = *prop_val; 623a3c5bd6dSspeer else { 624a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 625*52ccf843Smisaki " %s custom start port %d" 626*52ccf843Smisaki " read failed ", 627*52ccf843Smisaki " rxdma-cfg", port)); 628a3c5bd6dSspeer bad_config = B_TRUE; 629a3c5bd6dSspeer status |= NXGE_DDI_FAILED; 630a3c5bd6dSspeer } 631a3c5bd6dSspeer if ((custom_start_rdc[port] == -1) || 632*52ccf843Smisaki (custom_start_rdc[port] >= 633*52ccf843Smisaki NXGE_MAX_RDCS)) { 634a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 635*52ccf843Smisaki " %s custom start %d" 636*52ccf843Smisaki " out of range %x ", 637*52ccf843Smisaki " rxdma-cfg", 638*52ccf843Smisaki port, 639*52ccf843Smisaki custom_start_rdc[port])); 640a3c5bd6dSspeer bad_config = B_TRUE; 641a3c5bd6dSspeer break; 642a3c5bd6dSspeer } 643a3c5bd6dSspeer ddi_status = ddi_prop_lookup_int_array( 644*52ccf843Smisaki DDI_DEV_T_ANY, 645*52ccf843Smisaki s_dip[port], 646*52ccf843Smisaki 0, 647*52ccf843Smisaki num_rdc_prop, 648*52ccf843Smisaki &prop_val, 649*52ccf843Smisaki &prop_len); 650a3c5bd6dSspeer 651a3c5bd6dSspeer if (ddi_status == DDI_SUCCESS) 652a3c5bd6dSspeer custom_num_rdc[port] = *prop_val; 653a3c5bd6dSspeer else { 654a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 655*52ccf843Smisaki " %s custom num port %d" 656*52ccf843Smisaki " read failed ", 657*52ccf843Smisaki "rxdma-cfg", port)); 658a3c5bd6dSspeer bad_config = B_TRUE; 659a3c5bd6dSspeer status |= NXGE_DDI_FAILED; 66044961713Sgirish } 66144961713Sgirish 662a3c5bd6dSspeer if ((custom_num_rdc[port] == -1) || 663*52ccf843Smisaki (custom_num_rdc[port] > 664*52ccf843Smisaki NXGE_MAX_RDCS) || 665*52ccf843Smisaki ((custom_num_rdc[port] + 666*52ccf843Smisaki custom_start_rdc[port]) > 667*52ccf843Smisaki NXGE_MAX_RDCS)) { 668a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 669*52ccf843Smisaki " %s custom num %d" 670*52ccf843Smisaki " out of range %x ", 671*52ccf843Smisaki " rxdma-cfg", 672*52ccf843Smisaki port, custom_num_rdc[port])); 673a3c5bd6dSspeer bad_config = B_TRUE; 674a3c5bd6dSspeer break; 67544961713Sgirish } 676a3c5bd6dSspeer num_rdc += custom_num_rdc[port]; 677a3c5bd6dSspeer if (num_rdc > NXGE_MAX_RDCS) { 678a3c5bd6dSspeer bad_config = B_TRUE; 679a3c5bd6dSspeer break; 68044961713Sgirish } 681a3c5bd6dSspeer rdc_bitmap[port] = 0; 682a3c5bd6dSspeer for (bits = 0; 683*52ccf843Smisaki bits < custom_num_rdc[port]; bits++) { 684a3c5bd6dSspeer rdc_bitmap[port] |= 685*52ccf843Smisaki (1 << (bits + custom_start_rdc[port])); 686a3c5bd6dSspeer } 687a3c5bd6dSspeer } 68844961713Sgirish 689a3c5bd6dSspeer if (bad_config == B_FALSE) { 690a3c5bd6dSspeer /* check for overlap */ 691a3c5bd6dSspeer for (port = 0; port < num_ports - 1; port++) { 692a3c5bd6dSspeer for (j = port + 1; j < num_ports; j++) { 693a3c5bd6dSspeer if (rdc_bitmap[port] & 694*52ccf843Smisaki rdc_bitmap[j]) { 695a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, 696*52ccf843Smisaki CFG_CTL, 697*52ccf843Smisaki " rxdma-cfg" 698*52ccf843Smisaki " property custom" 699*52ccf843Smisaki " bit overlap" 700*52ccf843Smisaki " %d %d ", 701*52ccf843Smisaki port, j)); 702a3c5bd6dSspeer bad_config = B_TRUE; 703a3c5bd6dSspeer break; 704a3c5bd6dSspeer } 70544961713Sgirish } 706a3c5bd6dSspeer if (bad_config == B_TRUE) 707a3c5bd6dSspeer break; 70844961713Sgirish } 709a3c5bd6dSspeer } 710a3c5bd6dSspeer if (bad_config == B_TRUE) { 711a3c5bd6dSspeer /* use default config */ 712a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 713*52ccf843Smisaki " rxdma-cfg property:" 714*52ccf843Smisaki " bad custom config:" 715*52ccf843Smisaki " use default")); 71644961713Sgirish for (port = 0; port < num_ports; port++) { 717a3c5bd6dSspeer custom_num_rdc[port] = 718*52ccf843Smisaki (num_ports == 4) ? 719*52ccf843Smisaki p4_rx_fair[port] : 720*52ccf843Smisaki p2_rx_fair[port]; 72144961713Sgirish custom_start_rdc[port] = start_rdc; 72244961713Sgirish start_rdc += custom_num_rdc[port]; 72344961713Sgirish } 724a3c5bd6dSspeer } 725a3c5bd6dSspeer break; 726a3c5bd6dSspeer 727a3c5bd6dSspeer default: 728a3c5bd6dSspeer /* use default config */ 729a3c5bd6dSspeer cfg_prop = "fair"; 730a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 731a3c5bd6dSspeer custom_num_rdc[port] = (num_ports == 4) ? 732*52ccf843Smisaki p4_rx_fair[port] : p2_rx_fair[port]; 733a3c5bd6dSspeer custom_start_rdc[port] = start_rdc; 734a3c5bd6dSspeer start_rdc += custom_num_rdc[port]; 735a3c5bd6dSspeer } 736a3c5bd6dSspeer break; 73744961713Sgirish } 73844961713Sgirish 739a3c5bd6dSspeer /* Now Update the rx properties */ 74044961713Sgirish for (port = 0; port < num_ports; port++) { 74144961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 742*52ccf843Smisaki " update property rxdma-cfg with %s ", cfg_prop)); 74344961713Sgirish ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port], 744*52ccf843Smisaki "rxdma-cfg", cfg_prop); 74544961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) { 74644961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 747*52ccf843Smisaki " property rxdma-cfg is not updating to %s", 748*52ccf843Smisaki cfg_prop)); 74944961713Sgirish status |= NXGE_DDI_FAILED; 75044961713Sgirish } 75144961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ", 752*52ccf843Smisaki num_rdc_prop, custom_num_rdc[port])); 75344961713Sgirish 75444961713Sgirish ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 755*52ccf843Smisaki num_rdc_prop, custom_num_rdc[port]); 75644961713Sgirish 75744961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) { 75844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 759*52ccf843Smisaki " property %s not updating with %d", 760*52ccf843Smisaki num_rdc_prop, custom_num_rdc[port])); 76144961713Sgirish status |= NXGE_DDI_FAILED; 76244961713Sgirish } 76344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ", 764*52ccf843Smisaki start_rdc_prop, custom_start_rdc[port])); 76544961713Sgirish ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 766*52ccf843Smisaki start_rdc_prop, custom_start_rdc[port]); 76744961713Sgirish 76844961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) { 76944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 770*52ccf843Smisaki " property %s not updating with %d ", 771*52ccf843Smisaki start_rdc_prop, custom_start_rdc[port])); 77244961713Sgirish status |= NXGE_DDI_FAILED; 77344961713Sgirish } 77444961713Sgirish } 77544961713Sgirish if (status & NXGE_DDI_FAILED) 77644961713Sgirish status |= NXGE_ERROR; 77744961713Sgirish return (status); 77844961713Sgirish } 77944961713Sgirish 78044961713Sgirish static nxge_status_t 78144961713Sgirish nxge_update_txdma_properties(p_nxge_t nxgep, config_token_t token, 782a3c5bd6dSspeer dev_info_t *s_dip[]) 78344961713Sgirish { 78444961713Sgirish nxge_status_t status = NXGE_OK; 78544961713Sgirish int ddi_status = DDI_SUCCESS; 78644961713Sgirish int num_ports = nxgep->nports; 78744961713Sgirish int port, bits, j; 78844961713Sgirish uint8_t start_tdc = 0, num_tdc = 0; 78944961713Sgirish p_nxge_param_t param_arr; 79044961713Sgirish uint32_t tdc_bitmap[MAX_SIBLINGS]; 79144961713Sgirish int custom_start_tdc[MAX_SIBLINGS]; 79244961713Sgirish int custom_num_tdc[MAX_SIBLINGS]; 79344961713Sgirish uint8_t bad_config = B_FALSE; 79444961713Sgirish int *prop_val; 79544961713Sgirish uint_t prop_len; 79644961713Sgirish char *start_tdc_prop, *num_tdc_prop, *cfg_prop; 79744961713Sgirish 79844961713Sgirish start_tdc = 0; 79944961713Sgirish param_arr = nxgep->param_arr; 80044961713Sgirish start_tdc_prop = param_arr[param_txdma_channels_begin].fcode_name; 80144961713Sgirish num_tdc_prop = param_arr[param_txdma_channels].fcode_name; 80244961713Sgirish 80344961713Sgirish switch (token) { 804a3c5bd6dSspeer case FAIR: 805a3c5bd6dSspeer cfg_prop = "fair"; 806a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 807a3c5bd6dSspeer custom_num_tdc[port] = (num_ports == 4) ? 808*52ccf843Smisaki p4_tx_fair[port] : p2_tx_fair[port]; 809a3c5bd6dSspeer custom_start_tdc[port] = start_tdc; 810a3c5bd6dSspeer start_tdc += custom_num_tdc[port]; 811a3c5bd6dSspeer } 812a3c5bd6dSspeer break; 81344961713Sgirish 814a3c5bd6dSspeer case EQUAL: 815a3c5bd6dSspeer cfg_prop = "equal"; 816a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 817a3c5bd6dSspeer custom_num_tdc[port] = (num_ports == 4) ? 818*52ccf843Smisaki p4_tx_equal[port] : p2_tx_equal[port]; 819a3c5bd6dSspeer custom_start_tdc[port] = start_tdc; 820a3c5bd6dSspeer start_tdc += custom_num_tdc[port]; 821a3c5bd6dSspeer } 82244961713Sgirish break; 82344961713Sgirish 824a3c5bd6dSspeer case CUSTOM: 825a3c5bd6dSspeer cfg_prop = "custom"; 826a3c5bd6dSspeer /* See if it is good config */ 827a3c5bd6dSspeer num_tdc = 0; 828a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 829a3c5bd6dSspeer ddi_status = ddi_prop_lookup_int_array( 830*52ccf843Smisaki DDI_DEV_T_ANY, s_dip[port], 0, start_tdc_prop, 831*52ccf843Smisaki &prop_val, &prop_len); 832a3c5bd6dSspeer if (ddi_status == DDI_SUCCESS) 833a3c5bd6dSspeer custom_start_tdc[port] = *prop_val; 834a3c5bd6dSspeer else { 835a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 836*52ccf843Smisaki " %s custom start port %d" 837*52ccf843Smisaki " read failed ", " txdma-cfg", port)); 838a3c5bd6dSspeer bad_config = B_TRUE; 839a3c5bd6dSspeer status |= NXGE_DDI_FAILED; 84044961713Sgirish } 84144961713Sgirish 842a3c5bd6dSspeer if ((custom_start_tdc[port] == -1) || 843*52ccf843Smisaki (custom_start_tdc[port] >= 844*52ccf843Smisaki NXGE_MAX_RDCS)) { 845a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 846*52ccf843Smisaki " %s custom start %d" 847*52ccf843Smisaki " out of range %x ", " txdma-cfg", 848*52ccf843Smisaki port, custom_start_tdc[port])); 849a3c5bd6dSspeer bad_config = B_TRUE; 850a3c5bd6dSspeer break; 851a3c5bd6dSspeer } 85244961713Sgirish 853a3c5bd6dSspeer ddi_status = ddi_prop_lookup_int_array( 854*52ccf843Smisaki DDI_DEV_T_ANY, s_dip[port], 0, num_tdc_prop, 855*52ccf843Smisaki &prop_val, &prop_len); 856a3c5bd6dSspeer if (ddi_status == DDI_SUCCESS) 857a3c5bd6dSspeer custom_num_tdc[port] = *prop_val; 858a3c5bd6dSspeer else { 859a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 860*52ccf843Smisaki " %s custom num port %d" 861*52ccf843Smisaki " read failed ", " txdma-cfg", port)); 862a3c5bd6dSspeer bad_config = B_TRUE; 863a3c5bd6dSspeer status |= NXGE_DDI_FAILED; 864a3c5bd6dSspeer } 86544961713Sgirish 866a3c5bd6dSspeer if ((custom_num_tdc[port] == -1) || 867*52ccf843Smisaki (custom_num_tdc[port] > 868*52ccf843Smisaki NXGE_MAX_TDCS) || 869*52ccf843Smisaki ((custom_num_tdc[port] + 870*52ccf843Smisaki custom_start_tdc[port]) > 871*52ccf843Smisaki NXGE_MAX_TDCS)) { 872a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 873*52ccf843Smisaki " %s custom num %d" 874*52ccf843Smisaki " out of range %x ", " rxdma-cfg", 875*52ccf843Smisaki port, custom_num_tdc[port])); 876a3c5bd6dSspeer bad_config = B_TRUE; 877a3c5bd6dSspeer break; 87844961713Sgirish } 879a3c5bd6dSspeer num_tdc += custom_num_tdc[port]; 880a3c5bd6dSspeer if (num_tdc > NXGE_MAX_TDCS) { 881a3c5bd6dSspeer bad_config = B_TRUE; 882a3c5bd6dSspeer break; 883a3c5bd6dSspeer } 884a3c5bd6dSspeer tdc_bitmap[port] = 0; 885a3c5bd6dSspeer for (bits = 0; 886*52ccf843Smisaki bits < custom_num_tdc[port]; bits++) { 887a3c5bd6dSspeer tdc_bitmap[port] |= 888*52ccf843Smisaki (1 << 889*52ccf843Smisaki (bits + custom_start_tdc[port])); 89044961713Sgirish } 89144961713Sgirish 892a3c5bd6dSspeer } 893a3c5bd6dSspeer 894a3c5bd6dSspeer if (bad_config == B_FALSE) { 895a3c5bd6dSspeer /* check for overlap */ 896a3c5bd6dSspeer for (port = 0; port < num_ports - 1; port++) { 897a3c5bd6dSspeer for (j = port + 1; j < num_ports; j++) { 898a3c5bd6dSspeer if (tdc_bitmap[port] & 899*52ccf843Smisaki tdc_bitmap[j]) { 900a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 901*52ccf843Smisaki " rxdma-cfg" 902*52ccf843Smisaki " property custom" 903*52ccf843Smisaki " bit overlap" 904*52ccf843Smisaki " %d %d ", 905*52ccf843Smisaki port, j)); 906a3c5bd6dSspeer bad_config = B_TRUE; 907a3c5bd6dSspeer break; 908a3c5bd6dSspeer } 90944961713Sgirish } 910a3c5bd6dSspeer if (bad_config == B_TRUE) 911a3c5bd6dSspeer break; 91244961713Sgirish } 913a3c5bd6dSspeer } 914a3c5bd6dSspeer if (bad_config == B_TRUE) { 915a3c5bd6dSspeer /* use default config */ 916a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 917*52ccf843Smisaki " txdma-cfg property:" 918*52ccf843Smisaki " bad custom config:" " use default")); 91944961713Sgirish 92044961713Sgirish for (port = 0; port < num_ports; port++) { 92144961713Sgirish custom_num_tdc[port] = (num_ports == 4) ? 922*52ccf843Smisaki p4_tx_fair[port] : p2_tx_fair[port]; 92344961713Sgirish custom_start_tdc[port] = start_tdc; 92444961713Sgirish start_tdc += custom_num_tdc[port]; 92544961713Sgirish } 926a3c5bd6dSspeer } 927a3c5bd6dSspeer break; 928a3c5bd6dSspeer 929a3c5bd6dSspeer default: 930a3c5bd6dSspeer /* use default config */ 931a3c5bd6dSspeer cfg_prop = "fair"; 932a3c5bd6dSspeer for (port = 0; port < num_ports; port++) { 933a3c5bd6dSspeer custom_num_tdc[port] = (num_ports == 4) ? 934*52ccf843Smisaki p4_tx_fair[port] : p2_tx_fair[port]; 935a3c5bd6dSspeer custom_start_tdc[port] = start_tdc; 936a3c5bd6dSspeer start_tdc += custom_num_tdc[port]; 937a3c5bd6dSspeer } 938a3c5bd6dSspeer break; 93944961713Sgirish } 94044961713Sgirish 941a3c5bd6dSspeer /* Now Update the tx properties */ 94244961713Sgirish for (port = 0; port < num_ports; port++) { 94344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 944*52ccf843Smisaki " update property txdma-cfg with %s ", cfg_prop)); 94544961713Sgirish ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port], 946*52ccf843Smisaki "txdma-cfg", cfg_prop); 94744961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) { 94844961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 949*52ccf843Smisaki " property txdma-cfg is not updating to %s", 950*52ccf843Smisaki cfg_prop)); 95144961713Sgirish status |= NXGE_DDI_FAILED; 95244961713Sgirish } 95344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ", 954*52ccf843Smisaki num_tdc_prop, custom_num_tdc[port])); 95544961713Sgirish 95644961713Sgirish ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 957*52ccf843Smisaki num_tdc_prop, custom_num_tdc[port]); 95844961713Sgirish 95944961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) { 96044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 961*52ccf843Smisaki " property %s not updating with %d", 962*52ccf843Smisaki num_tdc_prop, 963*52ccf843Smisaki custom_num_tdc[port])); 96444961713Sgirish status |= NXGE_DDI_FAILED; 96544961713Sgirish } 96644961713Sgirish 96744961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ", 968*52ccf843Smisaki start_tdc_prop, custom_start_tdc[port])); 96944961713Sgirish 970a3c5bd6dSspeer ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port], 971*52ccf843Smisaki start_tdc_prop, custom_start_tdc[port]); 97244961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) { 97344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 974*52ccf843Smisaki " property %s not updating with %d ", 975*52ccf843Smisaki start_tdc_prop, custom_start_tdc[port])); 97644961713Sgirish status |= NXGE_DDI_FAILED; 97744961713Sgirish } 97844961713Sgirish } 97944961713Sgirish if (status & NXGE_DDI_FAILED) 98044961713Sgirish status |= NXGE_ERROR; 98144961713Sgirish return (status); 98244961713Sgirish } 98344961713Sgirish 98444961713Sgirish static nxge_status_t 98544961713Sgirish nxge_update_cfg_properties(p_nxge_t nxgep, uint32_t flags, 986a3c5bd6dSspeer config_token_t token, dev_info_t *s_dip[]) 98744961713Sgirish { 98844961713Sgirish nxge_status_t status = NXGE_OK; 98944961713Sgirish 99044961713Sgirish switch (flags) { 991a3c5bd6dSspeer case COMMON_TXDMA_CFG: 992a3c5bd6dSspeer if (nxge_dma_obp_props_only == 0) 99344961713Sgirish status = nxge_update_txdma_properties(nxgep, 994*52ccf843Smisaki token, s_dip); 995a3c5bd6dSspeer break; 996a3c5bd6dSspeer case COMMON_RXDMA_CFG: 997a3c5bd6dSspeer if (nxge_dma_obp_props_only == 0) 99844961713Sgirish status = nxge_update_rxdma_properties(nxgep, 999*52ccf843Smisaki token, s_dip); 100044961713Sgirish 1001a3c5bd6dSspeer break; 1002a3c5bd6dSspeer case COMMON_RXDMA_GRP_CFG: 1003a3c5bd6dSspeer status = nxge_update_rxdma_grp_properties(nxgep, 1004*52ccf843Smisaki token, s_dip); 1005a3c5bd6dSspeer break; 1006a3c5bd6dSspeer default: 1007a3c5bd6dSspeer return (NXGE_ERROR); 100844961713Sgirish } 100944961713Sgirish return (status); 101044961713Sgirish } 101144961713Sgirish 101244961713Sgirish /* 101344961713Sgirish * verify consistence. 101444961713Sgirish * (May require publishing the properties on all the ports. 101544961713Sgirish * 101644961713Sgirish * What if properties are published on function 0 device only? 101744961713Sgirish * 101844961713Sgirish * 101944961713Sgirish * rxdma-cfg, txdma-cfg, rxdma-grp-cfg (required ) 102044961713Sgirish * What about class configs? 102144961713Sgirish * 102244961713Sgirish * If consistent, update the property on all the siblings. 102344961713Sgirish * set a flag on hardware shared register 102444961713Sgirish * The rest of the siblings will check the flag 102544961713Sgirish * if the flag is set, they will use the updated property 102644961713Sgirish * without doing any validation. 102744961713Sgirish */ 102844961713Sgirish 102944961713Sgirish nxge_status_t 103044961713Sgirish nxge_cfg_verify_set_classify_prop(p_nxge_t nxgep, char *prop, 1031a3c5bd6dSspeer uint64_t known_cfg, uint32_t override, dev_info_t *c_dip[]) 103244961713Sgirish { 103344961713Sgirish nxge_status_t status = NXGE_OK; 103444961713Sgirish int ddi_status = DDI_SUCCESS; 103544961713Sgirish int i = 0, found = 0, update_prop = B_TRUE; 1036a3c5bd6dSspeer int *cfg_val; 1037a3c5bd6dSspeer uint_t new_value, cfg_value[MAX_SIBLINGS]; 1038a3c5bd6dSspeer uint_t prop_len; 103944961713Sgirish uint_t known_cfg_value; 104044961713Sgirish 104144961713Sgirish known_cfg_value = (uint_t)known_cfg; 104244961713Sgirish 104344961713Sgirish if (override == B_TRUE) { 104444961713Sgirish new_value = known_cfg_value; 104544961713Sgirish for (i = 0; i < nxgep->nports; i++) { 104644961713Sgirish ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, 1047*52ccf843Smisaki c_dip[i], prop, new_value); 104844961713Sgirish #ifdef NXGE_DEBUG_ERROR 104944961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) 105044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1051*52ccf843Smisaki " property %s failed update ", prop)); 105244961713Sgirish #endif 105344961713Sgirish } 105444961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) 105544961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 105644961713Sgirish } 105744961713Sgirish for (i = 0; i < nxgep->nports; i++) { 105844961713Sgirish cfg_value[i] = known_cfg_value; 105944961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, c_dip[i], 0, 1060*52ccf843Smisaki prop, &cfg_val, 1061*52ccf843Smisaki &prop_len) == DDI_PROP_SUCCESS) { 106244961713Sgirish cfg_value[i] = *cfg_val; 106344961713Sgirish ddi_prop_free(cfg_val); 106444961713Sgirish found++; 106544961713Sgirish } 106644961713Sgirish } 106744961713Sgirish 106844961713Sgirish if (found != i) { 106944961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1070*52ccf843Smisaki " property %s not specified on all ports", prop)); 107144961713Sgirish if (found == 0) { 1072a3c5bd6dSspeer /* not specified: Use default */ 107344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1074*52ccf843Smisaki " property %s not specified on any port:" 1075*52ccf843Smisaki " Using default", prop)); 107644961713Sgirish new_value = known_cfg_value; 107744961713Sgirish } else { 1078a3c5bd6dSspeer /* specified on some */ 107944961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1080*52ccf843Smisaki " property %s not specified" 1081*52ccf843Smisaki " on some ports: Using default", prop)); 108244961713Sgirish /* ? use p0 value instead ? */ 108344961713Sgirish new_value = known_cfg_value; 108444961713Sgirish } 108544961713Sgirish } else { 108644961713Sgirish /* check type and consistence */ 108744961713Sgirish /* found on all devices */ 108844961713Sgirish for (i = 1; i < found; i++) { 1089a3c5bd6dSspeer if (cfg_value[i] != cfg_value[i - 1]) { 109044961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1091*52ccf843Smisaki " property %s inconsistent:" 1092*52ccf843Smisaki " Using default", prop)); 109344961713Sgirish new_value = known_cfg_value; 109444961713Sgirish break; 1095a3c5bd6dSspeer } 1096a3c5bd6dSspeer /* 1097a3c5bd6dSspeer * Found on all the ports and consistent. Nothing to 1098a3c5bd6dSspeer * do. 1099a3c5bd6dSspeer */ 110044961713Sgirish update_prop = B_FALSE; 110144961713Sgirish } 110244961713Sgirish } 110344961713Sgirish 110444961713Sgirish if (update_prop == B_TRUE) { 110544961713Sgirish for (i = 0; i < nxgep->nports; i++) { 110644961713Sgirish ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, 1107*52ccf843Smisaki c_dip[i], prop, new_value); 110844961713Sgirish #ifdef NXGE_DEBUG_ERROR 110944961713Sgirish if (ddi_status != DDI_SUCCESS) 111044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1111*52ccf843Smisaki " property %s not updating with %d" 1112*52ccf843Smisaki " Using default", 1113*52ccf843Smisaki prop, new_value)); 111444961713Sgirish #endif 111544961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) 111644961713Sgirish status |= NXGE_DDI_FAILED; 111744961713Sgirish } 111844961713Sgirish } 111944961713Sgirish if (status & NXGE_DDI_FAILED) 112044961713Sgirish status |= NXGE_ERROR; 112144961713Sgirish 112244961713Sgirish return (status); 112344961713Sgirish } 112444961713Sgirish 112544961713Sgirish static uint64_t 1126a3c5bd6dSspeer nxge_class_get_known_cfg(p_nxge_t nxgep, int class_prop, int rx_quick_cfg) 112744961713Sgirish { 1128a3c5bd6dSspeer int start_prop; 112944961713Sgirish uint64_t cfg_value; 113044961713Sgirish p_nxge_param_t param_arr; 113144961713Sgirish 1132a3c5bd6dSspeer param_arr = nxgep->param_arr; 113344961713Sgirish cfg_value = param_arr[class_prop].value; 113444961713Sgirish start_prop = param_h1_init_value; 113544961713Sgirish 113644961713Sgirish /* update the properties per quick config */ 113744961713Sgirish switch (rx_quick_cfg) { 1138a3c5bd6dSspeer case CFG_L3_WEB: 1139a3c5bd6dSspeer case CFG_L3_DISTRIBUTE: 1140a3c5bd6dSspeer cfg_value = nxge_classify_get_cfg_value(nxgep, 1141*52ccf843Smisaki rx_quick_cfg, class_prop - start_prop); 1142a3c5bd6dSspeer break; 1143a3c5bd6dSspeer default: 1144a3c5bd6dSspeer cfg_value = param_arr[class_prop].value; 1145a3c5bd6dSspeer break; 114644961713Sgirish } 114744961713Sgirish return (cfg_value); 114844961713Sgirish } 114944961713Sgirish 115044961713Sgirish static nxge_status_t 115144961713Sgirish nxge_cfg_verify_set_classify(p_nxge_t nxgep, dev_info_t *c_dip[]) 115244961713Sgirish { 115344961713Sgirish nxge_status_t status = NXGE_OK; 1154a3c5bd6dSspeer int rx_quick_cfg, class_prop, start_prop, end_prop; 115544961713Sgirish char *prop_name; 115644961713Sgirish int override = B_TRUE; 115744961713Sgirish uint64_t cfg_value; 115844961713Sgirish p_nxge_param_t param_arr; 1159a3c5bd6dSspeer 116044961713Sgirish param_arr = nxgep->param_arr; 116144961713Sgirish rx_quick_cfg = param_arr[param_rx_quick_cfg].value; 116244961713Sgirish start_prop = param_h1_init_value; 116344961713Sgirish end_prop = param_class_opt_ipv6_sctp; 116444961713Sgirish 1165a3c5bd6dSspeer /* update the properties per quick config */ 116644961713Sgirish if (rx_quick_cfg == CFG_NOT_SPECIFIED) 116744961713Sgirish override = B_FALSE; 1168a3c5bd6dSspeer 1169a3c5bd6dSspeer /* 1170a3c5bd6dSspeer * these parameter affect the classification outcome. 1171a3c5bd6dSspeer * these parameters are used to configure the Flow key and 1172a3c5bd6dSspeer * the TCAM key for each of the IP classes. 117358324dfcSspeer * Included here are also the H1 and H2 initial values 1174a3c5bd6dSspeer * which affect the distribution as well as final hash value 1175a3c5bd6dSspeer * (hence the offset into RDC table and FCRAM bucket location) 1176a3c5bd6dSspeer * 1177a3c5bd6dSspeer */ 1178a3c5bd6dSspeer for (class_prop = start_prop; class_prop <= end_prop; class_prop++) { 117944961713Sgirish prop_name = param_arr[class_prop].fcode_name; 118044961713Sgirish cfg_value = nxge_class_get_known_cfg(nxgep, 1181*52ccf843Smisaki class_prop, rx_quick_cfg); 1182a3c5bd6dSspeer status = nxge_cfg_verify_set_classify_prop(nxgep, prop_name, 1183*52ccf843Smisaki cfg_value, override, c_dip); 118444961713Sgirish } 118544961713Sgirish 1186a3c5bd6dSspeer /* 1187a3c5bd6dSspeer * these properties do not affect the actual classification outcome. 1188a3c5bd6dSspeer * used to enable/disable or tune the fflp hardware 1189a3c5bd6dSspeer * 1190a3c5bd6dSspeer * fcram_access_ratio, tcam_access_ratio, tcam_enable, llc_snap_enable 1191a3c5bd6dSspeer * 1192a3c5bd6dSspeer */ 119344961713Sgirish override = B_FALSE; 119444961713Sgirish for (class_prop = param_fcram_access_ratio; 1195*52ccf843Smisaki class_prop <= param_llc_snap_enable; class_prop++) { 119644961713Sgirish prop_name = param_arr[class_prop].fcode_name; 119744961713Sgirish cfg_value = param_arr[class_prop].value; 119844961713Sgirish status = nxge_cfg_verify_set_classify_prop(nxgep, prop_name, 1199*52ccf843Smisaki cfg_value, override, c_dip); 120044961713Sgirish } 120144961713Sgirish 1202a3c5bd6dSspeer return (status); 120344961713Sgirish } 120444961713Sgirish 120544961713Sgirish nxge_status_t 120644961713Sgirish nxge_cfg_verify_set(p_nxge_t nxgep, uint32_t flag) 120744961713Sgirish { 120844961713Sgirish nxge_status_t status = NXGE_OK; 120944961713Sgirish int i = 0, found = 0; 121044961713Sgirish int num_siblings; 1211a3c5bd6dSspeer dev_info_t *c_dip[MAX_SIBLINGS + 1]; 121244961713Sgirish char *prop_val[MAX_SIBLINGS]; 121344961713Sgirish config_token_t c_token[MAX_SIBLINGS]; 121444961713Sgirish char *prop; 121544961713Sgirish 1216a3c5bd6dSspeer if (nxge_dma_obp_props_only) 121744961713Sgirish return (NXGE_OK); 121844961713Sgirish 121944961713Sgirish num_siblings = 0; 122044961713Sgirish c_dip[num_siblings] = ddi_get_child(nxgep->p_dip); 122144961713Sgirish while (c_dip[num_siblings]) { 122244961713Sgirish c_dip[num_siblings + 1] = 1223*52ccf843Smisaki ddi_get_next_sibling(c_dip[num_siblings]); 122444961713Sgirish num_siblings++; 122544961713Sgirish } 122644961713Sgirish 122744961713Sgirish switch (flag) { 1228a3c5bd6dSspeer case COMMON_TXDMA_CFG: 1229a3c5bd6dSspeer prop = "txdma-cfg"; 1230a3c5bd6dSspeer break; 1231a3c5bd6dSspeer case COMMON_RXDMA_CFG: 1232a3c5bd6dSspeer prop = "rxdma-cfg"; 1233a3c5bd6dSspeer break; 1234a3c5bd6dSspeer case COMMON_RXDMA_GRP_CFG: 1235a3c5bd6dSspeer prop = "rxdma-grp-cfg"; 1236a3c5bd6dSspeer break; 1237a3c5bd6dSspeer case COMMON_CLASS_CFG: 1238a3c5bd6dSspeer status = nxge_cfg_verify_set_classify(nxgep, c_dip); 1239a3c5bd6dSspeer return (status); 1240a3c5bd6dSspeer default: 1241a3c5bd6dSspeer return (NXGE_ERROR); 124244961713Sgirish } 124344961713Sgirish 124444961713Sgirish i = 0; 124544961713Sgirish while (i < num_siblings) { 1246a3c5bd6dSspeer if (ddi_prop_lookup_string(DDI_DEV_T_ANY, c_dip[i], 0, prop, 1247*52ccf843Smisaki (char **)&prop_val[i]) == DDI_PROP_SUCCESS) { 124844961713Sgirish c_token[i] = nxge_get_config_token(prop_val[i]); 124944961713Sgirish ddi_prop_free(prop_val[i]); 125044961713Sgirish found++; 125144961713Sgirish } else 125244961713Sgirish c_token[i] = CONFIG_TOKEN_NONE; 125344961713Sgirish i++; 125444961713Sgirish } 125544961713Sgirish 125644961713Sgirish if (found != i) { 125744961713Sgirish if (found == 0) { 1258a3c5bd6dSspeer /* not specified: Use default */ 125944961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1260*52ccf843Smisaki " property %s not specified on any port:" 1261*52ccf843Smisaki " Using default", prop)); 126244961713Sgirish 126344961713Sgirish status = nxge_update_cfg_properties(nxgep, 1264*52ccf843Smisaki flag, FAIR, c_dip); 126544961713Sgirish return (status); 126644961713Sgirish } else { 126744961713Sgirish /* 1268a3c5bd6dSspeer * if the convention is to use function 0 device then 1269a3c5bd6dSspeer * populate the other devices with this configuration. 127044961713Sgirish * 127144961713Sgirish * The other alternative is to use the default config. 127244961713Sgirish */ 1273a3c5bd6dSspeer /* not specified: Use default */ 127444961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1275*52ccf843Smisaki " property %s not specified on some ports:" 1276*52ccf843Smisaki " Using default", prop)); 127744961713Sgirish status = nxge_update_cfg_properties(nxgep, 1278*52ccf843Smisaki flag, FAIR, c_dip); 127944961713Sgirish return (status); 128044961713Sgirish } 128144961713Sgirish } 128244961713Sgirish 1283a3c5bd6dSspeer /* check type and consistence */ 1284a3c5bd6dSspeer /* found on all devices */ 1285a3c5bd6dSspeer for (i = 1; i < found; i++) { 1286a3c5bd6dSspeer if (c_token[i] != c_token[i - 1]) { 128744961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1288*52ccf843Smisaki " property %s inconsistent:" 1289*52ccf843Smisaki " Using default", prop)); 129044961713Sgirish status = nxge_update_cfg_properties(nxgep, 1291*52ccf843Smisaki flag, FAIR, c_dip); 129244961713Sgirish return (status); 129344961713Sgirish } 129444961713Sgirish } 129544961713Sgirish 1296a3c5bd6dSspeer /* 1297a3c5bd6dSspeer * Found on all the ports check if it is custom configuration. if 1298a3c5bd6dSspeer * custom, then verify consistence 1299a3c5bd6dSspeer * 1300a3c5bd6dSspeer * finally create soft properties 1301a3c5bd6dSspeer */ 1302a3c5bd6dSspeer status = nxge_update_cfg_properties(nxgep, flag, c_token[0], c_dip); 130344961713Sgirish return (status); 130444961713Sgirish } 130544961713Sgirish 130644961713Sgirish nxge_status_t 130744961713Sgirish nxge_cfg_verify_set_quick_config(p_nxge_t nxgep) 130844961713Sgirish { 130944961713Sgirish nxge_status_t status = NXGE_OK; 131044961713Sgirish int ddi_status = DDI_SUCCESS; 131144961713Sgirish char *prop_val; 131244961713Sgirish char *rx_prop; 131344961713Sgirish char *prop; 131444961713Sgirish uint32_t cfg_value = CFG_NOT_SPECIFIED; 131544961713Sgirish p_nxge_param_t param_arr; 131644961713Sgirish 1317a3c5bd6dSspeer param_arr = nxgep->param_arr; 131844961713Sgirish rx_prop = param_arr[param_rx_quick_cfg].fcode_name; 131944961713Sgirish 132044961713Sgirish prop = "rx-quick-cfg"; 132144961713Sgirish 1322a3c5bd6dSspeer /* 1323a3c5bd6dSspeer * good value are 1324a3c5bd6dSspeer * 1325a3c5bd6dSspeer * "web-server" "generic-server" "l3-classify" "flow-classify" 1326a3c5bd6dSspeer */ 132744961713Sgirish if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0, 1328*52ccf843Smisaki prop, (char **)&prop_val) != DDI_PROP_SUCCESS) { 132944961713Sgirish NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1330*52ccf843Smisaki " property %s not specified: using default ", prop)); 133144961713Sgirish cfg_value = CFG_NOT_SPECIFIED; 133244961713Sgirish } else { 133344961713Sgirish cfg_value = CFG_L3_DISTRIBUTE; 133444961713Sgirish if (strncmp("web-server", (caddr_t)prop_val, 8) == 0) { 133544961713Sgirish cfg_value = CFG_L3_WEB; 133644961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1337*52ccf843Smisaki " %s: web server ", prop)); 133844961713Sgirish } 133944961713Sgirish if (strncmp("generic-server", (caddr_t)prop_val, 8) == 0) { 134044961713Sgirish cfg_value = CFG_L3_DISTRIBUTE; 134144961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 1342*52ccf843Smisaki " %s: distribute ", prop)); 134344961713Sgirish } 134444961713Sgirish /* more */ 134544961713Sgirish ddi_prop_free(prop_val); 134644961713Sgirish } 134744961713Sgirish 134844961713Sgirish ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 1349*52ccf843Smisaki rx_prop, cfg_value); 135044961713Sgirish if (ddi_status != DDI_PROP_SUCCESS) 135144961713Sgirish status |= NXGE_DDI_FAILED; 135244961713Sgirish 1353a3c5bd6dSspeer /* now handle specified cases: */ 135444961713Sgirish if (status & NXGE_DDI_FAILED) 135544961713Sgirish status |= NXGE_ERROR; 135644961713Sgirish return (status); 135744961713Sgirish } 135844961713Sgirish 135900161856Syc /* 136000161856Syc * Device properties adv-autoneg-cap etc are defined by FWARC 136100161856Syc * http://sac.sfbay/FWARC/2002/345/20020610_asif.haswarey 136200161856Syc */ 136344961713Sgirish static void 136444961713Sgirish nxge_use_cfg_link_cfg(p_nxge_t nxgep) 136544961713Sgirish { 136644961713Sgirish int *prop_val; 136744961713Sgirish uint_t prop_len; 136844961713Sgirish dev_info_t *dip; 136944961713Sgirish int speed; 137044961713Sgirish int duplex; 137144961713Sgirish int adv_autoneg_cap; 137244961713Sgirish int adv_10gfdx_cap; 137344961713Sgirish int adv_10ghdx_cap; 137444961713Sgirish int adv_1000fdx_cap; 137544961713Sgirish int adv_1000hdx_cap; 137644961713Sgirish int adv_100fdx_cap; 137744961713Sgirish int adv_100hdx_cap; 137844961713Sgirish int adv_10fdx_cap; 137944961713Sgirish int adv_10hdx_cap; 138044961713Sgirish int status = DDI_SUCCESS; 138144961713Sgirish 138244961713Sgirish dip = nxgep->dip; 1383a3c5bd6dSspeer 1384a3c5bd6dSspeer /* 1385a3c5bd6dSspeer * first find out the card type and the supported link speeds and 1386a3c5bd6dSspeer * features 1387a3c5bd6dSspeer */ 1388a3c5bd6dSspeer /* add code for card type */ 138944961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-autoneg-cap", 1390*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 139144961713Sgirish ddi_prop_free(prop_val); 1392a3c5bd6dSspeer return; 139344961713Sgirish } 1394a3c5bd6dSspeer 139544961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10gfdx-cap", 1396*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 139744961713Sgirish ddi_prop_free(prop_val); 1398a3c5bd6dSspeer return; 139944961713Sgirish } 1400a3c5bd6dSspeer 140144961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000hdx-cap", 1402*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 140344961713Sgirish ddi_prop_free(prop_val); 1404a3c5bd6dSspeer return; 140544961713Sgirish } 1406a3c5bd6dSspeer 140744961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000fdx-cap", 1408*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 140944961713Sgirish ddi_prop_free(prop_val); 1410a3c5bd6dSspeer return; 141144961713Sgirish } 1412a3c5bd6dSspeer 141344961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-100fdx-cap", 1414*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 141544961713Sgirish ddi_prop_free(prop_val); 1416a3c5bd6dSspeer return; 141744961713Sgirish } 1418a3c5bd6dSspeer 141944961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-100hdx-cap", 1420*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 142144961713Sgirish ddi_prop_free(prop_val); 1422a3c5bd6dSspeer return; 142344961713Sgirish } 1424a3c5bd6dSspeer 142544961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10fdx-cap", 1426*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 142744961713Sgirish ddi_prop_free(prop_val); 1428a3c5bd6dSspeer return; 142944961713Sgirish } 1430a3c5bd6dSspeer 143144961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10hdx-cap", 1432*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 143344961713Sgirish ddi_prop_free(prop_val); 1434a3c5bd6dSspeer return; 143544961713Sgirish } 143644961713Sgirish 143744961713Sgirish if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, "speed", 1438*52ccf843Smisaki (uchar_t **)&prop_val, &prop_len) == DDI_PROP_SUCCESS) { 143944961713Sgirish if (strncmp("10000", (caddr_t)prop_val, 1440*52ccf843Smisaki (size_t)prop_len) == 0) { 144144961713Sgirish speed = 10000; 144244961713Sgirish } else if (strncmp("1000", (caddr_t)prop_val, 1443*52ccf843Smisaki (size_t)prop_len) == 0) { 144444961713Sgirish speed = 1000; 144544961713Sgirish } else if (strncmp("100", (caddr_t)prop_val, 1446*52ccf843Smisaki (size_t)prop_len) == 0) { 144744961713Sgirish speed = 100; 144844961713Sgirish } else if (strncmp("10", (caddr_t)prop_val, 1449*52ccf843Smisaki (size_t)prop_len) == 0) { 145044961713Sgirish speed = 10; 145144961713Sgirish } else if (strncmp("auto", (caddr_t)prop_val, 1452*52ccf843Smisaki (size_t)prop_len) == 0) { 145344961713Sgirish speed = 0; 145444961713Sgirish } else { 145544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_NOTE, 1456*52ccf843Smisaki "speed property is invalid reverting to auto")); 145744961713Sgirish speed = 0; 145844961713Sgirish } 145944961713Sgirish ddi_prop_free(prop_val); 146044961713Sgirish } else 146144961713Sgirish speed = 0; 146244961713Sgirish 146344961713Sgirish if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, "duplex", 1464*52ccf843Smisaki (uchar_t **)&prop_val, &prop_len) == DDI_PROP_SUCCESS) { 146544961713Sgirish if (strncmp("full", (caddr_t)prop_val, 1466*52ccf843Smisaki (size_t)prop_len) == 0) { 146744961713Sgirish duplex = 2; 146844961713Sgirish } else if (strncmp("half", (caddr_t)prop_val, 1469*52ccf843Smisaki (size_t)prop_len) == 0) { 147044961713Sgirish duplex = 1; 147144961713Sgirish } else if (strncmp("auto", (caddr_t)prop_val, 1472*52ccf843Smisaki (size_t)prop_len) == 0) { 147344961713Sgirish duplex = 0; 147444961713Sgirish } else { 147544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_NOTE, 1476*52ccf843Smisaki "duplex property is invalid" 1477*52ccf843Smisaki " reverting to auto")); 147844961713Sgirish duplex = 0; 147944961713Sgirish } 148044961713Sgirish ddi_prop_free(prop_val); 148144961713Sgirish } else 148244961713Sgirish duplex = 0; 148344961713Sgirish 148400161856Syc /* speed == 0 or duplex == 0 means auto negotiation. */ 148544961713Sgirish adv_autoneg_cap = (speed == 0) || (duplex == 0); 148644961713Sgirish if (adv_autoneg_cap == 0) { 148744961713Sgirish adv_10gfdx_cap = ((speed == 10000) && (duplex == 2)); 148844961713Sgirish adv_10ghdx_cap = adv_10gfdx_cap; 148944961713Sgirish adv_10ghdx_cap |= ((speed == 10000) && (duplex == 1)); 149044961713Sgirish adv_1000fdx_cap = adv_10ghdx_cap; 149144961713Sgirish adv_1000fdx_cap |= ((speed == 1000) && (duplex == 2)); 149244961713Sgirish adv_1000hdx_cap = adv_1000fdx_cap; 149344961713Sgirish adv_1000hdx_cap |= ((speed == 1000) && (duplex == 1)); 149444961713Sgirish adv_100fdx_cap = adv_1000hdx_cap; 149544961713Sgirish adv_100fdx_cap |= ((speed == 100) && (duplex == 2)); 149644961713Sgirish adv_100hdx_cap = adv_100fdx_cap; 149744961713Sgirish adv_100hdx_cap |= ((speed == 100) && (duplex == 1)); 149844961713Sgirish adv_10fdx_cap = adv_100hdx_cap; 149944961713Sgirish adv_10fdx_cap |= ((speed == 10) && (duplex == 2)); 150044961713Sgirish adv_10hdx_cap = adv_10fdx_cap; 150144961713Sgirish adv_10hdx_cap |= ((speed == 10) && (duplex == 1)); 150244961713Sgirish } else if (speed == 0) { 150344961713Sgirish adv_10gfdx_cap = (duplex == 2); 150444961713Sgirish adv_10ghdx_cap = (duplex == 1); 150544961713Sgirish adv_1000fdx_cap = (duplex == 2); 150644961713Sgirish adv_1000hdx_cap = (duplex == 1); 150744961713Sgirish adv_100fdx_cap = (duplex == 2); 150844961713Sgirish adv_100hdx_cap = (duplex == 1); 150944961713Sgirish adv_10fdx_cap = (duplex == 2); 151044961713Sgirish adv_10hdx_cap = (duplex == 1); 151144961713Sgirish } 151244961713Sgirish if (duplex == 0) { 151344961713Sgirish adv_10gfdx_cap = (speed == 0); 151444961713Sgirish adv_10gfdx_cap |= (speed == 10000); 151544961713Sgirish adv_10ghdx_cap = adv_10gfdx_cap; 151644961713Sgirish adv_10ghdx_cap |= (speed == 10000); 151744961713Sgirish adv_1000fdx_cap = adv_10ghdx_cap; 151844961713Sgirish adv_1000fdx_cap |= (speed == 1000); 151944961713Sgirish adv_1000hdx_cap = adv_1000fdx_cap; 152044961713Sgirish adv_1000hdx_cap |= (speed == 1000); 152144961713Sgirish adv_100fdx_cap = adv_1000hdx_cap; 152244961713Sgirish adv_100fdx_cap |= (speed == 100); 152344961713Sgirish adv_100hdx_cap = adv_100fdx_cap; 152444961713Sgirish adv_100hdx_cap |= (speed == 100); 152544961713Sgirish adv_10fdx_cap = adv_100hdx_cap; 152644961713Sgirish adv_10fdx_cap |= (speed == 10); 152744961713Sgirish adv_10hdx_cap = adv_10fdx_cap; 152844961713Sgirish adv_10hdx_cap |= (speed == 10); 152944961713Sgirish } 153044961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1531*52ccf843Smisaki "adv-autoneg-cap", &adv_autoneg_cap, 1); 153244961713Sgirish if (status) 1533a3c5bd6dSspeer return; 153444961713Sgirish 153544961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1536*52ccf843Smisaki "adv-10gfdx-cap", &adv_10gfdx_cap, 1); 153744961713Sgirish if (status) 153844961713Sgirish goto nxge_map_myargs_to_gmii_fail1; 153944961713Sgirish 154044961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1541*52ccf843Smisaki "adv-10ghdx-cap", &adv_10ghdx_cap, 1); 154244961713Sgirish if (status) 154344961713Sgirish goto nxge_map_myargs_to_gmii_fail2; 154444961713Sgirish 154544961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1546*52ccf843Smisaki "adv-1000fdx-cap", &adv_1000fdx_cap, 1); 154744961713Sgirish if (status) 154844961713Sgirish goto nxge_map_myargs_to_gmii_fail3; 154944961713Sgirish 155044961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1551*52ccf843Smisaki "adv-1000hdx-cap", &adv_1000hdx_cap, 1); 155244961713Sgirish if (status) 155344961713Sgirish goto nxge_map_myargs_to_gmii_fail4; 155444961713Sgirish 155544961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1556*52ccf843Smisaki "adv-100fdx-cap", &adv_100fdx_cap, 1); 155744961713Sgirish if (status) 155844961713Sgirish goto nxge_map_myargs_to_gmii_fail5; 155944961713Sgirish 156044961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1561*52ccf843Smisaki "adv-100hdx-cap", &adv_100hdx_cap, 1); 156244961713Sgirish if (status) 156344961713Sgirish goto nxge_map_myargs_to_gmii_fail6; 156444961713Sgirish 156544961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1566*52ccf843Smisaki "adv-10fdx-cap", &adv_10fdx_cap, 1); 156744961713Sgirish if (status) 156844961713Sgirish goto nxge_map_myargs_to_gmii_fail7; 156944961713Sgirish 157044961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1571*52ccf843Smisaki "adv-10hdx-cap", &adv_10hdx_cap, 1); 157244961713Sgirish if (status) 157344961713Sgirish goto nxge_map_myargs_to_gmii_fail8; 157444961713Sgirish 1575a3c5bd6dSspeer return; 157644961713Sgirish 157744961713Sgirish nxge_map_myargs_to_gmii_fail9: 157844961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10hdx-cap"); 157944961713Sgirish 158044961713Sgirish nxge_map_myargs_to_gmii_fail8: 158144961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10fdx-cap"); 158244961713Sgirish 158344961713Sgirish nxge_map_myargs_to_gmii_fail7: 158444961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-100hdx-cap"); 158544961713Sgirish 158644961713Sgirish nxge_map_myargs_to_gmii_fail6: 158744961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-100fdx-cap"); 158844961713Sgirish 158944961713Sgirish nxge_map_myargs_to_gmii_fail5: 159044961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-1000hdx-cap"); 159144961713Sgirish 159244961713Sgirish nxge_map_myargs_to_gmii_fail4: 159344961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-1000fdx-cap"); 159444961713Sgirish 159544961713Sgirish nxge_map_myargs_to_gmii_fail3: 159644961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10ghdx-cap"); 159744961713Sgirish 159844961713Sgirish nxge_map_myargs_to_gmii_fail2: 159944961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10gfdx-cap"); 160044961713Sgirish 160144961713Sgirish nxge_map_myargs_to_gmii_fail1: 160244961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-autoneg-cap"); 160344961713Sgirish } 160444961713Sgirish 160544961713Sgirish nxge_status_t 160644961713Sgirish nxge_get_config_properties(p_nxge_t nxgep) 160744961713Sgirish { 1608a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 1609a3c5bd6dSspeer p_nxge_hw_list_t hw_p; 161044961713Sgirish 161144961713Sgirish NXGE_DEBUG_MSG((nxgep, VPD_CTL, " ==> nxge_get_config_properties")); 161244961713Sgirish 161344961713Sgirish if ((hw_p = nxgep->nxge_hw_p) == NULL) { 161444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1615*52ccf843Smisaki " nxge_get_config_properties:" 1616*52ccf843Smisaki " common hardware not set", nxgep->niu_type)); 161744961713Sgirish return (NXGE_ERROR); 161844961713Sgirish } 161944961713Sgirish 162044961713Sgirish /* 162144961713Sgirish * Get info on how many ports Neptune card has. 162244961713Sgirish */ 16232e59129aSraghus nxgep->nports = nxge_get_nports(nxgep); 162459ac0c16Sdavemq if (nxgep->nports <= 0) { 162559ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 162659ac0c16Sdavemq "<==nxge_get_config_properties: Invalid Neptune type 0x%x", 162759ac0c16Sdavemq nxgep->niu_type)); 162859ac0c16Sdavemq return (NXGE_ERROR); 162959ac0c16Sdavemq } 163059ac0c16Sdavemq nxgep->classifier.tcam_size = TCAM_NIU_TCAM_MAX_ENTRY; 16312e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 16322e59129aSraghus nxgep->classifier.tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY; 16332e59129aSraghus } 163459ac0c16Sdavemq if (nxgep->function_num >= nxgep->nports) { 163559ac0c16Sdavemq return (NXGE_ERROR); 163644961713Sgirish } 163744961713Sgirish 163814ea4bb7Ssd status = nxge_get_mac_addr_properties(nxgep); 1639a3c5bd6dSspeer if (status != NXGE_OK) 164014ea4bb7Ssd return (NXGE_ERROR); 164144961713Sgirish 1642a3c5bd6dSspeer /* 1643a3c5bd6dSspeer * read the configuration type. If none is specified, used default. 1644a3c5bd6dSspeer * Config types: equal: (default) DMA channels, RDC groups, TCAM, FCRAM 1645a3c5bd6dSspeer * are shared equally across all the ports. 1646a3c5bd6dSspeer * 164758324dfcSspeer * Fair: DMA channels, RDC groups, TCAM, FCRAM are shared proportional 164858324dfcSspeer * to the port speed. 1649a3c5bd6dSspeer * 1650a3c5bd6dSspeer * 1651a3c5bd6dSspeer * custom: DMA channels, RDC groups, TCAM, FCRAM partition is 1652a3c5bd6dSspeer * specified in nxge.conf. Need to read each parameter and set 1653a3c5bd6dSspeer * up the parameters in nxge structures. 1654a3c5bd6dSspeer * 1655a3c5bd6dSspeer */ 1656a3c5bd6dSspeer switch (nxgep->niu_type) { 1657a3c5bd6dSspeer case N2_NIU: 1658a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1659*52ccf843Smisaki " ==> nxge_get_config_properties: N2")); 1660a3c5bd6dSspeer MUTEX_ENTER(&hw_p->nxge_cfg_lock); 1661a3c5bd6dSspeer if ((hw_p->flags & COMMON_CFG_VALID) != 1662*52ccf843Smisaki COMMON_CFG_VALID) { 1663a3c5bd6dSspeer status = nxge_cfg_verify_set(nxgep, 1664*52ccf843Smisaki COMMON_RXDMA_GRP_CFG); 1665a3c5bd6dSspeer status = nxge_cfg_verify_set(nxgep, 1666*52ccf843Smisaki COMMON_CLASS_CFG); 1667a3c5bd6dSspeer hw_p->flags |= COMMON_CFG_VALID; 1668a3c5bd6dSspeer } 1669a3c5bd6dSspeer MUTEX_EXIT(&hw_p->nxge_cfg_lock); 1670a3c5bd6dSspeer status = nxge_use_cfg_n2niu_properties(nxgep); 1671a3c5bd6dSspeer break; 167259ac0c16Sdavemq default: 16732e59129aSraghus if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 167459ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 167559ac0c16Sdavemq " nxge_get_config_properties:" 167659ac0c16Sdavemq " unknown NIU type 0x%x", nxgep->niu_type)); 167759ac0c16Sdavemq return (NXGE_ERROR); 1678a3c5bd6dSspeer } 167944961713Sgirish 1680a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, VPD_CTL, 1681*52ccf843Smisaki " ==> nxge_get_config_properties: Neptune")); 1682a3c5bd6dSspeer status = nxge_cfg_verify_set_quick_config(nxgep); 1683a3c5bd6dSspeer MUTEX_ENTER(&hw_p->nxge_cfg_lock); 1684a3c5bd6dSspeer if ((hw_p->flags & COMMON_CFG_VALID) != 1685*52ccf843Smisaki COMMON_CFG_VALID) { 1686a3c5bd6dSspeer status = nxge_cfg_verify_set(nxgep, 1687*52ccf843Smisaki COMMON_TXDMA_CFG); 1688a3c5bd6dSspeer status = nxge_cfg_verify_set(nxgep, 1689*52ccf843Smisaki COMMON_RXDMA_CFG); 1690a3c5bd6dSspeer status = nxge_cfg_verify_set(nxgep, 1691*52ccf843Smisaki COMMON_RXDMA_GRP_CFG); 1692a3c5bd6dSspeer status = nxge_cfg_verify_set(nxgep, 1693*52ccf843Smisaki COMMON_CLASS_CFG); 1694a3c5bd6dSspeer hw_p->flags |= COMMON_CFG_VALID; 1695a3c5bd6dSspeer } 1696a3c5bd6dSspeer MUTEX_EXIT(&hw_p->nxge_cfg_lock); 1697a3c5bd6dSspeer nxge_use_cfg_neptune_properties(nxgep); 1698a3c5bd6dSspeer status = NXGE_OK; 1699a3c5bd6dSspeer break; 170044961713Sgirish } 170144961713Sgirish 17023d16f8e7Sml /* 17033d16f8e7Sml * Get the software LSO enable flag property from the 17043d16f8e7Sml * driver configuration file (nxge.conf). 17053d16f8e7Sml * This flag will be set to disable (0) if this property 17063d16f8e7Sml * does not exist. 17073d16f8e7Sml */ 17083d16f8e7Sml nxgep->soft_lso_enable = ddi_prop_get_int(DDI_DEV_T_ANY, nxgep->dip, 17093d16f8e7Sml DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "soft-lso-enable", 0); 17103d16f8e7Sml NXGE_DEBUG_MSG((nxgep, VPD_CTL, 17113d16f8e7Sml "nxge_get_config_properties: software lso %d\n", 17123d16f8e7Sml nxgep->soft_lso_enable)); 17133d16f8e7Sml 171444961713Sgirish NXGE_DEBUG_MSG((nxgep, VPD_CTL, " <== nxge_get_config_properties")); 171544961713Sgirish return (status); 171644961713Sgirish } 171744961713Sgirish 171844961713Sgirish static nxge_status_t 171944961713Sgirish nxge_use_cfg_n2niu_properties(p_nxge_t nxgep) 172044961713Sgirish { 172144961713Sgirish nxge_status_t status = NXGE_OK; 172244961713Sgirish 172344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_n2niu_properties")); 172444961713Sgirish 172544961713Sgirish status = nxge_use_default_dma_config_n2(nxgep); 172644961713Sgirish if (status != NXGE_OK) { 172744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1728*52ccf843Smisaki " ==> nxge_use_cfg_n2niu_properties (err 0x%x)", 1729*52ccf843Smisaki status)); 173044961713Sgirish return (status | NXGE_ERROR); 173144961713Sgirish } 173244961713Sgirish 173344961713Sgirish (void) nxge_use_cfg_vlan_class_config(nxgep); 173444961713Sgirish (void) nxge_use_cfg_mac_class_config(nxgep); 173544961713Sgirish (void) nxge_use_cfg_class_config(nxgep); 173644961713Sgirish (void) nxge_use_cfg_link_cfg(nxgep); 173744961713Sgirish 173844961713Sgirish /* 1739a3c5bd6dSspeer * Read in the hardware (fcode) properties. Use the ndd array to read 1740a3c5bd6dSspeer * each property. 174144961713Sgirish */ 174244961713Sgirish (void) nxge_get_param_soft_properties(nxgep); 174344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_n2niu_properties")); 174444961713Sgirish 174544961713Sgirish return (status); 174644961713Sgirish } 174744961713Sgirish 174844961713Sgirish static void 174944961713Sgirish nxge_use_cfg_neptune_properties(p_nxge_t nxgep) 175044961713Sgirish { 1751a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_neptune_properties")); 175244961713Sgirish 175344961713Sgirish (void) nxge_use_cfg_dma_config(nxgep); 175444961713Sgirish (void) nxge_use_cfg_vlan_class_config(nxgep); 175544961713Sgirish (void) nxge_use_cfg_mac_class_config(nxgep); 175644961713Sgirish (void) nxge_use_cfg_class_config(nxgep); 175744961713Sgirish (void) nxge_use_cfg_link_cfg(nxgep); 175844961713Sgirish 175944961713Sgirish /* 1760a3c5bd6dSspeer * Read in the hardware (fcode) properties. Use the ndd array to read 1761a3c5bd6dSspeer * each property. 176244961713Sgirish */ 176344961713Sgirish (void) nxge_get_param_soft_properties(nxgep); 1764a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_neptune_properties")); 176544961713Sgirish } 176644961713Sgirish 1767a3c5bd6dSspeer /* 1768a3c5bd6dSspeer * FWARC 2006/556 1769a3c5bd6dSspeer */ 1770a3c5bd6dSspeer 177144961713Sgirish static nxge_status_t 177244961713Sgirish nxge_use_default_dma_config_n2(p_nxge_t nxgep) 177344961713Sgirish { 1774a3c5bd6dSspeer int ndmas; 1775a3c5bd6dSspeer uint8_t func; 1776a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 1777a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 1778a3c5bd6dSspeer int *prop_val; 1779a3c5bd6dSspeer uint_t prop_len; 1780a3c5bd6dSspeer int i; 1781a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 178244961713Sgirish 178344961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2")); 178444961713Sgirish 178544961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 178644961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 178744961713Sgirish 178844961713Sgirish func = nxgep->function_num; 178944961713Sgirish p_cfgp->function_number = func; 179044961713Sgirish ndmas = NXGE_TDMA_PER_NIU_PORT; 179144961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1792*52ccf843Smisaki "tx-dma-channels", (int **)&prop_val, 1793*52ccf843Smisaki &prop_len) == DDI_PROP_SUCCESS) { 1794678453a8Sspeer p_cfgp->tdc.start = prop_val[0]; 179544961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1796*52ccf843Smisaki "==> nxge_use_default_dma_config_n2: tdc starts %d " 1797*52ccf843Smisaki "(#%d)", p_cfgp->tdc.start, prop_len)); 179844961713Sgirish 1799a3c5bd6dSspeer ndmas = prop_val[1]; 180044961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1801*52ccf843Smisaki "==> nxge_use_default_dma_config_n2: #tdc %d (#%d)", 1802*52ccf843Smisaki ndmas, prop_len)); 180344961713Sgirish ddi_prop_free(prop_val); 180444961713Sgirish } else { 180544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1806*52ccf843Smisaki "==> nxge_use_default_dma_config_n2: " 1807*52ccf843Smisaki "get tx-dma-channels failed")); 180844961713Sgirish return (NXGE_DDI_FAILED); 180944961713Sgirish } 181044961713Sgirish 1811678453a8Sspeer p_cfgp->tdc.count = nxgep->max_tdcs = ndmas; 1812678453a8Sspeer p_cfgp->tdc.owned = p_cfgp->tdc.count; 181344961713Sgirish 181444961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: " 1815*52ccf843Smisaki "p_cfgp 0x%llx max_tdcs %d nxgep->max_tdcs %d start %d", 1816*52ccf843Smisaki p_cfgp, p_cfgp->tdc.count, nxgep->max_tdcs, p_cfgp->tdc.start)); 181744961713Sgirish 181844961713Sgirish /* Receive DMA */ 181944961713Sgirish ndmas = NXGE_RDMA_PER_NIU_PORT; 182044961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1821*52ccf843Smisaki "rx-dma-channels", (int **)&prop_val, 1822*52ccf843Smisaki &prop_len) == DDI_PROP_SUCCESS) { 182344961713Sgirish p_cfgp->start_rdc = prop_val[0]; 182444961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1825*52ccf843Smisaki "==> nxge_use_default_dma_config_n2(obp): rdc start %d" 1826*52ccf843Smisaki " (#%d)", p_cfgp->start_rdc, prop_len)); 182744961713Sgirish ndmas = prop_val[1]; 182844961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1829*52ccf843Smisaki "==> nxge_use_default_dma_config_n2(obp):#rdc %d (#%d)", 1830*52ccf843Smisaki ndmas, prop_len)); 183144961713Sgirish ddi_prop_free(prop_val); 183244961713Sgirish } else { 183344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1834*52ccf843Smisaki "==> nxge_use_default_dma_config_n2: " 1835*52ccf843Smisaki "get rx-dma-channel failed")); 183644961713Sgirish return (NXGE_DDI_FAILED); 183744961713Sgirish } 183844961713Sgirish 1839a3c5bd6dSspeer p_cfgp->max_rdcs = nxgep->max_rdcs = ndmas; 184044961713Sgirish nxgep->rdc_mask = (ndmas - 1); 184144961713Sgirish 184244961713Sgirish /* Hypervisor: rdc # and group # use the same # !! */ 1843678453a8Sspeer p_cfgp->max_grpids = p_cfgp->max_rdcs + p_cfgp->tdc.owned; 184444961713Sgirish p_cfgp->start_grpid = 0; 184544961713Sgirish p_cfgp->mif_ldvid = p_cfgp->mac_ldvid = p_cfgp->ser_ldvid = 0; 184644961713Sgirish 184744961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, 1848*52ccf843Smisaki "interrupts", (int **)&prop_val, 1849*52ccf843Smisaki &prop_len) == DDI_PROP_SUCCESS) { 185044961713Sgirish /* 1851a3c5bd6dSspeer * For each device assigned, the content of each interrupts 1852a3c5bd6dSspeer * property is its logical device group. 185344961713Sgirish * 1854a3c5bd6dSspeer * Assignment of interrupts property is in the the following 1855a3c5bd6dSspeer * order: 185644961713Sgirish * 1857a3c5bd6dSspeer * MAC MIF (if configured) SYSTEM ERROR (if configured) first 1858a3c5bd6dSspeer * receive channel next channel...... last receive channel 1859a3c5bd6dSspeer * first transmit channel next channel...... last transmit 1860a3c5bd6dSspeer * channel 186144961713Sgirish * 1862a3c5bd6dSspeer * prop_len should be at least for one mac and total # of rx and 1863a3c5bd6dSspeer * tx channels. Function 0 owns MIF and ERROR 186444961713Sgirish */ 186544961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1866*52ccf843Smisaki "==> nxge_use_default_dma_config_n2(obp): " 1867*52ccf843Smisaki "# interrupts %d", prop_len)); 186844961713Sgirish 186944961713Sgirish switch (func) { 187044961713Sgirish case 0: 187144961713Sgirish p_cfgp->ldg_chn_start = 3; 187244961713Sgirish p_cfgp->mac_ldvid = NXGE_MAC_LD_PORT0; 187344961713Sgirish p_cfgp->mif_ldvid = NXGE_MIF_LD; 187444961713Sgirish p_cfgp->ser_ldvid = NXGE_SYS_ERROR_LD; 187544961713Sgirish 187644961713Sgirish break; 187744961713Sgirish case 1: 187844961713Sgirish p_cfgp->ldg_chn_start = 1; 187944961713Sgirish p_cfgp->mac_ldvid = NXGE_MAC_LD_PORT1; 188044961713Sgirish 188144961713Sgirish break; 188244961713Sgirish default: 188344961713Sgirish status = NXGE_DDI_FAILED; 188444961713Sgirish break; 188544961713Sgirish } 188644961713Sgirish 1887a3c5bd6dSspeer if (status != NXGE_OK) 188844961713Sgirish return (status); 188944961713Sgirish 189044961713Sgirish for (i = 0; i < prop_len; i++) { 189144961713Sgirish p_cfgp->ldg[i] = prop_val[i]; 189244961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1893*52ccf843Smisaki "==> nxge_use_default_dma_config_n2(obp): " 1894*52ccf843Smisaki "F%d: interrupt #%d, ldg %d", 1895*52ccf843Smisaki nxgep->function_num, i, p_cfgp->ldg[i])); 189644961713Sgirish } 189744961713Sgirish 189844961713Sgirish p_cfgp->max_grpids = prop_len; 189944961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1900*52ccf843Smisaki "==> nxge_use_default_dma_config_n2(obp): %d " 1901*52ccf843Smisaki "(#%d) maxgrpids %d channel starts %d", 1902*52ccf843Smisaki p_cfgp->mac_ldvid, i, p_cfgp->max_grpids, 1903*52ccf843Smisaki p_cfgp->ldg_chn_start)); 190444961713Sgirish ddi_prop_free(prop_val); 190544961713Sgirish } else { 190644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1907*52ccf843Smisaki "==> nxge_use_default_dma_config_n2: " 1908*52ccf843Smisaki "get interrupts failed")); 190944961713Sgirish return (NXGE_DDI_FAILED); 191044961713Sgirish } 191144961713Sgirish 191244961713Sgirish p_cfgp->max_ldgs = p_cfgp->max_grpids; 191344961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 1914*52ccf843Smisaki "==> nxge_use_default_dma_config_n2: " 1915*52ccf843Smisaki "p_cfgp 0x%llx max_rdcs %d nxgep->max_rdcs %d max_grpids %d" 1916*52ccf843Smisaki "start_grpid %d macid %d mifid %d serrid %d", 1917*52ccf843Smisaki p_cfgp, p_cfgp->max_rdcs, nxgep->max_rdcs, p_cfgp->max_grpids, 1918*52ccf843Smisaki p_cfgp->start_grpid, 1919*52ccf843Smisaki p_cfgp->mac_ldvid, p_cfgp->mif_ldvid, p_cfgp->ser_ldvid)); 192044961713Sgirish 192144961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: " 1922*52ccf843Smisaki "p_cfgp p%p start_ldg %d nxgep->max_ldgs %d", 1923*52ccf843Smisaki p_cfgp, p_cfgp->start_ldg, p_cfgp->max_ldgs)); 192444961713Sgirish 192544961713Sgirish /* 1926a3c5bd6dSspeer * RDC groups and the beginning RDC group assigned to this function. 192744961713Sgirish */ 1928678453a8Sspeer p_cfgp->max_rdc_grpids = 1; 1929678453a8Sspeer p_cfgp->def_mac_rxdma_grpid = (nxgep->function_num * 1); 1930678453a8Sspeer 1931678453a8Sspeer if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind 1932*52ccf843Smisaki (nxgep, p_cfgp->def_mac_rxdma_grpid, B_TRUE)) 1933678453a8Sspeer >= NXGE_MAX_RDC_GRPS) { 1934678453a8Sspeer NXGE_ERROR_MSG((nxgep, CFG_CTL, 1935678453a8Sspeer "nxge_use_default_dma_config_n2(): " 1936678453a8Sspeer "nxge_fzc_rdc_tbl_bind failed")); 1937678453a8Sspeer return (NXGE_DDI_FAILED); 1938678453a8Sspeer } 193944961713Sgirish 194044961713Sgirish status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 1941678453a8Sspeer "rx-rdc-grps", p_cfgp->max_rdc_grpids); 194244961713Sgirish if (status) { 194344961713Sgirish return (NXGE_DDI_FAILED); 194444961713Sgirish } 194544961713Sgirish status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 1946*52ccf843Smisaki "rx-rdc-grps-begin", p_cfgp->def_mac_rxdma_grpid); 194744961713Sgirish if (status) { 194844961713Sgirish (void) ddi_prop_remove(DDI_DEV_T_NONE, nxgep->dip, 1949*52ccf843Smisaki "rx-rdc-grps"); 195044961713Sgirish return (NXGE_DDI_FAILED); 195144961713Sgirish } 195244961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: " 1953*52ccf843Smisaki "p_cfgp $%p # rdc groups %d start rdc group id %d", 1954*52ccf843Smisaki p_cfgp, p_cfgp->max_rdc_grpids, 1955*52ccf843Smisaki p_cfgp->def_mac_rxdma_grpid)); 195644961713Sgirish 195744961713Sgirish nxge_set_hw_dma_config(nxgep); 195844961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, "<== nxge_use_default_dma_config_n2")); 195944961713Sgirish return (status); 196044961713Sgirish } 196144961713Sgirish 196244961713Sgirish static void 196344961713Sgirish nxge_use_cfg_dma_config(p_nxge_t nxgep) 196444961713Sgirish { 196559ac0c16Sdavemq int tx_ndmas, rx_ndmas, nrxgp, st_txdma, st_rxdma; 1966a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 1967a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 196844961713Sgirish dev_info_t *dip; 196944961713Sgirish p_nxge_param_t param_arr; 197044961713Sgirish char *prop; 1971a3c5bd6dSspeer int *prop_val; 1972a3c5bd6dSspeer uint_t prop_len; 197359ac0c16Sdavemq int i; 197459ac0c16Sdavemq uint8_t *ch_arr_p; 197544961713Sgirish 197644961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_dma_config")); 197744961713Sgirish param_arr = nxgep->param_arr; 197844961713Sgirish 197944961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 198044961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 198144961713Sgirish dip = nxgep->dip; 198244961713Sgirish p_cfgp->function_number = nxgep->function_num; 198344961713Sgirish prop = param_arr[param_txdma_channels_begin].fcode_name; 198444961713Sgirish 198544961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 1986*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 1987678453a8Sspeer p_cfgp->tdc.start = *prop_val; 198844961713Sgirish ddi_prop_free(prop_val); 198944961713Sgirish } else { 199059ac0c16Sdavemq switch (nxgep->niu_type) { 199159ac0c16Sdavemq case NEPTUNE_4_1GC: 199259ac0c16Sdavemq ch_arr_p = &tx_4_1G[0]; 199359ac0c16Sdavemq break; 199459ac0c16Sdavemq case NEPTUNE_2_10GF: 199559ac0c16Sdavemq ch_arr_p = &tx_2_10G[0]; 199659ac0c16Sdavemq break; 199759ac0c16Sdavemq case NEPTUNE_2_10GF_2_1GC: 199859a835ddSjoycey case NEPTUNE_2_10GF_2_1GRF: 199959ac0c16Sdavemq ch_arr_p = &tx_2_10G_2_1G[0]; 200059ac0c16Sdavemq break; 200159ac0c16Sdavemq case NEPTUNE_1_10GF_3_1GC: 200259ac0c16Sdavemq ch_arr_p = &tx_1_10G_3_1G[0]; 200359ac0c16Sdavemq break; 200459ac0c16Sdavemq case NEPTUNE_1_1GC_1_10GF_2_1GC: 200559ac0c16Sdavemq ch_arr_p = &tx_1_1G_1_10G_2_1G[0]; 200659ac0c16Sdavemq break; 200759ac0c16Sdavemq default: 2008d81011f0Ssbehera switch (nxgep->platform_type) { 2009d81011f0Ssbehera case P_NEPTUNE_ALONSO: 2010d81011f0Ssbehera ch_arr_p = &tx_2_10G_2_1G[0]; 2011d81011f0Ssbehera break; 2012d81011f0Ssbehera default: 2013d81011f0Ssbehera ch_arr_p = &p4_tx_equal[0]; 2014d81011f0Ssbehera break; 2015d81011f0Ssbehera } 201659ac0c16Sdavemq break; 201744961713Sgirish } 201859ac0c16Sdavemq st_txdma = 0; 201959ac0c16Sdavemq for (i = 0; i < nxgep->function_num; i++, ch_arr_p++) 202059ac0c16Sdavemq st_txdma += *ch_arr_p; 202159ac0c16Sdavemq 2022a3c5bd6dSspeer (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 202359ac0c16Sdavemq prop, st_txdma); 2024678453a8Sspeer p_cfgp->tdc.start = st_txdma; 202544961713Sgirish } 202644961713Sgirish 202744961713Sgirish prop = param_arr[param_txdma_channels].fcode_name; 202844961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2029*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 203044961713Sgirish tx_ndmas = *prop_val; 203144961713Sgirish ddi_prop_free(prop_val); 203244961713Sgirish } else { 203359ac0c16Sdavemq switch (nxgep->niu_type) { 203459ac0c16Sdavemq case NEPTUNE_4_1GC: 203559ac0c16Sdavemq tx_ndmas = tx_4_1G[nxgep->function_num]; 203659ac0c16Sdavemq break; 203759ac0c16Sdavemq case NEPTUNE_2_10GF: 203859ac0c16Sdavemq tx_ndmas = tx_2_10G[nxgep->function_num]; 203959ac0c16Sdavemq break; 204059ac0c16Sdavemq case NEPTUNE_2_10GF_2_1GC: 204159a835ddSjoycey case NEPTUNE_2_10GF_2_1GRF: 204259ac0c16Sdavemq tx_ndmas = tx_2_10G_2_1G[nxgep->function_num]; 204359ac0c16Sdavemq break; 204459ac0c16Sdavemq case NEPTUNE_1_10GF_3_1GC: 204559ac0c16Sdavemq tx_ndmas = tx_1_10G_3_1G[nxgep->function_num]; 204659ac0c16Sdavemq break; 204759ac0c16Sdavemq case NEPTUNE_1_1GC_1_10GF_2_1GC: 204859ac0c16Sdavemq tx_ndmas = tx_1_1G_1_10G_2_1G[nxgep->function_num]; 204959ac0c16Sdavemq break; 205059ac0c16Sdavemq default: 2051d81011f0Ssbehera switch (nxgep->platform_type) { 2052d81011f0Ssbehera case P_NEPTUNE_ALONSO: 2053d81011f0Ssbehera tx_ndmas = tx_2_10G_2_1G[nxgep->function_num]; 2054d81011f0Ssbehera break; 2055d81011f0Ssbehera default: 2056d81011f0Ssbehera tx_ndmas = p4_tx_equal[nxgep->function_num]; 2057d81011f0Ssbehera break; 2058d81011f0Ssbehera } 205959ac0c16Sdavemq break; 206044961713Sgirish } 2061a3c5bd6dSspeer (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2062*52ccf843Smisaki prop, tx_ndmas); 206344961713Sgirish } 206444961713Sgirish 2065678453a8Sspeer p_cfgp->tdc.count = nxgep->max_tdcs = tx_ndmas; 2066678453a8Sspeer p_cfgp->tdc.owned = p_cfgp->tdc.count; 206744961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_dma_config: " 2068*52ccf843Smisaki "p_cfgp 0x%llx max_tdcs %d nxgep->max_tdcs %d", 2069*52ccf843Smisaki p_cfgp, p_cfgp->tdc.count, nxgep->max_tdcs)); 207044961713Sgirish 207144961713Sgirish prop = param_arr[param_rxdma_channels_begin].fcode_name; 207244961713Sgirish 207344961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2074*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 207544961713Sgirish p_cfgp->start_rdc = *prop_val; 207644961713Sgirish ddi_prop_free(prop_val); 207744961713Sgirish } else { 207859ac0c16Sdavemq switch (nxgep->niu_type) { 207959ac0c16Sdavemq case NEPTUNE_4_1GC: 208059ac0c16Sdavemq ch_arr_p = &rx_4_1G[0]; 208159ac0c16Sdavemq break; 208259ac0c16Sdavemq case NEPTUNE_2_10GF: 208359ac0c16Sdavemq ch_arr_p = &rx_2_10G[0]; 208459ac0c16Sdavemq break; 208559ac0c16Sdavemq case NEPTUNE_2_10GF_2_1GC: 208659a835ddSjoycey case NEPTUNE_2_10GF_2_1GRF: 208759ac0c16Sdavemq ch_arr_p = &rx_2_10G_2_1G[0]; 208859ac0c16Sdavemq break; 208959ac0c16Sdavemq case NEPTUNE_1_10GF_3_1GC: 209059ac0c16Sdavemq ch_arr_p = &rx_1_10G_3_1G[0]; 209159ac0c16Sdavemq break; 209259ac0c16Sdavemq case NEPTUNE_1_1GC_1_10GF_2_1GC: 209359ac0c16Sdavemq ch_arr_p = &rx_1_1G_1_10G_2_1G[0]; 209459ac0c16Sdavemq break; 209559ac0c16Sdavemq default: 2096d81011f0Ssbehera switch (nxgep->platform_type) { 2097d81011f0Ssbehera case P_NEPTUNE_ALONSO: 2098d81011f0Ssbehera ch_arr_p = &rx_2_10G_2_1G[0]; 2099d81011f0Ssbehera break; 2100d81011f0Ssbehera default: 2101d81011f0Ssbehera ch_arr_p = &p4_rx_equal[0]; 2102d81011f0Ssbehera break; 2103d81011f0Ssbehera } 210459ac0c16Sdavemq break; 210544961713Sgirish } 210659ac0c16Sdavemq st_rxdma = 0; 210759ac0c16Sdavemq for (i = 0; i < nxgep->function_num; i++, ch_arr_p++) 210859ac0c16Sdavemq st_rxdma += *ch_arr_p; 210959ac0c16Sdavemq 2110a3c5bd6dSspeer (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 211159ac0c16Sdavemq prop, st_rxdma); 211259ac0c16Sdavemq p_cfgp->start_rdc = st_rxdma; 211344961713Sgirish } 211444961713Sgirish 211544961713Sgirish prop = param_arr[param_rxdma_channels].fcode_name; 211644961713Sgirish 211744961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2118*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 211944961713Sgirish rx_ndmas = *prop_val; 212044961713Sgirish ddi_prop_free(prop_val); 212144961713Sgirish } else { 212259ac0c16Sdavemq switch (nxgep->niu_type) { 212359ac0c16Sdavemq case NEPTUNE_4_1GC: 212459ac0c16Sdavemq rx_ndmas = rx_4_1G[nxgep->function_num]; 212559ac0c16Sdavemq break; 212659ac0c16Sdavemq case NEPTUNE_2_10GF: 212759ac0c16Sdavemq rx_ndmas = rx_2_10G[nxgep->function_num]; 212859ac0c16Sdavemq break; 212959ac0c16Sdavemq case NEPTUNE_2_10GF_2_1GC: 213059a835ddSjoycey case NEPTUNE_2_10GF_2_1GRF: 213159ac0c16Sdavemq rx_ndmas = rx_2_10G_2_1G[nxgep->function_num]; 213259ac0c16Sdavemq break; 213359ac0c16Sdavemq case NEPTUNE_1_10GF_3_1GC: 213459ac0c16Sdavemq rx_ndmas = rx_1_10G_3_1G[nxgep->function_num]; 213559ac0c16Sdavemq break; 213659ac0c16Sdavemq case NEPTUNE_1_1GC_1_10GF_2_1GC: 213759ac0c16Sdavemq rx_ndmas = rx_1_1G_1_10G_2_1G[nxgep->function_num]; 213859ac0c16Sdavemq break; 213959ac0c16Sdavemq default: 2140d81011f0Ssbehera switch (nxgep->platform_type) { 2141d81011f0Ssbehera case P_NEPTUNE_ALONSO: 2142d81011f0Ssbehera rx_ndmas = rx_2_10G_2_1G[nxgep->function_num]; 2143d81011f0Ssbehera break; 2144d81011f0Ssbehera default: 2145d81011f0Ssbehera rx_ndmas = p4_rx_equal[nxgep->function_num]; 2146d81011f0Ssbehera break; 2147d81011f0Ssbehera } 214859ac0c16Sdavemq break; 214944961713Sgirish } 2150a3c5bd6dSspeer (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2151*52ccf843Smisaki prop, rx_ndmas); 215244961713Sgirish } 215344961713Sgirish 2154a3c5bd6dSspeer p_cfgp->max_rdcs = nxgep->max_rdcs = rx_ndmas; 215544961713Sgirish 215644961713Sgirish prop = param_arr[param_rdc_grps_start].fcode_name; 215744961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2158*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 2159678453a8Sspeer p_cfgp->def_mac_rxdma_grpid = *prop_val; 216044961713Sgirish ddi_prop_free(prop_val); 2161678453a8Sspeer if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind 2162*52ccf843Smisaki (nxgep, p_cfgp->def_mac_rxdma_grpid, B_TRUE)) 2163678453a8Sspeer >= NXGE_MAX_RDC_GRPS) { 2164678453a8Sspeer NXGE_ERROR_MSG((nxgep, CFG_CTL, 2165678453a8Sspeer "nxge_use_cfg_dma_config(): " 2166678453a8Sspeer "nxge_fzc_rdc_tbl_bind failed")); 2167678453a8Sspeer cmn_err(CE_CONT, "nxge%d: group not available!\n", 2168678453a8Sspeer nxgep->instance); 2169678453a8Sspeer goto nxge_use_cfg_dma_config_exit; 2170678453a8Sspeer } 2171678453a8Sspeer 217244961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 2173678453a8Sspeer "==> nxge_use_default_dma_config: " 2174678453a8Sspeer "use property " "start_grpid %d ", 2175*52ccf843Smisaki p_cfgp->start_grpid)); 217644961713Sgirish } else { 2177678453a8Sspeer p_cfgp->def_mac_rxdma_grpid = nxgep->function_num; 2178678453a8Sspeer if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind( 2179678453a8Sspeer nxgep, p_cfgp->def_mac_rxdma_grpid, B_TRUE)) >= 2180678453a8Sspeer NXGE_MAX_RDC_GRPS) { 2181678453a8Sspeer cmn_err(CE_CONT, "nxge%d: group not available!\n", 2182678453a8Sspeer nxgep->instance); 2183678453a8Sspeer goto nxge_use_cfg_dma_config_exit; 2184678453a8Sspeer } 2185a3c5bd6dSspeer (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2186*52ccf843Smisaki prop, p_cfgp->def_mac_rxdma_grpid); 218744961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 2188*52ccf843Smisaki "==> nxge_use_default_dma_config: " 2189*52ccf843Smisaki "use default " 2190*52ccf843Smisaki "start_grpid %d (same as function #)", 2191*52ccf843Smisaki p_cfgp->start_grpid)); 219244961713Sgirish } 219344961713Sgirish 219444961713Sgirish prop = param_arr[param_rx_rdc_grps].fcode_name; 219544961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2196*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 219744961713Sgirish nrxgp = *prop_val; 219844961713Sgirish ddi_prop_free(prop_val); 219944961713Sgirish } else { 220044961713Sgirish nrxgp = 1; 2201a3c5bd6dSspeer (void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip, 2202*52ccf843Smisaki prop, nrxgp); 220344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, 2204*52ccf843Smisaki "==> nxge_use_default_dma_config: " 2205*52ccf843Smisaki "num_rdc_grpid not found: use def:# of " 2206*52ccf843Smisaki "rdc groups %d\n", nrxgp)); 220744961713Sgirish } 220844961713Sgirish 220944961713Sgirish p_cfgp->max_rdc_grpids = nrxgp; 221044961713Sgirish 221144961713Sgirish /* 2212a3c5bd6dSspeer * 2/4 ports have the same hard-wired logical groups assigned. 221344961713Sgirish */ 221444961713Sgirish p_cfgp->start_ldg = nxgep->function_num * NXGE_LDGRP_PER_4PORTS; 221544961713Sgirish p_cfgp->max_ldgs = NXGE_LDGRP_PER_4PORTS; 221644961713Sgirish 221744961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_default_dma_config: " 2218*52ccf843Smisaki "p_cfgp 0x%llx max_rdcs %d nxgep->max_rdcs %d max_grpids %d" 2219*52ccf843Smisaki "start_grpid %d", 2220*52ccf843Smisaki p_cfgp, p_cfgp->max_rdcs, nxgep->max_rdcs, p_cfgp->max_grpids, 2221*52ccf843Smisaki p_cfgp->start_grpid)); 222244961713Sgirish 222344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_dma_config: " 2224*52ccf843Smisaki "p_cfgp 0x%016llx start_ldg %d nxgep->max_ldgs %d " 2225*52ccf843Smisaki "def_mac_rxdma_grpid %d", 2226*52ccf843Smisaki p_cfgp, p_cfgp->start_ldg, p_cfgp->max_ldgs, 2227*52ccf843Smisaki p_cfgp->def_mac_rxdma_grpid)); 222844961713Sgirish 222944961713Sgirish prop = param_arr[param_rxdma_intr_time].fcode_name; 223044961713Sgirish 223144961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2232*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 223344961713Sgirish if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) { 2234a3c5bd6dSspeer (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2235*52ccf843Smisaki nxgep->dip, prop, prop_val, prop_len); 223644961713Sgirish } 223744961713Sgirish ddi_prop_free(prop_val); 223844961713Sgirish } 223944961713Sgirish prop = param_arr[param_rxdma_intr_pkts].fcode_name; 224044961713Sgirish 224144961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop, 2242*52ccf843Smisaki &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 224344961713Sgirish if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) { 2244a3c5bd6dSspeer (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2245*52ccf843Smisaki nxgep->dip, prop, prop_val, prop_len); 224644961713Sgirish } 224744961713Sgirish ddi_prop_free(prop_val); 224844961713Sgirish } 224944961713Sgirish nxge_set_hw_dma_config(nxgep); 2250a3c5bd6dSspeer 225159ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config: " 225259ac0c16Sdavemq "sTDC[%d] nTDC[%d] sRDC[%d] nRDC[%d]", 2253678453a8Sspeer p_cfgp->tdc.start, p_cfgp->tdc.count, 225459ac0c16Sdavemq p_cfgp->start_rdc, p_cfgp->max_rdcs)); 225559ac0c16Sdavemq 2256678453a8Sspeer nxge_use_cfg_dma_config_exit: 225744961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config")); 225844961713Sgirish } 225944961713Sgirish 2260678453a8Sspeer void 2261678453a8Sspeer nxge_get_logical_props(p_nxge_t nxgep) 2262678453a8Sspeer { 2263678453a8Sspeer nxge_dma_pt_cfg_t *port = &nxgep->pt_config; 2264678453a8Sspeer nxge_hw_pt_cfg_t *hardware; 2265678453a8Sspeer nxge_rdc_grp_t *group; 2266678453a8Sspeer 2267678453a8Sspeer (void) memset(port, 0, sizeof (*port)); 2268678453a8Sspeer 2269678453a8Sspeer port->mac_port = 0; /* := function number */ 2270678453a8Sspeer 2271678453a8Sspeer /* 2272678453a8Sspeer * alloc_buf_size: 2273678453a8Sspeer * dead variables. 2274678453a8Sspeer */ 2275678453a8Sspeer port->rbr_size = nxge_rbr_size; 2276678453a8Sspeer port->rcr_size = nxge_rcr_size; 2277678453a8Sspeer 2278678453a8Sspeer port->tx_dma_map = 0; /* Transmit DMA channel bit map */ 2279678453a8Sspeer 2280678453a8Sspeer nxge_set_rdc_intr_property(nxgep); 2281678453a8Sspeer 2282678453a8Sspeer port->rcr_full_header = NXGE_RCR_FULL_HEADER; 2283678453a8Sspeer port->rx_drr_weight = PT_DRR_WT_DEFAULT_10G; 2284678453a8Sspeer 2285678453a8Sspeer /* ----------------------------------------------------- */ 2286678453a8Sspeer hardware = &port->hw_config; 2287678453a8Sspeer 2288678453a8Sspeer (void) memset(hardware, 0, sizeof (*hardware)); 2289678453a8Sspeer 2290678453a8Sspeer /* 2291678453a8Sspeer * partition_id, read_write_mode: 2292678453a8Sspeer * dead variables. 2293678453a8Sspeer */ 2294678453a8Sspeer 2295678453a8Sspeer /* 2296678453a8Sspeer * drr_wt, rx_full_header, *_ldg?, start_mac_entry, 2297678453a8Sspeer * mac_pref, def_mac_rxdma_grpid, start_vlan, max_vlans, 2298678453a8Sspeer * start_ldgs, max_ldgs, max_ldvs, 2299678453a8Sspeer * vlan_pref, def_vlan_rxdma_grpid are meaningful only 2300678453a8Sspeer * in the service domain. 2301678453a8Sspeer */ 2302678453a8Sspeer 2303678453a8Sspeer group = &port->rdc_grps[0]; 2304678453a8Sspeer 2305678453a8Sspeer group->flag = 1; /* configured */ 2306678453a8Sspeer group->config_method = RDC_TABLE_ENTRY_METHOD_REP; 2307678453a8Sspeer 2308678453a8Sspeer /* HIO futures: this is still an open question. */ 2309678453a8Sspeer hardware->max_macs = 1; 2310678453a8Sspeer } 2311678453a8Sspeer 231244961713Sgirish static void 231344961713Sgirish nxge_use_cfg_vlan_class_config(p_nxge_t nxgep) 231444961713Sgirish { 231544961713Sgirish uint_t vlan_cnt; 231644961713Sgirish int *vlan_cfg_val; 231744961713Sgirish int status; 231844961713Sgirish p_nxge_param_t param_arr; 231944961713Sgirish char *prop; 232044961713Sgirish 232144961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_vlan_config")); 232244961713Sgirish param_arr = nxgep->param_arr; 232344961713Sgirish prop = param_arr[param_vlan_2rdc_grp].fcode_name; 232444961713Sgirish 232544961713Sgirish status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2326*52ccf843Smisaki &vlan_cfg_val, &vlan_cnt); 232744961713Sgirish if (status == DDI_PROP_SUCCESS) { 232844961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, 2329*52ccf843Smisaki nxgep->dip, prop, vlan_cfg_val, vlan_cnt); 233044961713Sgirish ddi_prop_free(vlan_cfg_val); 233144961713Sgirish } 233244961713Sgirish nxge_set_hw_vlan_class_config(nxgep); 233344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_vlan_config")); 233444961713Sgirish } 233544961713Sgirish 233644961713Sgirish static void 233744961713Sgirish nxge_use_cfg_mac_class_config(p_nxge_t nxgep) 233844961713Sgirish { 2339a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 2340a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 234144961713Sgirish uint_t mac_cnt; 234244961713Sgirish int *mac_cfg_val; 234344961713Sgirish int status; 234444961713Sgirish p_nxge_param_t param_arr; 234544961713Sgirish char *prop; 234644961713Sgirish 234744961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_mac_class_config")); 234844961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 234944961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 235044961713Sgirish p_cfgp->start_mac_entry = 0; 235144961713Sgirish param_arr = nxgep->param_arr; 235244961713Sgirish prop = param_arr[param_mac_2rdc_grp].fcode_name; 235344961713Sgirish 235444961713Sgirish switch (nxgep->function_num) { 235544961713Sgirish case 0: 235644961713Sgirish case 1: 235744961713Sgirish /* 10G ports */ 235844961713Sgirish p_cfgp->max_macs = NXGE_MAX_MACS_XMACS; 235944961713Sgirish break; 236044961713Sgirish case 2: 236144961713Sgirish case 3: 236244961713Sgirish /* 1G ports */ 236344961713Sgirish default: 236444961713Sgirish p_cfgp->max_macs = NXGE_MAX_MACS_BMACS; 236544961713Sgirish break; 236644961713Sgirish } 236744961713Sgirish 236844961713Sgirish p_cfgp->mac_pref = 1; 236944961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 2370*52ccf843Smisaki "== nxge_use_cfg_mac_class_config: " 2371*52ccf843Smisaki " mac_pref bit set def_mac_rxdma_grpid %d", 2372*52ccf843Smisaki p_cfgp->def_mac_rxdma_grpid)); 237344961713Sgirish 237444961713Sgirish status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2375*52ccf843Smisaki &mac_cfg_val, &mac_cnt); 237644961713Sgirish if (status == DDI_PROP_SUCCESS) { 237744961713Sgirish if (mac_cnt <= p_cfgp->max_macs) 237844961713Sgirish status = ddi_prop_update_int_array(DDI_DEV_T_NONE, 2379*52ccf843Smisaki nxgep->dip, prop, mac_cfg_val, mac_cnt); 238044961713Sgirish ddi_prop_free(mac_cfg_val); 238144961713Sgirish } 238244961713Sgirish nxge_set_hw_mac_class_config(nxgep); 238344961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_mac_class_config")); 238444961713Sgirish } 238544961713Sgirish 238644961713Sgirish static void 238744961713Sgirish nxge_use_cfg_class_config(p_nxge_t nxgep) 238844961713Sgirish { 238944961713Sgirish nxge_set_hw_class_config(nxgep); 239044961713Sgirish } 239144961713Sgirish 239244961713Sgirish static void 239344961713Sgirish nxge_set_rdc_intr_property(p_nxge_t nxgep) 239444961713Sgirish { 2395a3c5bd6dSspeer int i; 2396a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 2397a3c5bd6dSspeer 239844961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_rdc_intr_property")); 239944961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 240044961713Sgirish 240144961713Sgirish for (i = 0; i < NXGE_MAX_RDCS; i++) { 240244961713Sgirish p_dma_cfgp->rcr_timeout[i] = nxge_rcr_timeout; 240344961713Sgirish p_dma_cfgp->rcr_threshold[i] = nxge_rcr_threshold; 240444961713Sgirish } 240544961713Sgirish 240644961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_rdc_intr_property")); 240744961713Sgirish } 240844961713Sgirish 240944961713Sgirish static void 241044961713Sgirish nxge_set_hw_dma_config(p_nxge_t nxgep) 241144961713Sgirish { 2412678453a8Sspeer int i, ndmas, ngrps, bitmap, end, st_rdc; 2413a3c5bd6dSspeer int32_t status; 241444961713Sgirish uint8_t rdcs_per_grp; 2415a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 2416a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 2417a3c5bd6dSspeer p_nxge_rdc_grp_t rdc_grp_p; 2418a3c5bd6dSspeer int rdcgrp_cfg = CFG_NOT_SPECIFIED, rx_quick_cfg; 241944961713Sgirish char *prop, *prop_val; 242044961713Sgirish p_nxge_param_t param_arr; 242144961713Sgirish config_token_t token; 2422678453a8Sspeer nxge_grp_t *group; 2423a3c5bd6dSspeer 242444961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_dma_config")); 242544961713Sgirish 242644961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 242744961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 242844961713Sgirish rdc_grp_p = p_dma_cfgp->rdc_grps; 242944961713Sgirish 243044961713Sgirish bitmap = 0; 2431678453a8Sspeer end = p_cfgp->tdc.start + p_cfgp->tdc.owned; 243244961713Sgirish p_dma_cfgp->tx_dma_map = 0; 2433678453a8Sspeer for (i = p_cfgp->tdc.start; i < end; i++) { 243444961713Sgirish bitmap |= (1 << i); 243544961713Sgirish } 243644961713Sgirish 2437678453a8Sspeer nxgep->tx_set.owned.map |= bitmap; /* Owned, & not shared. */ 2438678453a8Sspeer 2439678453a8Sspeer group = (nxge_grp_t *)nxge_grp_add(nxgep, NXGE_TRANSMIT_GROUP); 2440678453a8Sspeer group->map = bitmap; 2441678453a8Sspeer 244244961713Sgirish p_dma_cfgp->tx_dma_map = bitmap; 244344961713Sgirish param_arr = nxgep->param_arr; 244444961713Sgirish 244544961713Sgirish /* Assume RDCs are evenly distributed */ 244644961713Sgirish rx_quick_cfg = param_arr[param_rx_quick_cfg].value; 244744961713Sgirish switch (rx_quick_cfg) { 2448a3c5bd6dSspeer case CFG_NOT_SPECIFIED: 2449a3c5bd6dSspeer prop = "rxdma-grp-cfg"; 2450a3c5bd6dSspeer status = ddi_prop_lookup_string(DDI_DEV_T_NONE, 2451*52ccf843Smisaki nxgep->dip, 0, prop, (char **)&prop_val); 2452a3c5bd6dSspeer if (status != DDI_PROP_SUCCESS) { 2453a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 2454*52ccf843Smisaki " property %s not found", prop)); 2455a3c5bd6dSspeer rdcgrp_cfg = CFG_L3_DISTRIBUTE; 2456a3c5bd6dSspeer } else { 2457a3c5bd6dSspeer token = nxge_get_config_token(prop_val); 2458a3c5bd6dSspeer switch (token) { 2459a3c5bd6dSspeer case L2_CLASSIFY: 2460a3c5bd6dSspeer break; 2461a3c5bd6dSspeer case CLASSIFY: 2462a3c5bd6dSspeer case L3_CLASSIFY: 2463a3c5bd6dSspeer case L3_DISTRIBUTE: 2464a3c5bd6dSspeer case L3_TCAM: 246544961713Sgirish rdcgrp_cfg = CFG_L3_DISTRIBUTE; 2466a3c5bd6dSspeer break; 2467a3c5bd6dSspeer default: 2468a3c5bd6dSspeer rdcgrp_cfg = CFG_L3_DISTRIBUTE; 2469a3c5bd6dSspeer break; 247044961713Sgirish } 2471a3c5bd6dSspeer ddi_prop_free(prop_val); 2472a3c5bd6dSspeer } 2473a3c5bd6dSspeer break; 2474a3c5bd6dSspeer case CFG_L3_WEB: 2475a3c5bd6dSspeer case CFG_L3_DISTRIBUTE: 2476a3c5bd6dSspeer case CFG_L2_CLASSIFY: 2477a3c5bd6dSspeer case CFG_L3_TCAM: 2478a3c5bd6dSspeer rdcgrp_cfg = rx_quick_cfg; 2479a3c5bd6dSspeer break; 2480a3c5bd6dSspeer default: 2481a3c5bd6dSspeer rdcgrp_cfg = CFG_L3_DISTRIBUTE; 2482a3c5bd6dSspeer break; 248344961713Sgirish } 248444961713Sgirish 248544961713Sgirish st_rdc = p_cfgp->start_rdc; 248644961713Sgirish 248744961713Sgirish switch (rdcgrp_cfg) { 2488a3c5bd6dSspeer case CFG_L3_DISTRIBUTE: 2489a3c5bd6dSspeer case CFG_L3_WEB: 2490a3c5bd6dSspeer case CFG_L3_TCAM: 2491a3c5bd6dSspeer ndmas = p_cfgp->max_rdcs; 2492a3c5bd6dSspeer ngrps = 1; 2493a3c5bd6dSspeer rdcs_per_grp = ndmas / ngrps; 2494a3c5bd6dSspeer break; 2495a3c5bd6dSspeer case CFG_L2_CLASSIFY: 2496a3c5bd6dSspeer ndmas = p_cfgp->max_rdcs / 2; 2497a3c5bd6dSspeer if (p_cfgp->max_rdcs < 2) 2498a3c5bd6dSspeer ndmas = 1; 2499a3c5bd6dSspeer ngrps = 1; 2500a3c5bd6dSspeer rdcs_per_grp = ndmas / ngrps; 2501a3c5bd6dSspeer break; 2502a3c5bd6dSspeer default: 2503a3c5bd6dSspeer ngrps = p_cfgp->max_rdc_grpids; 2504a3c5bd6dSspeer ndmas = p_cfgp->max_rdcs; 2505a3c5bd6dSspeer rdcs_per_grp = ndmas / ngrps; 2506a3c5bd6dSspeer break; 250744961713Sgirish } 250844961713Sgirish 250944961713Sgirish for (i = 0; i < ngrps; i++) { 2510678453a8Sspeer uint8_t count = rdcs_per_grp; 2511678453a8Sspeer dc_map_t map = 0; 2512678453a8Sspeer 2513678453a8Sspeer rdc_grp_p = &p_dma_cfgp->rdc_grps[ 2514*52ccf843Smisaki p_cfgp->def_mac_rxdma_grpid + i]; 251544961713Sgirish rdc_grp_p->start_rdc = st_rdc + i * rdcs_per_grp; 251644961713Sgirish rdc_grp_p->max_rdcs = rdcs_per_grp; 2517678453a8Sspeer rdc_grp_p->def_rdc = rdc_grp_p->start_rdc; 251844961713Sgirish 251944961713Sgirish /* default to: 0, 1, 2, 3, ...., 0, 1, 2, 3.... */ 2520678453a8Sspeer while (count) { 2521678453a8Sspeer map |= (1 << count); 2522678453a8Sspeer count--; 252344961713Sgirish } 2524678453a8Sspeer map >>= 1; /* In case <start_rdc> is zero (0) */ 2525678453a8Sspeer map <<= rdc_grp_p->start_rdc; 2526678453a8Sspeer rdc_grp_p->map = map; 2527678453a8Sspeer 2528678453a8Sspeer nxgep->rx_set.owned.map |= map; /* Owned, & not shared. */ 2529678453a8Sspeer 2530678453a8Sspeer group = (nxge_grp_t *)nxge_grp_add(nxgep, NXGE_RECEIVE_GROUP); 2531678453a8Sspeer group->map = rdc_grp_p->map; 2532678453a8Sspeer 2533678453a8Sspeer rdc_grp_p->config_method = RDC_TABLE_ENTRY_METHOD_SEQ; 2534678453a8Sspeer rdc_grp_p->flag = 1; /* This group has been configured. */ 253544961713Sgirish } 253644961713Sgirish 2537678453a8Sspeer 253844961713Sgirish /* default RDC */ 2539a3c5bd6dSspeer p_cfgp->def_rdc = p_cfgp->start_rdc; 254044961713Sgirish nxgep->def_rdc = p_cfgp->start_rdc; 254144961713Sgirish 254244961713Sgirish /* full 18 byte header ? */ 2543a3c5bd6dSspeer p_dma_cfgp->rcr_full_header = NXGE_RCR_FULL_HEADER; 254444961713Sgirish p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_10G; 254544961713Sgirish if (nxgep->function_num > 1) 254644961713Sgirish p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_1G; 254744961713Sgirish p_dma_cfgp->rbr_size = nxge_rbr_size; 2548a3c5bd6dSspeer p_dma_cfgp->rcr_size = nxge_rcr_size; 254944961713Sgirish 255044961713Sgirish nxge_set_rdc_intr_property(nxgep); 255144961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_dma_config")); 255244961713Sgirish } 255344961713Sgirish 255444961713Sgirish boolean_t 255544961713Sgirish nxge_check_rxdma_port_member(p_nxge_t nxgep, uint8_t rdc) 255644961713Sgirish { 2557a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 2558a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 255944961713Sgirish int status = B_TRUE; 2560a3c5bd6dSspeer 256144961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rxdma_port_member")); 256244961713Sgirish 256344961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 256444961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 256544961713Sgirish 256644961713Sgirish /* Receive DMA Channels */ 256744961713Sgirish if (rdc < p_cfgp->max_rdcs) 256844961713Sgirish status = B_TRUE; 256944961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rxdma_port_member")); 257044961713Sgirish return (status); 257144961713Sgirish } 257244961713Sgirish 257344961713Sgirish boolean_t 257444961713Sgirish nxge_check_txdma_port_member(p_nxge_t nxgep, uint8_t tdc) 257544961713Sgirish { 257644961713Sgirish int status = B_FALSE; 2577a3c5bd6dSspeer 2578678453a8Sspeer NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_txdma_port_member")); 257944961713Sgirish 2580678453a8Sspeer if (tdc >= nxgep->pt_config.hw_config.tdc.start && 2581678453a8Sspeer tdc < nxgep->pt_config.hw_config.tdc.count) 258244961713Sgirish status = B_TRUE; 2583678453a8Sspeer 2584678453a8Sspeer NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_txdma_port_member")); 2585a3c5bd6dSspeer return (status); 258644961713Sgirish } 258744961713Sgirish 258844961713Sgirish boolean_t 258944961713Sgirish nxge_check_rxdma_rdcgrp_member(p_nxge_t nxgep, uint8_t rdc_grp, uint8_t rdc) 259044961713Sgirish { 2591a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 259244961713Sgirish int status = B_TRUE; 2593a3c5bd6dSspeer p_nxge_rdc_grp_t rdc_grp_p; 259444961713Sgirish 259544961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2596*52ccf843Smisaki " ==> nxge_check_rxdma_rdcgrp_member")); 259744961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " nxge_check_rxdma_rdcgrp_member" 2598*52ccf843Smisaki " rdc %d group %d", rdc, rdc_grp)); 259944961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 260044961713Sgirish 260144961713Sgirish rdc_grp_p = &p_dma_cfgp->rdc_grps[rdc_grp]; 2602a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " max %d ", rdc_grp_p->max_rdcs)); 260344961713Sgirish if (rdc >= rdc_grp_p->max_rdcs) { 260444961713Sgirish status = B_FALSE; 260544961713Sgirish } 260644961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2607*52ccf843Smisaki " <== nxge_check_rxdma_rdcgrp_member")); 260844961713Sgirish return (status); 260944961713Sgirish } 261044961713Sgirish 261144961713Sgirish boolean_t 261244961713Sgirish nxge_check_rdcgrp_port_member(p_nxge_t nxgep, uint8_t rdc_grp) 261344961713Sgirish { 2614a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 2615a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 261644961713Sgirish int status = B_TRUE; 261744961713Sgirish 261844961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rdcgrp_port_member")); 261944961713Sgirish 262044961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 262144961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 262244961713Sgirish 262344961713Sgirish if (rdc_grp >= p_cfgp->max_rdc_grpids) 262444961713Sgirish status = B_FALSE; 262544961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rdcgrp_port_member")); 262644961713Sgirish return (status); 262744961713Sgirish } 262844961713Sgirish 262944961713Sgirish static void 263044961713Sgirish nxge_set_hw_vlan_class_config(p_nxge_t nxgep) 263144961713Sgirish { 2632a3c5bd6dSspeer int i; 2633a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 2634a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 263544961713Sgirish p_nxge_param_t param_arr; 263644961713Sgirish uint_t vlan_cnt; 263744961713Sgirish int *vlan_cfg_val; 263844961713Sgirish nxge_param_map_t *vmap; 263944961713Sgirish char *prop; 2640a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 264144961713Sgirish uint32_t good_cfg[32]; 264244961713Sgirish int good_count = 0; 2643a3c5bd6dSspeer nxge_mv_cfg_t *vlan_tbl; 264444961713Sgirish 264544961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_vlan_config")); 264644961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 264744961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 264844961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 264944961713Sgirish 265044961713Sgirish param_arr = nxgep->param_arr; 265144961713Sgirish prop = param_arr[param_vlan_2rdc_grp].fcode_name; 265244961713Sgirish 2653a3c5bd6dSspeer /* 2654a3c5bd6dSspeer * By default, VLAN to RDC group mapping is disabled Need to read HW or 2655a3c5bd6dSspeer * .conf properties to find out if mapping is required 2656a3c5bd6dSspeer * 2657a3c5bd6dSspeer * Format 2658a3c5bd6dSspeer * 2659a3c5bd6dSspeer * uint32_t array, each array entry specifying the VLAN id and the 2660a3c5bd6dSspeer * mapping 2661a3c5bd6dSspeer * 2662a3c5bd6dSspeer * bit[30] = add bit[29] = remove bit[28] = preference bits[23-16] = 2663a3c5bd6dSspeer * rdcgrp bits[15-0] = VLAN ID ( ) 2664a3c5bd6dSspeer */ 2665a3c5bd6dSspeer 266644961713Sgirish for (i = 0; i < NXGE_MAX_VLANS; i++) { 266744961713Sgirish p_class_cfgp->vlan_tbl[i].flag = 0; 266844961713Sgirish } 266944961713Sgirish 267044961713Sgirish vlan_tbl = (nxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0]; 267144961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2672*52ccf843Smisaki &vlan_cfg_val, &vlan_cnt) == DDI_PROP_SUCCESS) { 267344961713Sgirish for (i = 0; i < vlan_cnt; i++) { 267444961713Sgirish vmap = (nxge_param_map_t *)&vlan_cfg_val[i]; 267544961713Sgirish if ((vmap->param_id) && 2676*52ccf843Smisaki (vmap->param_id < NXGE_MAX_VLANS) && 2677*52ccf843Smisaki (vmap->map_to < 2678*52ccf843Smisaki p_cfgp->max_rdc_grpids) && 2679*52ccf843Smisaki (vmap->map_to >= (uint8_t)0)) { 268044961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2681*52ccf843Smisaki " nxge_vlan_config mapping" 2682*52ccf843Smisaki " id %d grp %d", 2683*52ccf843Smisaki vmap->param_id, vmap->map_to)); 268444961713Sgirish good_cfg[good_count] = vlan_cfg_val[i]; 268544961713Sgirish if (vlan_tbl[vmap->param_id].flag == 0) 268644961713Sgirish good_count++; 268744961713Sgirish vlan_tbl[vmap->param_id].flag = 1; 268844961713Sgirish vlan_tbl[vmap->param_id].rdctbl = 2689678453a8Sspeer vmap->map_to + p_cfgp->def_mac_rxdma_grpid; 269044961713Sgirish vlan_tbl[vmap->param_id].mpr_npr = vmap->pref; 269144961713Sgirish } 269244961713Sgirish } 269344961713Sgirish ddi_prop_free(vlan_cfg_val); 269444961713Sgirish if (good_count != vlan_cnt) { 2695a3c5bd6dSspeer (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2696*52ccf843Smisaki nxgep->dip, prop, (int *)good_cfg, good_count); 269744961713Sgirish } 269844961713Sgirish } 2699a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_vlan_config")); 270044961713Sgirish } 270144961713Sgirish 270244961713Sgirish static void 270344961713Sgirish nxge_set_hw_mac_class_config(p_nxge_t nxgep) 270444961713Sgirish { 2705a3c5bd6dSspeer int i; 2706a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 2707a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 270844961713Sgirish p_nxge_param_t param_arr; 270944961713Sgirish uint_t mac_cnt; 271044961713Sgirish int *mac_cfg_val; 271144961713Sgirish nxge_param_map_t *mac_map; 271244961713Sgirish char *prop; 2713a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 271444961713Sgirish int good_count = 0; 271544961713Sgirish int good_cfg[NXGE_MAX_MACS]; 2716a3c5bd6dSspeer nxge_mv_cfg_t *mac_host_info; 2717a3c5bd6dSspeer 271844961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_mac_config")); 271944961713Sgirish 272044961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 272144961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 272244961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2723a3c5bd6dSspeer mac_host_info = (nxge_mv_cfg_t *)&p_class_cfgp->mac_host_info[0]; 272444961713Sgirish 272544961713Sgirish param_arr = nxgep->param_arr; 272644961713Sgirish prop = param_arr[param_mac_2rdc_grp].fcode_name; 272744961713Sgirish 272844961713Sgirish for (i = 0; i < NXGE_MAX_MACS; i++) { 272944961713Sgirish p_class_cfgp->mac_host_info[i].flag = 0; 27307b9fa28bSspeer p_class_cfgp->mac_host_info[i].rdctbl = 27317b9fa28bSspeer p_cfgp->def_mac_rxdma_grpid; 273244961713Sgirish } 273344961713Sgirish 273444961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2735*52ccf843Smisaki &mac_cfg_val, &mac_cnt) == DDI_PROP_SUCCESS) { 273644961713Sgirish for (i = 0; i < mac_cnt; i++) { 273744961713Sgirish mac_map = (nxge_param_map_t *)&mac_cfg_val[i]; 273844961713Sgirish if ((mac_map->param_id < p_cfgp->max_macs) && 2739*52ccf843Smisaki (mac_map->map_to < 2740*52ccf843Smisaki p_cfgp->max_rdc_grpids) && 2741*52ccf843Smisaki (mac_map->map_to >= (uint8_t)0)) { 274244961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG2_CTL, 2743*52ccf843Smisaki " nxge_mac_config mapping" 2744*52ccf843Smisaki " id %d grp %d", 2745*52ccf843Smisaki mac_map->param_id, mac_map->map_to)); 274644961713Sgirish mac_host_info[mac_map->param_id].mpr_npr = 2747*52ccf843Smisaki mac_map->pref; 274844961713Sgirish mac_host_info[mac_map->param_id].rdctbl = 2749*52ccf843Smisaki mac_map->map_to + 2750*52ccf843Smisaki p_cfgp->def_mac_rxdma_grpid; 275144961713Sgirish good_cfg[good_count] = mac_cfg_val[i]; 275244961713Sgirish if (mac_host_info[mac_map->param_id].flag == 0) 275344961713Sgirish good_count++; 275444961713Sgirish mac_host_info[mac_map->param_id].flag = 1; 275544961713Sgirish } 275644961713Sgirish } 275744961713Sgirish ddi_prop_free(mac_cfg_val); 275844961713Sgirish if (good_count != mac_cnt) { 2759a3c5bd6dSspeer (void) ddi_prop_update_int_array(DDI_DEV_T_NONE, 2760*52ccf843Smisaki nxgep->dip, prop, good_cfg, good_count); 276144961713Sgirish } 276244961713Sgirish } 2763a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_mac_config")); 276444961713Sgirish } 276544961713Sgirish 276644961713Sgirish static void 276744961713Sgirish nxge_set_hw_class_config(p_nxge_t nxgep) 276844961713Sgirish { 2769a3c5bd6dSspeer int i; 277044961713Sgirish p_nxge_param_t param_arr; 277144961713Sgirish int *int_prop_val; 277244961713Sgirish uint32_t cfg_value; 277344961713Sgirish char *prop; 2774a3c5bd6dSspeer p_nxge_class_pt_cfg_t p_class_cfgp; 277544961713Sgirish int start_prop, end_prop; 277644961713Sgirish uint_t prop_cnt; 2777a3c5bd6dSspeer 277844961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_class_config")); 277944961713Sgirish 278044961713Sgirish p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 278144961713Sgirish param_arr = nxgep->param_arr; 2782a3c5bd6dSspeer start_prop = param_class_opt_ip_usr4; 278344961713Sgirish end_prop = param_class_opt_ipv6_sctp; 278444961713Sgirish 278544961713Sgirish for (i = start_prop; i <= end_prop; i++) { 278644961713Sgirish prop = param_arr[i].fcode_name; 278744961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 2788*52ccf843Smisaki 0, prop, &int_prop_val, 2789*52ccf843Smisaki &prop_cnt) == DDI_PROP_SUCCESS) { 2790a3c5bd6dSspeer cfg_value = (uint32_t)*int_prop_val; 279144961713Sgirish ddi_prop_free(int_prop_val); 279244961713Sgirish } else { 279344961713Sgirish cfg_value = (uint32_t)param_arr[i].value; 279444961713Sgirish } 279544961713Sgirish p_class_cfgp->class_cfg[i - start_prop] = cfg_value; 279644961713Sgirish } 279744961713Sgirish 279844961713Sgirish prop = param_arr[param_h1_init_value].fcode_name; 279944961713Sgirish 280044961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2801*52ccf843Smisaki &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) { 2802a3c5bd6dSspeer cfg_value = (uint32_t)*int_prop_val; 2803a3c5bd6dSspeer ddi_prop_free(int_prop_val); 280444961713Sgirish } else { 280544961713Sgirish cfg_value = (uint32_t)param_arr[param_h1_init_value].value; 280644961713Sgirish } 280744961713Sgirish 280844961713Sgirish p_class_cfgp->init_h1 = (uint32_t)cfg_value; 280944961713Sgirish prop = param_arr[param_h2_init_value].fcode_name; 281044961713Sgirish 281144961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop, 2812*52ccf843Smisaki &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) { 2813a3c5bd6dSspeer cfg_value = (uint32_t)*int_prop_val; 2814a3c5bd6dSspeer ddi_prop_free(int_prop_val); 281544961713Sgirish } else { 281644961713Sgirish cfg_value = (uint32_t)param_arr[param_h2_init_value].value; 281744961713Sgirish } 281844961713Sgirish 281944961713Sgirish p_class_cfgp->init_h2 = (uint16_t)cfg_value; 282044961713Sgirish NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_class_config")); 282144961713Sgirish } 282244961713Sgirish 282344961713Sgirish nxge_status_t 282444961713Sgirish nxge_ldgv_init_n2(p_nxge_t nxgep, int *navail_p, int *nrequired_p) 282544961713Sgirish { 2826678453a8Sspeer int i, maxldvs, maxldgs, nldvs; 2827a3c5bd6dSspeer int ldv, endldg; 2828a3c5bd6dSspeer uint8_t func; 2829a3c5bd6dSspeer uint8_t channel; 2830a3c5bd6dSspeer uint8_t chn_start; 2831a3c5bd6dSspeer boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE; 2832a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 2833a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 2834a3c5bd6dSspeer p_nxge_ldgv_t ldgvp; 2835a3c5bd6dSspeer p_nxge_ldg_t ldgp, ptr; 2836a3c5bd6dSspeer p_nxge_ldv_t ldvp; 2837a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 2838678453a8Sspeer nxge_grp_set_t *set; 283944961713Sgirish 284044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2")); 284144961713Sgirish if (!*navail_p) { 284244961713Sgirish *nrequired_p = 0; 284344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2844*52ccf843Smisaki "<== nxge_ldgv_init:no avail")); 284544961713Sgirish return (NXGE_ERROR); 284644961713Sgirish } 284744961713Sgirish /* 2848a3c5bd6dSspeer * N2/NIU: one logical device owns one logical group. and each 2849a3c5bd6dSspeer * device/group will be assigned one vector by Hypervisor. 285044961713Sgirish */ 285144961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 285244961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 285344961713Sgirish maxldgs = p_cfgp->max_ldgs; 285444961713Sgirish if (!maxldgs) { 285544961713Sgirish /* No devices configured. */ 285644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init_n2: " 2857*52ccf843Smisaki "no logical groups configured.")); 285844961713Sgirish return (NXGE_ERROR); 285944961713Sgirish } else { 286044961713Sgirish maxldvs = maxldgs + 1; 286144961713Sgirish } 286244961713Sgirish 286344961713Sgirish /* 2864a3c5bd6dSspeer * If function zero instance, it needs to handle the system and MIF 2865a3c5bd6dSspeer * error interrupts. MIF interrupt may not be needed for N2/NIU. 286644961713Sgirish */ 286744961713Sgirish func = nxgep->function_num; 286844961713Sgirish if (func == 0) { 286944961713Sgirish own_sys_err = B_TRUE; 287044961713Sgirish if (!p_cfgp->ser_ldvid) { 287144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2872*52ccf843Smisaki "nxge_ldgv_init_n2: func 0, ERR ID not set!")); 287344961713Sgirish } 287444961713Sgirish /* MIF interrupt */ 287544961713Sgirish if (!p_cfgp->mif_ldvid) { 287644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2877*52ccf843Smisaki "nxge_ldgv_init_n2: func 0, MIF ID not set!")); 287844961713Sgirish } 287944961713Sgirish } 288044961713Sgirish 288144961713Sgirish /* 288244961713Sgirish * Assume single partition, each function owns mac. 288344961713Sgirish */ 2884a3c5bd6dSspeer if (!nxge_use_partition) 288544961713Sgirish own_fzc = B_TRUE; 288644961713Sgirish 288744961713Sgirish ldgvp = nxgep->ldgvp; 288844961713Sgirish if (ldgvp == NULL) { 288944961713Sgirish ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP); 289044961713Sgirish nxgep->ldgvp = ldgvp; 289144961713Sgirish ldgvp->maxldgs = (uint8_t)maxldgs; 289244961713Sgirish ldgvp->maxldvs = (uint8_t)maxldvs; 2893678453a8Sspeer ldgp = ldgvp->ldgp = KMEM_ZALLOC( 2894*52ccf843Smisaki sizeof (nxge_ldg_t) * maxldgs, KM_SLEEP); 2895678453a8Sspeer ldvp = ldgvp->ldvp = KMEM_ZALLOC( 2896*52ccf843Smisaki sizeof (nxge_ldv_t) * maxldvs, KM_SLEEP); 289744961713Sgirish } else { 289844961713Sgirish ldgp = ldgvp->ldgp; 289944961713Sgirish ldvp = ldgvp->ldvp; 290044961713Sgirish } 290144961713Sgirish 2902678453a8Sspeer ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 290344961713Sgirish ldgvp->tmres = NXGE_TIMER_RESO; 290444961713Sgirish 290544961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 2906*52ccf843Smisaki "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d", 2907*52ccf843Smisaki maxldvs, maxldgs)); 2908a3c5bd6dSspeer 290944961713Sgirish /* logical start_ldg is ldv */ 291044961713Sgirish ptr = ldgp; 291144961713Sgirish for (i = 0; i < maxldgs; i++) { 291244961713Sgirish ptr->func = func; 291344961713Sgirish ptr->arm = B_TRUE; 291444961713Sgirish ptr->vldg_index = (uint8_t)i; 291544961713Sgirish ptr->ldg_timer = NXGE_TIMER_LDG; 291644961713Sgirish ptr->ldg = p_cfgp->ldg[i]; 291744961713Sgirish ptr->sys_intr_handler = nxge_intr; 291844961713Sgirish ptr->nldvs = 0; 291944961713Sgirish ptr->ldvp = NULL; 292044961713Sgirish ptr->nxgep = nxgep; 292144961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 2922*52ccf843Smisaki "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d " 2923*52ccf843Smisaki "ldg %d ldgptr $%p", 2924*52ccf843Smisaki maxldvs, maxldgs, ptr->ldg, ptr)); 292544961713Sgirish ptr++; 292644961713Sgirish } 292744961713Sgirish 292844961713Sgirish endldg = NXGE_INT_MAX_LDG; 292944961713Sgirish nldvs = 0; 293044961713Sgirish ldgvp->nldvs = 0; 293144961713Sgirish ldgp->ldvp = NULL; 293244961713Sgirish *nrequired_p = 0; 293344961713Sgirish 293444961713Sgirish /* 2935a3c5bd6dSspeer * logical device group table is organized in the following order (same 2936a3c5bd6dSspeer * as what interrupt property has). function 0: owns MAC, MIF, error, 2937a3c5bd6dSspeer * rx, tx. function 1: owns MAC, rx, tx. 293844961713Sgirish */ 293944961713Sgirish 294044961713Sgirish if (own_fzc && p_cfgp->mac_ldvid) { 294144961713Sgirish /* Each function should own MAC interrupt */ 294244961713Sgirish ldv = p_cfgp->mac_ldvid; 294344961713Sgirish ldvp->ldv = (uint8_t)ldv; 294444961713Sgirish ldvp->is_mac = B_TRUE; 294544961713Sgirish ldvp->ldv_intr_handler = nxge_mac_intr; 294644961713Sgirish ldvp->ldv_ldf_masks = 0; 294744961713Sgirish ldvp->nxgep = nxgep; 294844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 2949*52ccf843Smisaki "==> nxge_ldgv_init_n2(mac): maxldvs %d ldv %d " 2950*52ccf843Smisaki "ldg %d ldgptr $%p ldvptr $%p", 2951*52ccf843Smisaki maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 295244961713Sgirish nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 295344961713Sgirish nldvs++; 295444961713Sgirish } 295544961713Sgirish 295644961713Sgirish if (own_fzc && p_cfgp->mif_ldvid) { 295744961713Sgirish ldv = p_cfgp->mif_ldvid; 295844961713Sgirish ldvp->ldv = (uint8_t)ldv; 295944961713Sgirish ldvp->is_mif = B_TRUE; 296044961713Sgirish ldvp->ldv_intr_handler = nxge_mif_intr; 296144961713Sgirish ldvp->ldv_ldf_masks = 0; 296244961713Sgirish ldvp->nxgep = nxgep; 296344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 2964*52ccf843Smisaki "==> nxge_ldgv_init_n2(mif): maxldvs %d ldv %d " 2965*52ccf843Smisaki "ldg %d ldgptr $%p ldvptr $%p", 2966*52ccf843Smisaki maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 296744961713Sgirish nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 296844961713Sgirish nldvs++; 296944961713Sgirish } 297044961713Sgirish 297144961713Sgirish ldv = NXGE_SYS_ERROR_LD; 297244961713Sgirish ldvp->use_timer = B_TRUE; 297344961713Sgirish if (own_sys_err && p_cfgp->ser_ldvid) { 297444961713Sgirish ldv = p_cfgp->ser_ldvid; 297544961713Sgirish /* 297644961713Sgirish * Unmask the system interrupt states. 297744961713Sgirish */ 297844961713Sgirish (void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK | 2979*52ccf843Smisaki SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK | 2980*52ccf843Smisaki SYS_ERR_ZCP_MASK); 298144961713Sgirish } 298244961713Sgirish ldvp->ldv = (uint8_t)ldv; 298344961713Sgirish ldvp->is_syserr = B_TRUE; 298444961713Sgirish ldvp->ldv_intr_handler = nxge_syserr_intr; 298544961713Sgirish ldvp->ldv_ldf_masks = 0; 298644961713Sgirish ldvp->nxgep = nxgep; 298744961713Sgirish ldgvp->ldvp_syserr = ldvp; 298844961713Sgirish 298944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 2990*52ccf843Smisaki "==> nxge_ldgv_init_n2(syserr): maxldvs %d ldv %d " 2991*52ccf843Smisaki "ldg %d ldgptr $%p ldvptr p%p", 2992*52ccf843Smisaki maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 299344961713Sgirish 299414ea4bb7Ssd if (own_sys_err && p_cfgp->ser_ldvid) { 299544961713Sgirish (void) nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 299644961713Sgirish } else { 299744961713Sgirish ldvp++; 299844961713Sgirish } 299944961713Sgirish 300044961713Sgirish nldvs++; 300144961713Sgirish 300244961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3003*52ccf843Smisaki "(before rx) func %d nldvs %d navail %d nrequired %d", 3004*52ccf843Smisaki func, nldvs, *navail_p, *nrequired_p)); 300544961713Sgirish 300644961713Sgirish /* 300744961713Sgirish * Start with RDC to configure logical devices for each group. 300844961713Sgirish */ 3009678453a8Sspeer chn_start = p_cfgp->ldg_chn_start; 3010678453a8Sspeer set = &nxgep->rx_set; 3011678453a8Sspeer for (channel = 0; channel < NXGE_MAX_RDCS; channel++) { 3012678453a8Sspeer if ((1 << channel) & set->owned.map) { 3013678453a8Sspeer ldvp->is_rxdma = B_TRUE; 3014678453a8Sspeer ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START; 3015678453a8Sspeer ldvp->channel = channel; 3016678453a8Sspeer ldvp->vdma_index = (uint8_t)channel; 3017678453a8Sspeer ldvp->ldv_intr_handler = nxge_rx_intr; 3018678453a8Sspeer ldvp->ldv_ldf_masks = 0; 3019678453a8Sspeer ldvp->nxgep = nxgep; 3020678453a8Sspeer ldgp->ldg = p_cfgp->ldg[chn_start]; 3021678453a8Sspeer 3022678453a8Sspeer NXGE_DEBUG_MSG((nxgep, INT_CTL, 3023678453a8Sspeer "==> nxge_ldgv_init_n2(rx%d): maxldvs %d ldv %d " 3024678453a8Sspeer "ldg %d ldgptr 0x%016llx ldvptr 0x%016llx", 3025678453a8Sspeer i, maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3026678453a8Sspeer nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3027678453a8Sspeer endldg, nrequired_p); 3028678453a8Sspeer nldvs++; 3029678453a8Sspeer chn_start++; 3030678453a8Sspeer } 303144961713Sgirish } 303244961713Sgirish 303344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3034*52ccf843Smisaki "func %d nldvs %d navail %d nrequired %d", 3035*52ccf843Smisaki func, nldvs, *navail_p, *nrequired_p)); 303644961713Sgirish 303744961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3038*52ccf843Smisaki "func %d nldvs %d navail %d nrequired %d ldgp 0x%llx " 3039*52ccf843Smisaki "ldvp 0x%llx", 3040*52ccf843Smisaki func, nldvs, *navail_p, *nrequired_p, ldgp, ldvp)); 304144961713Sgirish /* 304244961713Sgirish * Transmit DMA channels. 304344961713Sgirish */ 3044678453a8Sspeer chn_start = p_cfgp->ldg_chn_start + 8; 3045678453a8Sspeer set = &nxgep->tx_set; 3046678453a8Sspeer for (channel = 0; channel < NXGE_MAX_TDCS; channel++) { 3047678453a8Sspeer if ((1 << channel) & set->owned.map) { 3048678453a8Sspeer ldvp->is_txdma = B_TRUE; 3049678453a8Sspeer ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START; 3050678453a8Sspeer ldvp->channel = channel; 3051678453a8Sspeer ldvp->vdma_index = (uint8_t)channel; 3052678453a8Sspeer ldvp->ldv_intr_handler = nxge_tx_intr; 3053678453a8Sspeer ldvp->ldv_ldf_masks = 0; 3054678453a8Sspeer ldgp->ldg = p_cfgp->ldg[chn_start]; 3055678453a8Sspeer ldvp->nxgep = nxgep; 3056678453a8Sspeer NXGE_DEBUG_MSG((nxgep, INT_CTL, 3057678453a8Sspeer "==> nxge_ldgv_init_n2(tx%d): maxldvs %d ldv %d " 3058678453a8Sspeer "ldg %d ldgptr %p ldvptr %p", 3059678453a8Sspeer channel, maxldvs, ldv, ldgp->ldg, ldgp, ldvp)); 3060678453a8Sspeer nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3061678453a8Sspeer endldg, nrequired_p); 3062678453a8Sspeer nldvs++; 3063678453a8Sspeer chn_start++; 3064678453a8Sspeer } 306544961713Sgirish } 306644961713Sgirish 306744961713Sgirish ldgvp->ldg_intrs = *nrequired_p; 306844961713Sgirish ldgvp->nldvs = (uint8_t)nldvs; 306944961713Sgirish 307044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: " 3071*52ccf843Smisaki "func %d nldvs %d maxgrps %d navail %d nrequired %d", 3072*52ccf843Smisaki func, nldvs, maxldgs, *navail_p, *nrequired_p)); 307344961713Sgirish 307444961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init_n2")); 307544961713Sgirish return (status); 307644961713Sgirish } 307744961713Sgirish 307844961713Sgirish /* 307944961713Sgirish * Interrupts related interface functions. 308044961713Sgirish */ 3081a3c5bd6dSspeer 308244961713Sgirish nxge_status_t 308344961713Sgirish nxge_ldgv_init(p_nxge_t nxgep, int *navail_p, int *nrequired_p) 308444961713Sgirish { 3085678453a8Sspeer int i, maxldvs, maxldgs, nldvs; 3086a3c5bd6dSspeer int ldv, ldg, endldg, ngrps; 3087a3c5bd6dSspeer uint8_t func; 3088a3c5bd6dSspeer uint8_t channel; 3089a3c5bd6dSspeer boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE; 3090a3c5bd6dSspeer p_nxge_dma_pt_cfg_t p_dma_cfgp; 3091a3c5bd6dSspeer p_nxge_hw_pt_cfg_t p_cfgp; 3092a3c5bd6dSspeer p_nxge_ldgv_t ldgvp; 3093a3c5bd6dSspeer p_nxge_ldg_t ldgp, ptr; 3094a3c5bd6dSspeer p_nxge_ldv_t ldvp; 3095678453a8Sspeer nxge_grp_set_t *set; 3096678453a8Sspeer 3097a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 309844961713Sgirish 309944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init")); 310044961713Sgirish if (!*navail_p) { 310144961713Sgirish *nrequired_p = 0; 310244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3103*52ccf843Smisaki "<== nxge_ldgv_init:no avail")); 310444961713Sgirish return (NXGE_ERROR); 310544961713Sgirish } 310644961713Sgirish p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 310744961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 310844961713Sgirish 3109678453a8Sspeer nldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 311044961713Sgirish 311144961713Sgirish /* 3112a3c5bd6dSspeer * If function zero instance, it needs to handle the system error 3113a3c5bd6dSspeer * interrupts. 311444961713Sgirish */ 311544961713Sgirish func = nxgep->function_num; 311644961713Sgirish if (func == 0) { 311744961713Sgirish nldvs++; 311844961713Sgirish own_sys_err = B_TRUE; 311944961713Sgirish } else { 312044961713Sgirish /* use timer */ 312144961713Sgirish nldvs++; 312244961713Sgirish } 312344961713Sgirish 312444961713Sgirish /* 312544961713Sgirish * Assume single partition, each function owns mac. 312644961713Sgirish */ 312744961713Sgirish if (!nxge_use_partition) { 312844961713Sgirish /* mac */ 312944961713Sgirish nldvs++; 313044961713Sgirish /* MIF */ 313144961713Sgirish nldvs++; 313244961713Sgirish own_fzc = B_TRUE; 313344961713Sgirish } 313444961713Sgirish maxldvs = nldvs; 313544961713Sgirish maxldgs = p_cfgp->max_ldgs; 313644961713Sgirish if (!maxldvs || !maxldgs) { 313744961713Sgirish /* No devices configured. */ 313844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init: " 3139*52ccf843Smisaki "no logical devices or groups configured.")); 314044961713Sgirish return (NXGE_ERROR); 314144961713Sgirish } 314244961713Sgirish ldgvp = nxgep->ldgvp; 314344961713Sgirish if (ldgvp == NULL) { 314444961713Sgirish ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP); 314544961713Sgirish nxgep->ldgvp = ldgvp; 314644961713Sgirish ldgvp->maxldgs = (uint8_t)maxldgs; 314744961713Sgirish ldgvp->maxldvs = (uint8_t)maxldvs; 314844961713Sgirish ldgp = ldgvp->ldgp = KMEM_ZALLOC(sizeof (nxge_ldg_t) * maxldgs, 3149*52ccf843Smisaki KM_SLEEP); 315044961713Sgirish ldvp = ldgvp->ldvp = KMEM_ZALLOC(sizeof (nxge_ldv_t) * maxldvs, 3151*52ccf843Smisaki KM_SLEEP); 315244961713Sgirish } 3153678453a8Sspeer ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs; 315444961713Sgirish ldgvp->tmres = NXGE_TIMER_RESO; 315544961713Sgirish 315644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3157*52ccf843Smisaki "==> nxge_ldgv_init: maxldvs %d maxldgs %d nldvs %d", 3158*52ccf843Smisaki maxldvs, maxldgs, nldvs)); 315944961713Sgirish ldg = p_cfgp->start_ldg; 316044961713Sgirish ptr = ldgp; 316144961713Sgirish for (i = 0; i < maxldgs; i++) { 316244961713Sgirish ptr->func = func; 316344961713Sgirish ptr->arm = B_TRUE; 316444961713Sgirish ptr->vldg_index = (uint8_t)i; 316544961713Sgirish ptr->ldg_timer = NXGE_TIMER_LDG; 316644961713Sgirish ptr->ldg = ldg++; 316744961713Sgirish ptr->sys_intr_handler = nxge_intr; 316844961713Sgirish ptr->nldvs = 0; 316944961713Sgirish ptr->nxgep = nxgep; 317044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3171*52ccf843Smisaki "==> nxge_ldgv_init: maxldvs %d maxldgs %d ldg %d", 3172*52ccf843Smisaki maxldvs, maxldgs, ptr->ldg)); 317344961713Sgirish ptr++; 317444961713Sgirish } 317544961713Sgirish 317644961713Sgirish ldg = p_cfgp->start_ldg; 317744961713Sgirish if (maxldgs > *navail_p) { 317844961713Sgirish ngrps = *navail_p; 317944961713Sgirish } else { 318044961713Sgirish ngrps = maxldgs; 318144961713Sgirish } 318244961713Sgirish endldg = ldg + ngrps; 318344961713Sgirish 318444961713Sgirish /* 318544961713Sgirish * Receive DMA channels. 318644961713Sgirish */ 318744961713Sgirish nldvs = 0; 318844961713Sgirish ldgvp->nldvs = 0; 318944961713Sgirish ldgp->ldvp = NULL; 319044961713Sgirish *nrequired_p = 0; 319144961713Sgirish 319244961713Sgirish /* 319344961713Sgirish * Start with RDC to configure logical devices for each group. 319444961713Sgirish */ 3195678453a8Sspeer set = &nxgep->rx_set; 3196678453a8Sspeer for (channel = 0; channel < NXGE_MAX_RDCS; channel++) { 3197678453a8Sspeer if ((1 << channel) & set->owned.map) { 3198678453a8Sspeer /* For now, <channel & <vdma_index> are the same. */ 3199678453a8Sspeer ldvp->is_rxdma = B_TRUE; 3200678453a8Sspeer ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START; 3201678453a8Sspeer ldvp->channel = channel; 3202678453a8Sspeer ldvp->vdma_index = (uint8_t)channel; 3203678453a8Sspeer ldvp->ldv_intr_handler = nxge_rx_intr; 3204678453a8Sspeer ldvp->ldv_ldf_masks = 0; 3205678453a8Sspeer ldvp->use_timer = B_FALSE; 3206678453a8Sspeer ldvp->nxgep = nxgep; 3207678453a8Sspeer nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3208678453a8Sspeer endldg, nrequired_p); 3209678453a8Sspeer nldvs++; 3210678453a8Sspeer } 321144961713Sgirish } 3212a3c5bd6dSspeer 321344961713Sgirish /* 321444961713Sgirish * Transmit DMA channels. 321544961713Sgirish */ 3216678453a8Sspeer set = &nxgep->tx_set; 3217678453a8Sspeer for (channel = 0; channel < NXGE_MAX_TDCS; channel++) { 3218678453a8Sspeer if ((1 << channel) & set->owned.map) { 3219678453a8Sspeer /* For now, <channel & <vdma_index> are the same. */ 3220678453a8Sspeer ldvp->is_txdma = B_TRUE; 3221678453a8Sspeer ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START; 3222678453a8Sspeer ldvp->channel = channel; 3223678453a8Sspeer ldvp->vdma_index = (uint8_t)channel; 3224678453a8Sspeer ldvp->ldv_intr_handler = nxge_tx_intr; 3225678453a8Sspeer ldvp->ldv_ldf_masks = 0; 3226678453a8Sspeer ldvp->use_timer = B_FALSE; 3227678453a8Sspeer ldvp->nxgep = nxgep; 3228678453a8Sspeer nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv, 3229678453a8Sspeer endldg, nrequired_p); 3230678453a8Sspeer nldvs++; 3231678453a8Sspeer } 323244961713Sgirish } 323344961713Sgirish 323444961713Sgirish if (own_fzc) { 323544961713Sgirish ldv = NXGE_MIF_LD; 323644961713Sgirish ldvp->ldv = (uint8_t)ldv; 323744961713Sgirish ldvp->is_mif = B_TRUE; 323844961713Sgirish ldvp->ldv_intr_handler = nxge_mif_intr; 323944961713Sgirish ldvp->ldv_ldf_masks = 0; 324044961713Sgirish ldvp->use_timer = B_FALSE; 324144961713Sgirish ldvp->nxgep = nxgep; 324244961713Sgirish nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 324344961713Sgirish nldvs++; 324444961713Sgirish } 324544961713Sgirish /* 324644961713Sgirish * MAC port (function zero control) 324744961713Sgirish */ 324844961713Sgirish if (own_fzc) { 324944961713Sgirish ldvp->is_mac = B_TRUE; 325044961713Sgirish ldvp->ldv_intr_handler = nxge_mac_intr; 325144961713Sgirish ldvp->ldv_ldf_masks = 0; 325244961713Sgirish ldv = func + NXGE_MAC_LD_START; 325344961713Sgirish ldvp->ldv = (uint8_t)ldv; 325444961713Sgirish ldvp->use_timer = B_FALSE; 325544961713Sgirish ldvp->nxgep = nxgep; 325644961713Sgirish nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 325744961713Sgirish nldvs++; 325844961713Sgirish } 325944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: " 3260*52ccf843Smisaki "func %d nldvs %d navail %d nrequired %d", 3261*52ccf843Smisaki func, nldvs, *navail_p, *nrequired_p)); 326244961713Sgirish /* 326344961713Sgirish * Function 0 owns system error interrupts. 326444961713Sgirish */ 326514ea4bb7Ssd ldvp->use_timer = B_TRUE; 326644961713Sgirish if (own_sys_err) { 326744961713Sgirish ldv = NXGE_SYS_ERROR_LD; 326844961713Sgirish ldvp->ldv = (uint8_t)ldv; 326944961713Sgirish ldvp->is_syserr = B_TRUE; 327044961713Sgirish ldvp->ldv_intr_handler = nxge_syserr_intr; 327144961713Sgirish ldvp->ldv_ldf_masks = 0; 327244961713Sgirish ldvp->nxgep = nxgep; 327344961713Sgirish ldgvp->ldvp_syserr = ldvp; 327444961713Sgirish /* 327544961713Sgirish * Unmask the system interrupt states. 327644961713Sgirish */ 327744961713Sgirish (void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK | 3278*52ccf843Smisaki SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK | 3279*52ccf843Smisaki SYS_ERR_ZCP_MASK); 328044961713Sgirish 328144961713Sgirish (void) nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p); 328244961713Sgirish nldvs++; 328344961713Sgirish } else { 328444961713Sgirish ldv = NXGE_SYS_ERROR_LD; 328544961713Sgirish ldvp->ldv = (uint8_t)ldv; 328644961713Sgirish ldvp->is_syserr = B_TRUE; 328744961713Sgirish ldvp->ldv_intr_handler = nxge_syserr_intr; 328844961713Sgirish ldvp->nxgep = nxgep; 328944961713Sgirish ldvp->ldv_ldf_masks = 0; 329044961713Sgirish ldgvp->ldvp_syserr = ldvp; 329144961713Sgirish } 329244961713Sgirish 329344961713Sgirish ldgvp->ldg_intrs = *nrequired_p; 329444961713Sgirish 329544961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: " 3296*52ccf843Smisaki "func %d nldvs %d navail %d nrequired %d", 3297*52ccf843Smisaki func, nldvs, *navail_p, *nrequired_p)); 329844961713Sgirish 329944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init")); 330044961713Sgirish return (status); 330144961713Sgirish } 330244961713Sgirish 330344961713Sgirish nxge_status_t 330444961713Sgirish nxge_ldgv_uninit(p_nxge_t nxgep) 330544961713Sgirish { 3306a3c5bd6dSspeer p_nxge_ldgv_t ldgvp; 330744961713Sgirish 330844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_uninit")); 330944961713Sgirish ldgvp = nxgep->ldgvp; 331044961713Sgirish if (ldgvp == NULL) { 331144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_uninit: " 3312*52ccf843Smisaki "no logical group configured.")); 331344961713Sgirish return (NXGE_OK); 331444961713Sgirish } 331544961713Sgirish if (ldgvp->ldgp) { 331644961713Sgirish KMEM_FREE(ldgvp->ldgp, sizeof (nxge_ldg_t) * ldgvp->maxldgs); 331744961713Sgirish } 331844961713Sgirish if (ldgvp->ldvp) { 331944961713Sgirish KMEM_FREE(ldgvp->ldvp, sizeof (nxge_ldv_t) * ldgvp->maxldvs); 332044961713Sgirish } 332144961713Sgirish KMEM_FREE(ldgvp, sizeof (nxge_ldgv_t)); 332244961713Sgirish nxgep->ldgvp = NULL; 332344961713Sgirish 332444961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_uninit")); 332544961713Sgirish return (NXGE_OK); 332644961713Sgirish } 332744961713Sgirish 332844961713Sgirish nxge_status_t 332944961713Sgirish nxge_intr_ldgv_init(p_nxge_t nxgep) 333044961713Sgirish { 3331a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 333244961713Sgirish 333344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_ldgv_init")); 333444961713Sgirish /* 3335a3c5bd6dSspeer * Configure the logical device group numbers, state vectors and 3336a3c5bd6dSspeer * interrupt masks for each logical device. 333744961713Sgirish */ 333844961713Sgirish status = nxge_fzc_intr_init(nxgep); 333944961713Sgirish 334044961713Sgirish /* 334144961713Sgirish * Configure logical device masks and timers. 334244961713Sgirish */ 334344961713Sgirish status = nxge_intr_mask_mgmt(nxgep); 334444961713Sgirish 334544961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_ldgv_init")); 334644961713Sgirish return (status); 334744961713Sgirish } 334844961713Sgirish 334944961713Sgirish nxge_status_t 335044961713Sgirish nxge_intr_mask_mgmt(p_nxge_t nxgep) 335144961713Sgirish { 3352a3c5bd6dSspeer p_nxge_ldgv_t ldgvp; 3353a3c5bd6dSspeer p_nxge_ldg_t ldgp; 3354a3c5bd6dSspeer p_nxge_ldv_t ldvp; 3355a3c5bd6dSspeer npi_handle_t handle; 3356a3c5bd6dSspeer int i, j; 3357a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 335844961713Sgirish 335944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_mask_mgmt")); 336044961713Sgirish 336144961713Sgirish if ((ldgvp = nxgep->ldgvp) == NULL) { 336244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3363*52ccf843Smisaki "<== nxge_intr_mask_mgmt: Null ldgvp")); 336444961713Sgirish return (NXGE_ERROR); 336544961713Sgirish } 336644961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 336744961713Sgirish ldgp = ldgvp->ldgp; 336844961713Sgirish ldvp = ldgvp->ldvp; 336944961713Sgirish if (ldgp == NULL || ldvp == NULL) { 337044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3371*52ccf843Smisaki "<== nxge_intr_mask_mgmt: Null ldgp or ldvp")); 337244961713Sgirish return (NXGE_ERROR); 337344961713Sgirish } 337444961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3375*52ccf843Smisaki "==> nxge_intr_mask_mgmt: # of intrs %d ", ldgvp->ldg_intrs)); 337644961713Sgirish /* Initialize masks. */ 337744961713Sgirish if (nxgep->niu_type != N2_NIU) { 337844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3379*52ccf843Smisaki "==> nxge_intr_mask_mgmt(Neptune): # intrs %d ", 3380*52ccf843Smisaki ldgvp->ldg_intrs)); 338144961713Sgirish for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) { 338244961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3383*52ccf843Smisaki "==> nxge_intr_mask_mgmt(Neptune): # ldv %d " 3384*52ccf843Smisaki "in group %d", ldgp->nldvs, ldgp->ldg)); 338544961713Sgirish for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 338644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3387*52ccf843Smisaki "==> nxge_intr_mask_mgmt: set ldv # %d " 3388*52ccf843Smisaki "for ldg %d", ldvp->ldv, ldgp->ldg)); 338944961713Sgirish rs = npi_intr_mask_set(handle, ldvp->ldv, 3390*52ccf843Smisaki ldvp->ldv_ldf_masks); 339144961713Sgirish if (rs != NPI_SUCCESS) { 339244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3393*52ccf843Smisaki "<== nxge_intr_mask_mgmt: " 3394*52ccf843Smisaki "set mask failed " 3395*52ccf843Smisaki " rs 0x%x ldv %d mask 0x%x", 3396*52ccf843Smisaki rs, ldvp->ldv, 3397*52ccf843Smisaki ldvp->ldv_ldf_masks)); 339844961713Sgirish return (NXGE_ERROR | rs); 339944961713Sgirish } 340044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3401*52ccf843Smisaki "==> nxge_intr_mask_mgmt: " 3402*52ccf843Smisaki "set mask OK " 3403*52ccf843Smisaki " rs 0x%x ldv %d mask 0x%x", 3404*52ccf843Smisaki rs, ldvp->ldv, 3405*52ccf843Smisaki ldvp->ldv_ldf_masks)); 340644961713Sgirish } 340744961713Sgirish } 340844961713Sgirish } 340944961713Sgirish ldgp = ldgvp->ldgp; 341044961713Sgirish /* Configure timer and arm bit */ 341144961713Sgirish for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 341244961713Sgirish rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3413*52ccf843Smisaki ldgp->arm, ldgp->ldg_timer); 341444961713Sgirish if (rs != NPI_SUCCESS) { 341544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3416*52ccf843Smisaki "<== nxge_intr_mask_mgmt: " 3417*52ccf843Smisaki "set timer failed " 3418*52ccf843Smisaki " rs 0x%x dg %d timer 0x%x", 3419*52ccf843Smisaki rs, ldgp->ldg, ldgp->ldg_timer)); 342044961713Sgirish return (NXGE_ERROR | rs); 342144961713Sgirish } 342244961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3423*52ccf843Smisaki "==> nxge_intr_mask_mgmt: " 3424*52ccf843Smisaki "set timer OK " 3425*52ccf843Smisaki " rs 0x%x ldg %d timer 0x%x", 3426*52ccf843Smisaki rs, ldgp->ldg, ldgp->ldg_timer)); 342744961713Sgirish } 342844961713Sgirish 342944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_mask_mgmt")); 343044961713Sgirish return (NXGE_OK); 343144961713Sgirish } 343244961713Sgirish 343344961713Sgirish nxge_status_t 343444961713Sgirish nxge_intr_mask_mgmt_set(p_nxge_t nxgep, boolean_t on) 343544961713Sgirish { 3436a3c5bd6dSspeer p_nxge_ldgv_t ldgvp; 3437a3c5bd6dSspeer p_nxge_ldg_t ldgp; 3438a3c5bd6dSspeer p_nxge_ldv_t ldvp; 3439a3c5bd6dSspeer npi_handle_t handle; 3440a3c5bd6dSspeer int i, j; 3441a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 344244961713Sgirish 344344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3444*52ccf843Smisaki "==> nxge_intr_mask_mgmt_set (%d)", on)); 344544961713Sgirish 344644961713Sgirish if (nxgep->niu_type == N2_NIU) { 344744961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3448*52ccf843Smisaki "<== nxge_intr_mask_mgmt_set (%d) not set (N2/NIU)", 3449*52ccf843Smisaki on)); 345044961713Sgirish return (NXGE_ERROR); 345144961713Sgirish } 3452a3c5bd6dSspeer 345344961713Sgirish if ((ldgvp = nxgep->ldgvp) == NULL) { 345444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3455*52ccf843Smisaki "==> nxge_intr_mask_mgmt_set: Null ldgvp")); 345644961713Sgirish return (NXGE_ERROR); 345744961713Sgirish } 3458a3c5bd6dSspeer 345944961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 346044961713Sgirish ldgp = ldgvp->ldgp; 346144961713Sgirish ldvp = ldgvp->ldvp; 346244961713Sgirish if (ldgp == NULL || ldvp == NULL) { 346344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3464*52ccf843Smisaki "<== nxge_intr_mask_mgmt_set: Null ldgp or ldvp")); 346544961713Sgirish return (NXGE_ERROR); 346644961713Sgirish } 346744961713Sgirish /* set masks. */ 346844961713Sgirish for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) { 346944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3470*52ccf843Smisaki "==> nxge_intr_mask_mgmt_set: flag %d ldg %d" 3471*52ccf843Smisaki "set mask nldvs %d", on, ldgp->ldg, ldgp->nldvs)); 347244961713Sgirish for (j = 0; j < ldgp->nldvs; j++, ldvp++) { 347344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3474*52ccf843Smisaki "==> nxge_intr_mask_mgmt_set: " 3475*52ccf843Smisaki "for %d %d flag %d", i, j, on)); 347644961713Sgirish if (on) { 347744961713Sgirish ldvp->ldv_ldf_masks = 0; 347844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3479*52ccf843Smisaki "==> nxge_intr_mask_mgmt_set: " 3480*52ccf843Smisaki "ON mask off")); 348144961713Sgirish } else if (!on) { 348244961713Sgirish ldvp->ldv_ldf_masks = (uint8_t)LD_IM1_MASK; 348344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3484*52ccf843Smisaki "==> nxge_intr_mask_mgmt_set:mask on")); 348544961713Sgirish } 348644961713Sgirish rs = npi_intr_mask_set(handle, ldvp->ldv, 3487*52ccf843Smisaki ldvp->ldv_ldf_masks); 348844961713Sgirish if (rs != NPI_SUCCESS) { 348944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3490*52ccf843Smisaki "==> nxge_intr_mask_mgmt_set: " 3491*52ccf843Smisaki "set mask failed " 3492*52ccf843Smisaki " rs 0x%x ldv %d mask 0x%x", 3493*52ccf843Smisaki rs, ldvp->ldv, ldvp->ldv_ldf_masks)); 349444961713Sgirish return (NXGE_ERROR | rs); 349544961713Sgirish } 349644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3497*52ccf843Smisaki "==> nxge_intr_mask_mgmt_set: flag %d" 3498*52ccf843Smisaki "set mask OK " 3499*52ccf843Smisaki " ldv %d mask 0x%x", 3500*52ccf843Smisaki on, ldvp->ldv, ldvp->ldv_ldf_masks)); 350144961713Sgirish } 350244961713Sgirish } 350344961713Sgirish 350444961713Sgirish ldgp = ldgvp->ldgp; 350544961713Sgirish /* set the arm bit */ 350644961713Sgirish for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) { 350744961713Sgirish if (on && !ldgp->arm) { 350844961713Sgirish ldgp->arm = B_TRUE; 350944961713Sgirish } else if (!on && ldgp->arm) { 351044961713Sgirish ldgp->arm = B_FALSE; 351144961713Sgirish } 351244961713Sgirish rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3513*52ccf843Smisaki ldgp->arm, ldgp->ldg_timer); 351444961713Sgirish if (rs != NPI_SUCCESS) { 351544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3516*52ccf843Smisaki "<== nxge_intr_mask_mgmt_set: " 3517*52ccf843Smisaki "set timer failed " 3518*52ccf843Smisaki " rs 0x%x ldg %d timer 0x%x", 3519*52ccf843Smisaki rs, ldgp->ldg, ldgp->ldg_timer)); 352044961713Sgirish return (NXGE_ERROR | rs); 352144961713Sgirish } 352244961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3523*52ccf843Smisaki "==> nxge_intr_mask_mgmt_set: OK (flag %d) " 3524*52ccf843Smisaki "set timer " 3525*52ccf843Smisaki " ldg %d timer 0x%x", 3526*52ccf843Smisaki on, ldgp->ldg, ldgp->ldg_timer)); 352744961713Sgirish } 352844961713Sgirish 352944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_mask_mgmt_set")); 353044961713Sgirish return (NXGE_OK); 353144961713Sgirish } 353244961713Sgirish 353314ea4bb7Ssd static nxge_status_t 353444961713Sgirish nxge_get_mac_addr_properties(p_nxge_t nxgep) 353544961713Sgirish { 353659ac0c16Sdavemq #if defined(_BIG_ENDIAN) 3537a3c5bd6dSspeer uchar_t *prop_val; 3538a3c5bd6dSspeer uint_t prop_len; 353959ac0c16Sdavemq uint_t j; 354059ac0c16Sdavemq #endif 3541a3c5bd6dSspeer uint_t i; 3542a3c5bd6dSspeer uint8_t func_num; 354359ac0c16Sdavemq boolean_t compute_macs = B_TRUE; 354444961713Sgirish 354544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_mac_addr_properties ")); 354644961713Sgirish 354744961713Sgirish #if defined(_BIG_ENDIAN) 354844961713Sgirish /* 354944961713Sgirish * Get the ethernet address. 355044961713Sgirish */ 355144961713Sgirish (void) localetheraddr((struct ether_addr *)NULL, &nxgep->ouraddr); 355244961713Sgirish 355344961713Sgirish /* 3554a3c5bd6dSspeer * Check if it is an adapter with its own local mac address If it is 3555a3c5bd6dSspeer * present, override the system mac address. 355644961713Sgirish */ 355744961713Sgirish if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3558*52ccf843Smisaki "local-mac-address", &prop_val, 3559*52ccf843Smisaki &prop_len) == DDI_PROP_SUCCESS) { 356044961713Sgirish if (prop_len == ETHERADDRL) { 356144961713Sgirish nxgep->factaddr = *(p_ether_addr_t)prop_val; 356244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "Local mac address = " 3563*52ccf843Smisaki "%02x:%02x:%02x:%02x:%02x:%02x", 3564*52ccf843Smisaki prop_val[0], prop_val[1], prop_val[2], 3565*52ccf843Smisaki prop_val[3], prop_val[4], prop_val[5])); 356644961713Sgirish } 356744961713Sgirish ddi_prop_free(prop_val); 356844961713Sgirish } 356944961713Sgirish if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3570*52ccf843Smisaki "local-mac-address?", &prop_val, 3571*52ccf843Smisaki &prop_len) == DDI_PROP_SUCCESS) { 3572a3c5bd6dSspeer if (strncmp("true", (caddr_t)prop_val, (size_t)prop_len) == 0) { 357344961713Sgirish nxgep->ouraddr = nxgep->factaddr; 357444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 3575*52ccf843Smisaki "Using local MAC address")); 357644961713Sgirish } 357744961713Sgirish ddi_prop_free(prop_val); 357844961713Sgirish } else { 357944961713Sgirish nxgep->ouraddr = nxgep->factaddr; 358044961713Sgirish } 358156d930aeSspeer 35822e59129aSraghus if ((!nxgep->vpd_info.present) || 358359ac0c16Sdavemq (nxge_is_valid_local_mac(nxgep->factaddr))) 358456d930aeSspeer goto got_mac_addr; 358556d930aeSspeer 358656d930aeSspeer NXGE_DEBUG_MSG((nxgep, DDI_CTL, "nxge_get_mac_addr_properties: " 358756d930aeSspeer "MAC address from properties is not valid...reading from PROM")); 358856d930aeSspeer 358944961713Sgirish #endif 359056d930aeSspeer if (!nxgep->vpd_info.ver_valid) { 359156d930aeSspeer (void) nxge_espc_mac_addrs_get(nxgep); 359256d930aeSspeer if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 35932e59129aSraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get " 35942e59129aSraghus "MAC address")); 359556d930aeSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 359656d930aeSspeer "[%s] invalid...please update", 359756d930aeSspeer nxgep->vpd_info.ver)); 359856d930aeSspeer return (NXGE_ERROR); 359956d930aeSspeer } 360056d930aeSspeer nxgep->ouraddr = nxgep->factaddr; 360156d930aeSspeer goto got_mac_addr; 360256d930aeSspeer } 360356d930aeSspeer /* 360456d930aeSspeer * First get the MAC address from the info in the VPD data read 360556d930aeSspeer * from the EEPROM. 360656d930aeSspeer */ 360756d930aeSspeer nxge_espc_get_next_mac_addr(nxgep->vpd_info.mac_addr, 360859ac0c16Sdavemq nxgep->function_num, &nxgep->factaddr); 360956d930aeSspeer 361056d930aeSspeer if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 361156d930aeSspeer NXGE_DEBUG_MSG((nxgep, DDI_CTL, 361256d930aeSspeer "nxge_get_mac_addr_properties: " 361356d930aeSspeer "MAC address in EEPROM VPD data not valid" 361456d930aeSspeer "...reading from NCR registers")); 361556d930aeSspeer (void) nxge_espc_mac_addrs_get(nxgep); 361656d930aeSspeer if (!nxge_is_valid_local_mac(nxgep->factaddr)) { 36172e59129aSraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get " 36182e59129aSraghus "MAC address")); 361956d930aeSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 362056d930aeSspeer "[%s] invalid...please update", 362156d930aeSspeer nxgep->vpd_info.ver)); 362256d930aeSspeer return (NXGE_ERROR); 362356d930aeSspeer } 362456d930aeSspeer } 362544961713Sgirish 362656d930aeSspeer nxgep->ouraddr = nxgep->factaddr; 362756d930aeSspeer 362856d930aeSspeer got_mac_addr: 362944961713Sgirish func_num = nxgep->function_num; 363044961713Sgirish 363158324dfcSspeer /* 363259ac0c16Sdavemq * Note: mac-addresses property is the list of mac addresses for a 363359ac0c16Sdavemq * port. NXGE_MAX_MMAC_ADDRS is the total number of MAC addresses 363459ac0c16Sdavemq * allocated for a board. 363558324dfcSspeer */ 363659ac0c16Sdavemq nxgep->nxge_mmac_info.total_factory_macs = NXGE_MAX_MMAC_ADDRS; 363744961713Sgirish 363859ac0c16Sdavemq #if defined(_BIG_ENDIAN) 363959ac0c16Sdavemq if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 364059ac0c16Sdavemq "mac-addresses", &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 364144961713Sgirish /* 364259ac0c16Sdavemq * XAUI may have up to 18 MACs, more than the XMAC can 364359ac0c16Sdavemq * use (1 unique MAC plus 16 alternate MACs) 364444961713Sgirish */ 364559ac0c16Sdavemq nxgep->nxge_mmac_info.num_factory_mmac = 364659ac0c16Sdavemq prop_len / ETHERADDRL - 1; 364759ac0c16Sdavemq if (nxgep->nxge_mmac_info.num_factory_mmac > 364859ac0c16Sdavemq XMAC_MAX_ALT_ADDR_ENTRY) { 364956d930aeSspeer nxgep->nxge_mmac_info.num_factory_mmac = 365059ac0c16Sdavemq XMAC_MAX_ALT_ADDR_ENTRY; 365159ac0c16Sdavemq } 365259ac0c16Sdavemq 365359ac0c16Sdavemq for (i = 1; i <= nxgep->nxge_mmac_info.num_factory_mmac; i++) { 365459ac0c16Sdavemq for (j = 0; j < ETHERADDRL; j++) { 365559ac0c16Sdavemq nxgep->nxge_mmac_info.factory_mac_pool[i][j] = 365659ac0c16Sdavemq *(prop_val + (i * ETHERADDRL) + j); 365759ac0c16Sdavemq } 365859ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, DDI_CTL, 365959ac0c16Sdavemq "nxge_get_mac_addr_properties: Alt mac[%d] from " 366059ac0c16Sdavemq "mac-addresses property[%2x:%2x:%2x:%2x:%2x:%2x]", 366159ac0c16Sdavemq i, nxgep->nxge_mmac_info.factory_mac_pool[i][0], 366259ac0c16Sdavemq nxgep->nxge_mmac_info.factory_mac_pool[i][1], 366359ac0c16Sdavemq nxgep->nxge_mmac_info.factory_mac_pool[i][2], 366459ac0c16Sdavemq nxgep->nxge_mmac_info.factory_mac_pool[i][3], 366559ac0c16Sdavemq nxgep->nxge_mmac_info.factory_mac_pool[i][4], 366659ac0c16Sdavemq nxgep->nxge_mmac_info.factory_mac_pool[i][5])); 366756d930aeSspeer } 366859ac0c16Sdavemq 366959ac0c16Sdavemq compute_macs = B_FALSE; 367059ac0c16Sdavemq ddi_prop_free(prop_val); 367159ac0c16Sdavemq goto got_mmac_info; 367258324dfcSspeer } 367359ac0c16Sdavemq #endif 367459ac0c16Sdavemq /* 367559ac0c16Sdavemq * total_factory_macs = 32 367659ac0c16Sdavemq * num_factory_mmac = (32 >> (nports/2)) - 1 367759ac0c16Sdavemq * So if nports = 4, then num_factory_mmac = 7 367859ac0c16Sdavemq * if nports = 2, then num_factory_mmac = 15 367959ac0c16Sdavemq */ 368059ac0c16Sdavemq nxgep->nxge_mmac_info.num_factory_mmac = 368159ac0c16Sdavemq ((nxgep->nxge_mmac_info.total_factory_macs >> 368259ac0c16Sdavemq (nxgep->nports >> 1))) - 1; 368356d930aeSspeer 368459ac0c16Sdavemq got_mmac_info: 368559ac0c16Sdavemq 368659ac0c16Sdavemq if ((nxgep->function_num < 2) && 368759ac0c16Sdavemq (nxgep->nxge_mmac_info.num_factory_mmac > 368859ac0c16Sdavemq XMAC_MAX_ALT_ADDR_ENTRY)) { 368959ac0c16Sdavemq nxgep->nxge_mmac_info.num_factory_mmac = 369059ac0c16Sdavemq XMAC_MAX_ALT_ADDR_ENTRY; 369159ac0c16Sdavemq } else if ((nxgep->function_num > 1) && 369259ac0c16Sdavemq (nxgep->nxge_mmac_info.num_factory_mmac > 369359ac0c16Sdavemq BMAC_MAX_ALT_ADDR_ENTRY)) { 369459ac0c16Sdavemq nxgep->nxge_mmac_info.num_factory_mmac = 369559ac0c16Sdavemq BMAC_MAX_ALT_ADDR_ENTRY; 369656d930aeSspeer } 369756d930aeSspeer 369858324dfcSspeer for (i = 0; i <= nxgep->nxge_mmac_info.num_mmac; i++) { 369944961713Sgirish (void) npi_mac_altaddr_disable(nxgep->npi_handle, 3700*52ccf843Smisaki NXGE_GET_PORT_NUM(func_num), i); 370144961713Sgirish } 370244961713Sgirish 370359ac0c16Sdavemq (void) nxge_init_mmac(nxgep, compute_macs); 370414ea4bb7Ssd return (NXGE_OK); 370544961713Sgirish } 370644961713Sgirish 370744961713Sgirish void 370844961713Sgirish nxge_get_xcvr_properties(p_nxge_t nxgep) 370944961713Sgirish { 3710a3c5bd6dSspeer uchar_t *prop_val; 3711a3c5bd6dSspeer uint_t prop_len; 371244961713Sgirish 371344961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_xcvr_properties")); 371444961713Sgirish 371544961713Sgirish /* 371644961713Sgirish * Read the type of physical layer interface being used. 371744961713Sgirish */ 371844961713Sgirish nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 371944961713Sgirish if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3720*52ccf843Smisaki "phy-type", &prop_val, &prop_len) == DDI_PROP_SUCCESS) { 3721a3c5bd6dSspeer if (strncmp("pcs", (caddr_t)prop_val, 3722*52ccf843Smisaki (size_t)prop_len) == 0) { 372344961713Sgirish nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 372444961713Sgirish } else { 372544961713Sgirish nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 372644961713Sgirish } 372744961713Sgirish ddi_prop_free(prop_val); 372844961713Sgirish } else if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0, 3729*52ccf843Smisaki "phy-interface", &prop_val, 3730*52ccf843Smisaki &prop_len) == DDI_PROP_SUCCESS) { 373144961713Sgirish if (strncmp("pcs", (caddr_t)prop_val, (size_t)prop_len) == 0) { 373244961713Sgirish nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 373344961713Sgirish } else { 373444961713Sgirish nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 373544961713Sgirish } 373644961713Sgirish ddi_prop_free(prop_val); 373744961713Sgirish } 373844961713Sgirish } 373944961713Sgirish 374044961713Sgirish /* 374144961713Sgirish * Static functions start here. 374244961713Sgirish */ 3743a3c5bd6dSspeer 374444961713Sgirish static void 374544961713Sgirish nxge_ldgv_setup(p_nxge_ldg_t *ldgp, p_nxge_ldv_t *ldvp, uint8_t ldv, 3746a3c5bd6dSspeer uint8_t endldg, int *ngrps) 374744961713Sgirish { 374844961713Sgirish NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup")); 374944961713Sgirish /* Assign the group number for each device. */ 375044961713Sgirish (*ldvp)->ldg_assigned = (*ldgp)->ldg; 375144961713Sgirish (*ldvp)->ldgp = *ldgp; 375244961713Sgirish (*ldvp)->ldv = ldv; 375344961713Sgirish 375444961713Sgirish NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: " 3755*52ccf843Smisaki "ldv %d endldg %d ldg %d, ldvp $%p", 3756*52ccf843Smisaki ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp)); 375744961713Sgirish 375844961713Sgirish (*ldgp)->nldvs++; 375944961713Sgirish if ((*ldgp)->ldg == (endldg - 1)) { 376044961713Sgirish if ((*ldgp)->ldvp == NULL) { 376144961713Sgirish (*ldgp)->ldvp = *ldvp; 376244961713Sgirish *ngrps += 1; 376344961713Sgirish NXGE_DEBUG_MSG((NULL, INT_CTL, 3764*52ccf843Smisaki "==> nxge_ldgv_setup: ngrps %d", *ngrps)); 376544961713Sgirish } 376644961713Sgirish NXGE_DEBUG_MSG((NULL, INT_CTL, 3767*52ccf843Smisaki "==> nxge_ldgv_setup: ldvp $%p ngrps %d", 3768*52ccf843Smisaki *ldvp, *ngrps)); 376944961713Sgirish ++*ldvp; 377044961713Sgirish } else { 377144961713Sgirish (*ldgp)->ldvp = *ldvp; 377244961713Sgirish *ngrps += 1; 377344961713Sgirish NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup(done): " 3774*52ccf843Smisaki "ldv %d endldg %d ldg %d, ldvp $%p", 3775*52ccf843Smisaki ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp)); 377644961713Sgirish (*ldvp) = ++*ldvp; 377744961713Sgirish (*ldgp) = ++*ldgp; 377844961713Sgirish NXGE_DEBUG_MSG((NULL, INT_CTL, 3779*52ccf843Smisaki "==> nxge_ldgv_setup: new ngrps %d", *ngrps)); 378044961713Sgirish } 378144961713Sgirish 378244961713Sgirish NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: " 3783*52ccf843Smisaki "ldv %d ldvp $%p endldg %d ngrps %d", 3784*52ccf843Smisaki ldv, ldvp, endldg, *ngrps)); 378544961713Sgirish 378644961713Sgirish NXGE_DEBUG_MSG((NULL, INT_CTL, "<== nxge_ldgv_setup")); 378744961713Sgirish } 378844961713Sgirish 378944961713Sgirish /* 379058324dfcSspeer * Note: This function assumes the following distribution of mac 379144961713Sgirish * addresses among 4 ports in neptune: 379244961713Sgirish * 379344961713Sgirish * ------------- 379444961713Sgirish * 0| |0 - local-mac-address for fn 0 379544961713Sgirish * ------------- 379644961713Sgirish * 1| |1 - local-mac-address for fn 1 379744961713Sgirish * ------------- 379844961713Sgirish * 2| |2 - local-mac-address for fn 2 379944961713Sgirish * ------------- 380044961713Sgirish * 3| |3 - local-mac-address for fn 3 380144961713Sgirish * ------------- 380244961713Sgirish * | |4 - Start of alt. mac addr. for fn 0 380344961713Sgirish * | | 380444961713Sgirish * | | 380544961713Sgirish * | |10 380644961713Sgirish * -------------- 380744961713Sgirish * | |11 - Start of alt. mac addr. for fn 1 380844961713Sgirish * | | 380944961713Sgirish * | | 381044961713Sgirish * | |17 381144961713Sgirish * -------------- 381244961713Sgirish * | |18 - Start of alt. mac addr. for fn 2 381344961713Sgirish * | | 381444961713Sgirish * | | 381544961713Sgirish * | |24 381644961713Sgirish * -------------- 381744961713Sgirish * | |25 - Start of alt. mac addr. for fn 3 381844961713Sgirish * | | 381944961713Sgirish * | | 382044961713Sgirish * | |31 382144961713Sgirish * -------------- 382244961713Sgirish * 382344961713Sgirish * For N2/NIU the mac addresses is from XAUI card. 382459ac0c16Sdavemq * 382559ac0c16Sdavemq * When 'compute_addrs' is true, the alternate mac addresses are computed 382659ac0c16Sdavemq * using the unique mac address as base. Otherwise the alternate addresses 382759ac0c16Sdavemq * are assigned from the list read off the 'mac-addresses' property. 382844961713Sgirish */ 382944961713Sgirish 383044961713Sgirish static void 383159ac0c16Sdavemq nxge_init_mmac(p_nxge_t nxgep, boolean_t compute_addrs) 383244961713Sgirish { 383358324dfcSspeer int slot; 3834a3c5bd6dSspeer uint8_t func_num; 3835a3c5bd6dSspeer uint16_t *base_mmac_addr; 383658324dfcSspeer uint32_t alt_mac_ls4b; 3837a3c5bd6dSspeer uint16_t *mmac_addr; 383858324dfcSspeer uint32_t base_mac_ls4b; /* least significant 4 bytes */ 383958324dfcSspeer nxge_mmac_t *mmac_info; 3840a3c5bd6dSspeer npi_mac_addr_t mac_addr; 384144961713Sgirish 384244961713Sgirish func_num = nxgep->function_num; 384344961713Sgirish base_mmac_addr = (uint16_t *)&nxgep->factaddr; 384458324dfcSspeer mmac_info = (nxge_mmac_t *)&nxgep->nxge_mmac_info; 384544961713Sgirish 384659ac0c16Sdavemq if (compute_addrs) { 384759ac0c16Sdavemq base_mac_ls4b = ((uint32_t)base_mmac_addr[1]) << 16 | 384859ac0c16Sdavemq base_mmac_addr[2]; 384944961713Sgirish 385059ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 385159ac0c16Sdavemq /* ls4b of 1st altmac */ 385259ac0c16Sdavemq alt_mac_ls4b = base_mac_ls4b + 1; 385359ac0c16Sdavemq } else { /* Neptune */ 385459ac0c16Sdavemq alt_mac_ls4b = base_mac_ls4b + 385559ac0c16Sdavemq (nxgep->nports - func_num) + 385659ac0c16Sdavemq (func_num * (mmac_info->num_factory_mmac)); 385759ac0c16Sdavemq } 385858324dfcSspeer } 385944961713Sgirish 386058324dfcSspeer /* Set flags for unique MAC */ 386158324dfcSspeer mmac_info->mac_pool[0].flags |= MMAC_SLOT_USED | MMAC_VENDOR_ADDR; 386258324dfcSspeer 386358324dfcSspeer /* Clear flags of all alternate MAC slots */ 386458324dfcSspeer for (slot = 1; slot <= mmac_info->num_mmac; slot++) { 386558324dfcSspeer if (slot <= mmac_info->num_factory_mmac) 386658324dfcSspeer mmac_info->mac_pool[slot].flags = MMAC_VENDOR_ADDR; 386758324dfcSspeer else 386858324dfcSspeer mmac_info->mac_pool[slot].flags = 0; 386958324dfcSspeer } 387058324dfcSspeer 387158324dfcSspeer /* Generate and store factory alternate MACs */ 387258324dfcSspeer for (slot = 1; slot <= mmac_info->num_factory_mmac; slot++) { 387358324dfcSspeer mmac_addr = (uint16_t *)&mmac_info->factory_mac_pool[slot]; 387459ac0c16Sdavemq if (compute_addrs) { 387559ac0c16Sdavemq mmac_addr[0] = base_mmac_addr[0]; 387659ac0c16Sdavemq mac_addr.w2 = mmac_addr[0]; 387759ac0c16Sdavemq 387859ac0c16Sdavemq mmac_addr[1] = (alt_mac_ls4b >> 16) & 0x0FFFF; 387959ac0c16Sdavemq mac_addr.w1 = mmac_addr[1]; 388059ac0c16Sdavemq 388159ac0c16Sdavemq mmac_addr[2] = alt_mac_ls4b & 0x0FFFF; 388259ac0c16Sdavemq mac_addr.w0 = mmac_addr[2]; 388344961713Sgirish 388459ac0c16Sdavemq alt_mac_ls4b++; 388559ac0c16Sdavemq } else { 388659ac0c16Sdavemq mac_addr.w2 = mmac_addr[0]; 388759ac0c16Sdavemq mac_addr.w1 = mmac_addr[1]; 388859ac0c16Sdavemq mac_addr.w0 = mmac_addr[2]; 388959ac0c16Sdavemq } 389044961713Sgirish 389159ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, DDI_CTL, 389259ac0c16Sdavemq "mac_pool_addr[%2x:%2x:%2x:%2x:%2x:%2x] npi_addr[%x%x%x]", 389359ac0c16Sdavemq mmac_info->factory_mac_pool[slot][0], 389459ac0c16Sdavemq mmac_info->factory_mac_pool[slot][1], 389559ac0c16Sdavemq mmac_info->factory_mac_pool[slot][2], 389659ac0c16Sdavemq mmac_info->factory_mac_pool[slot][3], 389759ac0c16Sdavemq mmac_info->factory_mac_pool[slot][4], 389859ac0c16Sdavemq mmac_info->factory_mac_pool[slot][5], 389959ac0c16Sdavemq mac_addr.w0, mac_addr.w1, mac_addr.w2)); 390044961713Sgirish /* 390159ac0c16Sdavemq * slot minus 1 because npi_mac_altaddr_entry expects 0 390258324dfcSspeer * for the first alternate mac address. 390344961713Sgirish */ 390444961713Sgirish (void) npi_mac_altaddr_entry(nxgep->npi_handle, OP_SET, 3905*52ccf843Smisaki NXGE_GET_PORT_NUM(func_num), slot - 1, &mac_addr); 390644961713Sgirish } 390758324dfcSspeer /* Initialize the first two parameters for mmac kstat */ 390858324dfcSspeer nxgep->statsp->mmac_stats.mmac_max_cnt = mmac_info->num_mmac; 390958324dfcSspeer nxgep->statsp->mmac_stats.mmac_avail_cnt = mmac_info->num_mmac; 391044961713Sgirish } 3911